OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 #include "ui/views/accessibility/native_view_accessibility.h" |
| 6 |
5 #include "base/memory/ptr_util.h" | 7 #include "base/memory/ptr_util.h" |
6 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
7 #include "ui/accessibility/ax_node_data.h" | 9 #include "ui/accessibility/ax_node_data.h" |
8 #include "ui/gfx/geometry/rect_conversions.h" | 10 #include "ui/gfx/geometry/rect_conversions.h" |
9 #include "ui/views/accessibility/native_view_accessibility.h" | |
10 #include "ui/views/controls/button/button.h" | 11 #include "ui/views/controls/button/button.h" |
11 #include "ui/views/controls/label.h" | 12 #include "ui/views/controls/label.h" |
12 #include "ui/views/test/views_test_base.h" | 13 #include "ui/views/test/views_test_base.h" |
| 14 #include "ui/views/widget/widget.h" |
13 | 15 |
14 namespace views { | 16 namespace views { |
15 namespace test { | 17 namespace test { |
16 | |
17 class NativeViewAccessibilityTest; | |
18 | |
19 namespace { | 18 namespace { |
20 | 19 |
21 class TestButton : public Button { | 20 class TestButton : public Button { |
22 public: | 21 public: |
23 TestButton() : Button(NULL) {} | 22 TestButton() : Button(NULL) {} |
24 }; | 23 }; |
25 | 24 |
| 25 // Adds a View with given bounds and focusability to a parent. |
| 26 View* AddNewChildWithBoundsAndFocusability(View* parent, |
| 27 const gfx::Rect& bounds, |
| 28 bool focusable) { |
| 29 View* child = new View; |
| 30 child->SetBoundsRect(bounds); |
| 31 parent->AddChildView(child); |
| 32 child->SetFocusBehavior(focusable ? ClientView::FocusBehavior::ACCESSIBLE_ONLY |
| 33 : ClientView::FocusBehavior::NEVER); |
| 34 return child; |
| 35 } |
| 36 |
26 } // namespace | 37 } // namespace |
27 | 38 |
28 class NativeViewAccessibilityTest : public ViewsTestBase { | 39 class NativeViewAccessibilityTest : public ViewsTestBase { |
29 public: | 40 public: |
30 NativeViewAccessibilityTest() {} | 41 NativeViewAccessibilityTest() {} |
31 ~NativeViewAccessibilityTest() override {} | 42 ~NativeViewAccessibilityTest() override {} |
32 | 43 |
33 void SetUp() override { | 44 void SetUp() override { |
34 ViewsTestBase::SetUp(); | 45 ViewsTestBase::SetUp(); |
35 | 46 |
36 widget_ = new views::Widget; | 47 widget_ = new Widget; |
37 views::Widget::InitParams params = | 48 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW); |
38 CreateParams(views::Widget::InitParams::TYPE_WINDOW); | |
39 params.bounds = gfx::Rect(0, 0, 200, 200); | 49 params.bounds = gfx::Rect(0, 0, 200, 200); |
40 widget_->Init(params); | 50 widget_->Init(params); |
41 | 51 |
42 button_ = new TestButton(); | 52 button_ = new TestButton(); |
43 button_->SetSize(gfx::Size(20, 20)); | 53 button_->SetSize(gfx::Size(20, 20)); |
44 button_accessibility_ = NativeViewAccessibility::Create(button_); | 54 button_accessibility_ = NativeViewAccessibility::GetForView(button_); |
45 | 55 |
46 label_ = new Label(); | 56 label_ = new Label(); |
47 button_->AddChildView(label_); | 57 button_->AddChildView(label_); |
48 label_accessibility_ = NativeViewAccessibility::Create(label_); | 58 label_accessibility_ = NativeViewAccessibility::GetForView(label_); |
49 | 59 |
50 widget_->GetContentsView()->AddChildView(button_); | 60 widget_->GetContentsView()->AddChildView(button_); |
51 widget_->Show(); | 61 widget_->Show(); |
52 } | 62 } |
53 | 63 |
54 void TearDown() override { | 64 void TearDown() override { |
| 65 // Closing the Widget will destroy all its children and their associated |
| 66 // NativeViewAccessibility instances. |
55 if (!widget_->IsClosed()) | 67 if (!widget_->IsClosed()) |
56 widget_->Close(); | 68 widget_->Close(); |
57 button_accessibility_->Destroy(); | 69 button_accessibility_ = nullptr; |
58 button_accessibility_ = NULL; | 70 label_accessibility_ = nullptr; |
59 label_accessibility_->Destroy(); | |
60 label_accessibility_ = NULL; | |
61 ViewsTestBase::TearDown(); | 71 ViewsTestBase::TearDown(); |
62 } | 72 } |
63 | 73 |
64 protected: | 74 protected: |
65 views::Widget* widget_; | 75 Widget* widget_; |
66 TestButton* button_; | 76 TestButton* button_; |
67 NativeViewAccessibility* button_accessibility_; | 77 NativeViewAccessibility* button_accessibility_; |
68 Label* label_; | 78 Label* label_; |
69 NativeViewAccessibility* label_accessibility_; | 79 NativeViewAccessibility* label_accessibility_; |
| 80 |
| 81 DISALLOW_COPY_AND_ASSIGN(NativeViewAccessibilityTest); |
70 }; | 82 }; |
71 | 83 |
72 TEST_F(NativeViewAccessibilityTest, RoleShouldMatch) { | 84 TEST_F(NativeViewAccessibilityTest, RoleShouldMatch) { |
73 EXPECT_EQ(ui::AX_ROLE_BUTTON, button_accessibility_->GetData().role); | 85 EXPECT_EQ(ui::AX_ROLE_BUTTON, button_accessibility_->GetData().role); |
| 86 // Since the label is a subview of |button_|, and the button is keyboard |
| 87 // focusable, the label is assumed to form part of the button and not have a |
| 88 // role of its own. |
| 89 EXPECT_EQ(ui::AX_ROLE_IGNORED, label_accessibility_->GetData().role); |
| 90 // This will happen for all potentially keyboard-focusable Views with |
| 91 // non-keyboard-focusable children, so if we make the button unfocusable, the |
| 92 // label will be allowed to have its own role again. |
| 93 button_->SetFocusBehavior(View::FocusBehavior::NEVER); |
74 EXPECT_EQ(ui::AX_ROLE_STATIC_TEXT, label_accessibility_->GetData().role); | 94 EXPECT_EQ(ui::AX_ROLE_STATIC_TEXT, label_accessibility_->GetData().role); |
75 } | 95 } |
76 | 96 |
77 TEST_F(NativeViewAccessibilityTest, BoundsShouldMatch) { | 97 TEST_F(NativeViewAccessibilityTest, BoundsShouldMatch) { |
78 gfx::Rect bounds = gfx::ToEnclosingRect( | 98 gfx::Rect bounds = gfx::ToEnclosingRect( |
79 button_accessibility_->GetData().location); | 99 button_accessibility_->GetData().location); |
80 bounds.Offset(button_accessibility_->GetGlobalCoordinateOffset()); | 100 bounds.Offset(button_accessibility_->GetGlobalCoordinateOffset()); |
81 EXPECT_EQ(button_->GetBoundsInScreen(), bounds); | 101 EXPECT_EQ(button_->GetBoundsInScreen(), bounds); |
82 } | 102 } |
83 | 103 |
84 TEST_F(NativeViewAccessibilityTest, LabelIsChildOfButton) { | 104 TEST_F(NativeViewAccessibilityTest, LabelIsChildOfButton) { |
| 105 EXPECT_EQ(0, button_accessibility_->GetChildCount()); |
| 106 EXPECT_EQ(nullptr, button_accessibility_->ChildAtIndex(0)); |
| 107 EXPECT_EQ(button_->GetNativeViewAccessible(), |
| 108 label_accessibility_->GetParent()); |
| 109 |
| 110 // If |button_| is no longer focusable, |label_| should show up again. |
| 111 button_->SetFocusBehavior(View::FocusBehavior::NEVER); |
85 EXPECT_EQ(1, button_accessibility_->GetChildCount()); | 112 EXPECT_EQ(1, button_accessibility_->GetChildCount()); |
86 EXPECT_EQ(label_->GetNativeViewAccessible(), | 113 EXPECT_EQ(label_->GetNativeViewAccessible(), |
87 button_accessibility_->ChildAtIndex(0)); | 114 button_accessibility_->ChildAtIndex(0)); |
88 EXPECT_EQ(button_->GetNativeViewAccessible(), | |
89 label_accessibility_->GetParent()); | |
90 } | 115 } |
91 | 116 |
92 // Verify Views with invisible ancestors have AX_STATE_INVISIBLE. | 117 // Verify Views with invisible ancestors have AX_STATE_INVISIBLE. |
93 TEST_F(NativeViewAccessibilityTest, InvisibleViews) { | 118 TEST_F(NativeViewAccessibilityTest, InvisibleViews) { |
94 EXPECT_TRUE(widget_->IsVisible()); | 119 EXPECT_TRUE(widget_->IsVisible()); |
95 EXPECT_FALSE( | 120 EXPECT_FALSE( |
96 button_accessibility_->GetData().HasStateFlag(ui::AX_STATE_INVISIBLE)); | 121 button_accessibility_->GetData().HasStateFlag(ui::AX_STATE_INVISIBLE)); |
97 EXPECT_FALSE( | 122 EXPECT_FALSE( |
98 label_accessibility_->GetData().HasStateFlag(ui::AX_STATE_INVISIBLE)); | 123 label_accessibility_->GetData().HasStateFlag(ui::AX_STATE_INVISIBLE)); |
99 button_->SetVisible(false); | 124 button_->SetVisible(false); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 bool is_destroying_parent_widget = (parent_widget_ == widget); | 158 bool is_destroying_parent_widget = (parent_widget_ == widget); |
134 NativeViewAccessibility::OnWidgetDestroying(widget); | 159 NativeViewAccessibility::OnWidgetDestroying(widget); |
135 if (is_destroying_parent_widget) | 160 if (is_destroying_parent_widget) |
136 delete this; | 161 delete this; |
137 } | 162 } |
138 }; | 163 }; |
139 | 164 |
140 TEST_F(NativeViewAccessibilityTest, CrashOnWidgetDestroyed) { | 165 TEST_F(NativeViewAccessibilityTest, CrashOnWidgetDestroyed) { |
141 std::unique_ptr<Widget> parent_widget(new Widget); | 166 std::unique_ptr<Widget> parent_widget(new Widget); |
142 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); | 167 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); |
143 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 168 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
144 params.bounds = gfx::Rect(50, 50, 650, 650); | 169 params.bounds = gfx::Rect(50, 50, 650, 650); |
145 parent_widget->Init(params); | 170 parent_widget->Init(params); |
146 | 171 |
147 std::unique_ptr<Widget> child_widget(new Widget); | 172 std::unique_ptr<Widget> child_widget(new Widget); |
148 child_widget->Init(params); | 173 child_widget->Init(params); |
149 | 174 |
150 // Make sure that deleting the parent widget can't cause a crash | 175 // Make sure that deleting the parent widget can't cause a crash |
151 // due to NativeViewAccessibility not unregistering itself as a | 176 // due to NativeViewAccessibility not unregistering itself as a |
152 // WidgetObserver. Note that TestNativeViewAccessibility is a subclass | 177 // WidgetObserver. Note that TestNativeViewAccessibility is a subclass |
153 // defined above that destroys itself when its parent widget is destroyed. | 178 // defined above that destroys itself when its parent widget is destroyed. |
154 TestNativeViewAccessibility* child_accessible = | 179 TestNativeViewAccessibility* child_accessible = |
155 new TestNativeViewAccessibility(child_widget->GetRootView()); | 180 new TestNativeViewAccessibility(child_widget->GetRootView()); |
156 child_accessible->SetParentWidget(parent_widget.get()); | 181 child_accessible->SetParentWidget(parent_widget.get()); |
157 parent_widget.reset(); | 182 parent_widget.reset(); |
158 } | 183 } |
159 | 184 |
| 185 // Separate test class for a complicated test case for ignored accessibility |
| 186 // elements which are excluded from the accessibility tree. |
| 187 class NativeViewAccessibilityIgnoredElementsTest : public ViewsTestBase { |
| 188 public: |
| 189 NativeViewAccessibilityIgnoredElementsTest() {} |
| 190 |
| 191 void SetUp() override { |
| 192 ViewsTestBase::SetUp(); |
| 193 // Set up an accessibility tree where X-nodes should be ignored. A Views |
| 194 // hierarchy as shown on the left should expose the accessibility tree in |
| 195 // the middle, and respond to hit tests as shown on the right. This test |
| 196 // is here for completeness (in practice, it's unlikely a keyboard-focusable |
| 197 // View will be needed as a descendant of another keyboard-focusable View). |
| 198 // |
| 199 // A A |
| 200 // / \ / | \ +++---+---+---++---+---+---+++ |
| 201 // B X1 B F E ||| C | D | B || F | A | E ||| |
| 202 // / | \ / | \ / \ +++---+---+---++---+---+---+++ |
| 203 // C D X2 X3 X4 E C D |
| 204 // | | |
| 205 // X5 F |
| 206 // |
| 207 // Note: For hit tests, the parent's bounds will be divided equally amongst |
| 208 // its children (including ignored elements). This means all Views belonging |
| 209 // on the same level of the Views hierarchy will be the same size. |
| 210 a_root_ = new View; |
| 211 a_root_->SetSize(gfx::Size(400, 20)); |
| 212 a_root_->SetFocusBehavior(View::FocusBehavior::ACCESSIBLE_ONLY); |
| 213 |
| 214 // Create Views in the left subtree from |a_root_|. |
| 215 gfx::Rect new_bounds(0, 0, a_root_->width() / 2, a_root_->height()); |
| 216 View* b = AddNewChildWithBoundsAndFocusability(a_root_, new_bounds, true); |
| 217 // |a_root_| has 6 leaves, so divvy up space equally between them for hit |
| 218 // tests. |
| 219 new_bounds = gfx::Rect(0, 0, a_root_->width() / 6, a_root_->height()); |
| 220 View* c = AddNewChildWithBoundsAndFocusability(b, new_bounds, true); |
| 221 View* x5 = AddNewChildWithBoundsAndFocusability(c, new_bounds, false); |
| 222 // Update the |new_bounds| origin to position leaves next to each other. |
| 223 new_bounds.set_x(new_bounds.x() + a_root_->width() / 6); |
| 224 View* d = AddNewChildWithBoundsAndFocusability(b, new_bounds, true); |
| 225 new_bounds.set_x(new_bounds.x() + a_root_->width() / 6); |
| 226 View* x2 = AddNewChildWithBoundsAndFocusability(b, new_bounds, false); |
| 227 new_bounds.set_x(new_bounds.x() + a_root_->width() / 6); |
| 228 |
| 229 // Create Views in the right subtree from root |a_root_|. |
| 230 new_bounds.set_size(b->size()); |
| 231 View* x1 = AddNewChildWithBoundsAndFocusability(a_root_, new_bounds, false); |
| 232 new_bounds.set_origin(gfx::Point()); |
| 233 View* x3 = AddNewChildWithBoundsAndFocusability(x1, new_bounds, false); |
| 234 View* f = AddNewChildWithBoundsAndFocusability(x3, new_bounds, true); |
| 235 new_bounds.set_x(new_bounds.x() + a_root_->width() / 6); |
| 236 View* x4 = AddNewChildWithBoundsAndFocusability(x1, new_bounds, false); |
| 237 new_bounds.set_x(new_bounds.x() + a_root_->width() / 6); |
| 238 View* e = AddNewChildWithBoundsAndFocusability(x1, new_bounds, true); |
| 239 |
| 240 // Populate NativeViewAccessibility instances for convenience. |
| 241 a_root_nva_ = NativeViewAccessibility::GetForView(a_root_); |
| 242 b_nva_ = NativeViewAccessibility::GetForView(b); |
| 243 c_b_nva_ = NativeViewAccessibility::GetForView(c); |
| 244 d_b_nva_ = NativeViewAccessibility::GetForView(d); |
| 245 e_x1_nva_ = NativeViewAccessibility::GetForView(e); |
| 246 f_x3_x1_nva_ = NativeViewAccessibility::GetForView(f); |
| 247 x1_nva_ = NativeViewAccessibility::GetForView(x1); |
| 248 x2_b_nva_ = NativeViewAccessibility::GetForView(x2); |
| 249 x3_x1_nva_ = NativeViewAccessibility::GetForView(x3); |
| 250 x4_x1_nva_ = NativeViewAccessibility::GetForView(x4); |
| 251 x5_c_b_nva_ = NativeViewAccessibility::GetForView(x5); |
| 252 |
| 253 // Add everything to a new widget, needed for hit testing and parent tests. |
| 254 widget_ = new Widget; |
| 255 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW); |
| 256 widget_->Init(params); |
| 257 widget_->GetContentsView()->AddChildView(a_root_); |
| 258 widget_->Show(); |
| 259 } |
| 260 |
| 261 void TearDown() override { |
| 262 widget_->Close(); |
| 263 ViewsTestBase::TearDown(); |
| 264 } |
| 265 |
| 266 protected: |
| 267 // Owned by |widget_|. |
| 268 View* a_root_; |
| 269 |
| 270 // Owned by their respective View, which are owned by |widget_|. |
| 271 // The following NativeViewAccessibility objects are named after their |
| 272 // corresponding node as shown in the diagrams in SetUp(), then a list of |
| 273 // their ancestors (minus the root), separated by underscores. |
| 274 NativeViewAccessibility* a_root_nva_; |
| 275 NativeViewAccessibility* b_nva_; |
| 276 NativeViewAccessibility* c_b_nva_; |
| 277 NativeViewAccessibility* d_b_nva_; |
| 278 NativeViewAccessibility* e_x1_nva_; |
| 279 NativeViewAccessibility* f_x3_x1_nva_; |
| 280 NativeViewAccessibility* x1_nva_; |
| 281 NativeViewAccessibility* x2_b_nva_; |
| 282 NativeViewAccessibility* x3_x1_nva_; |
| 283 NativeViewAccessibility* x4_x1_nva_; |
| 284 NativeViewAccessibility* x5_c_b_nva_; |
| 285 |
| 286 Widget* widget_ = nullptr; |
| 287 |
| 288 private: |
| 289 DISALLOW_COPY_AND_ASSIGN(NativeViewAccessibilityIgnoredElementsTest); |
| 290 }; |
| 291 |
| 292 // Check the number of a11y children returned accounts for ignored elements. |
| 293 TEST_F(NativeViewAccessibilityIgnoredElementsTest, GetChildCount) { |
| 294 EXPECT_EQ(3, a_root_nva_->GetChildCount()); |
| 295 EXPECT_EQ(2, b_nva_->GetChildCount()); |
| 296 // Leaf elements will return 0. |
| 297 EXPECT_EQ(0, c_b_nva_->GetChildCount()); |
| 298 EXPECT_EQ(0, x5_c_b_nva_->GetChildCount()); |
| 299 EXPECT_EQ(0, d_b_nva_->GetChildCount()); |
| 300 EXPECT_EQ(0, x2_b_nva_->GetChildCount()); |
| 301 EXPECT_EQ(2, x1_nva_->GetChildCount()); |
| 302 EXPECT_EQ(1, x3_x1_nva_->GetChildCount()); |
| 303 EXPECT_EQ(0, f_x3_x1_nva_->GetChildCount()); |
| 304 EXPECT_EQ(0, x4_x1_nva_->GetChildCount()); |
| 305 EXPECT_EQ(0, e_x1_nva_->GetChildCount()); |
| 306 } |
| 307 |
| 308 // Make sure the correct a11y child element is returned at its corresponding |
| 309 // index. Unignored children with ignored parents should move up in the tree. |
| 310 TEST_F(NativeViewAccessibilityIgnoredElementsTest, ChildAtIndex) { |
| 311 EXPECT_EQ(b_nva_->GetNativeObject(), a_root_nva_->ChildAtIndex(0)); |
| 312 EXPECT_EQ(f_x3_x1_nva_->GetNativeObject(), a_root_nva_->ChildAtIndex(1)); |
| 313 EXPECT_EQ(e_x1_nva_->GetNativeObject(), a_root_nva_->ChildAtIndex(2)); |
| 314 EXPECT_EQ(nullptr, a_root_nva_->ChildAtIndex(3)); |
| 315 |
| 316 EXPECT_EQ(c_b_nva_->GetNativeObject(), b_nva_->ChildAtIndex(0)); |
| 317 EXPECT_EQ(d_b_nva_->GetNativeObject(), b_nva_->ChildAtIndex(1)); |
| 318 EXPECT_EQ(nullptr, b_nva_->ChildAtIndex(2)); |
| 319 |
| 320 EXPECT_EQ(f_x3_x1_nva_->GetNativeObject(), x1_nva_->ChildAtIndex(0)); |
| 321 EXPECT_EQ(e_x1_nva_->GetNativeObject(), x1_nva_->ChildAtIndex(1)); |
| 322 EXPECT_EQ(nullptr, x1_nva_->ChildAtIndex(2)); |
| 323 |
| 324 EXPECT_EQ(f_x3_x1_nva_->GetNativeObject(), x3_x1_nva_->ChildAtIndex(0)); |
| 325 |
| 326 // Node with ignored children. |
| 327 EXPECT_EQ(nullptr, c_b_nva_->ChildAtIndex(0)); |
| 328 // Node with 0 children. |
| 329 EXPECT_EQ(nullptr, d_b_nva_->ChildAtIndex(0)); |
| 330 // Ignored node with 0 children. |
| 331 EXPECT_EQ(nullptr, x2_b_nva_->ChildAtIndex(0)); |
| 332 } |
| 333 |
| 334 // Check the a11y parents returned correspond to their unignored children. |
| 335 TEST_F(NativeViewAccessibilityIgnoredElementsTest, GetParent) { |
| 336 EXPECT_EQ(a_root_->parent()->GetNativeViewAccessible(), |
| 337 a_root_nva_->GetParent()); |
| 338 EXPECT_EQ(a_root_->GetNativeViewAccessible(), b_nva_->GetParent()); |
| 339 EXPECT_EQ(b_nva_->GetNativeObject(), c_b_nva_->GetParent()); |
| 340 EXPECT_EQ(c_b_nva_->GetNativeObject(), x5_c_b_nva_->GetParent()); |
| 341 EXPECT_EQ(b_nva_->GetNativeObject(), d_b_nva_->GetParent()); |
| 342 EXPECT_EQ(b_nva_->GetNativeObject(), x2_b_nva_->GetParent()); |
| 343 EXPECT_EQ(a_root_->GetNativeViewAccessible(), x1_nva_->GetParent()); |
| 344 |
| 345 // Skips X1. |
| 346 EXPECT_EQ(a_root_->GetNativeViewAccessible(), x3_x1_nva_->GetParent()); |
| 347 EXPECT_EQ(a_root_->GetNativeViewAccessible(), x4_x1_nva_->GetParent()); |
| 348 EXPECT_EQ(a_root_->GetNativeViewAccessible(), e_x1_nva_->GetParent()); |
| 349 |
| 350 // Skips X3 and X1. |
| 351 EXPECT_EQ(a_root_->GetNativeViewAccessible(), f_x3_x1_nva_->GetParent()); |
| 352 } |
| 353 |
| 354 // Test that a11y hit tests work correctly with ignored elements. A hit on a |
| 355 // ignored element should return its first unignored ancestor. |
| 356 TEST_F(NativeViewAccessibilityIgnoredElementsTest, HitTestSync) { |
| 357 // Move the hit point horizontally, incrementing by the leaf View width. |
| 358 const int min_width = a_root_->GetBoundsInScreen().width() / 6; |
| 359 int curr_x = a_root_->GetBoundsInScreen().x() + min_width / 2; |
| 360 const int y = a_root_->GetBoundsInScreen().CenterPoint().y(); |
| 361 |
| 362 // HitTestSync isn't recursive, so manually do the recursion until arriving at |
| 363 // the correct answer. I.e., the last NativeViewAccessible being tested for |
| 364 // each |curr_x|, |y| pair below would be the correct return value if |
| 365 // HitTestSync were recursive. |
| 366 EXPECT_EQ(b_nva_->GetNativeObject(), a_root_nva_->HitTestSync(curr_x, y)); |
| 367 EXPECT_EQ(c_b_nva_->GetNativeObject(), b_nva_->HitTestSync(curr_x, y)); |
| 368 EXPECT_EQ(c_b_nva_->GetNativeObject(), c_b_nva_->HitTestSync(curr_x, y)); |
| 369 curr_x += min_width; |
| 370 EXPECT_EQ(b_nva_->GetNativeObject(), a_root_nva_->HitTestSync(curr_x, y)); |
| 371 EXPECT_EQ(d_b_nva_->GetNativeObject(), b_nva_->HitTestSync(curr_x, y)); |
| 372 curr_x += min_width; |
| 373 EXPECT_EQ(b_nva_->GetNativeObject(), a_root_nva_->HitTestSync(curr_x, y)); |
| 374 EXPECT_EQ(x2_b_nva_->GetNativeObject(), b_nva_->HitTestSync(curr_x, y)); |
| 375 EXPECT_EQ(nullptr, x2_b_nva_->HitTestSync(curr_x, y)); |
| 376 curr_x += min_width; |
| 377 EXPECT_EQ(x1_nva_->GetNativeObject(), a_root_nva_->HitTestSync(curr_x, y)); |
| 378 EXPECT_EQ(x3_x1_nva_->GetNativeObject(), x1_nva_->HitTestSync(curr_x, y)); |
| 379 EXPECT_EQ(f_x3_x1_nva_->GetNativeObject(), |
| 380 x3_x1_nva_->HitTestSync(curr_x, y)); |
| 381 curr_x += min_width; |
| 382 EXPECT_EQ(x1_nva_->GetNativeObject(), a_root_nva_->HitTestSync(curr_x, y)); |
| 383 EXPECT_EQ(x4_x1_nva_->GetNativeObject(), x1_nva_->HitTestSync(curr_x, y)); |
| 384 EXPECT_EQ(nullptr, x4_x1_nva_->HitTestSync(curr_x, y)); |
| 385 curr_x += min_width; |
| 386 EXPECT_EQ(x1_nva_->GetNativeObject(), a_root_nva_->HitTestSync(curr_x, y)); |
| 387 EXPECT_EQ(e_x1_nva_->GetNativeObject(), x1_nva_->HitTestSync(curr_x, y)); |
| 388 } |
| 389 |
160 } // namespace test | 390 } // namespace test |
161 } // namespace views | 391 } // namespace views |
OLD | NEW |