Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(972)

Side by Side Diff: ui/views/accessibility/native_view_accessibility_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698