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