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