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

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: Linting & review comments. Created 3 years, 6 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
« no previous file with comments | « ui/views/accessibility/native_view_accessibility_base.cc ('k') | ui/views/view.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 class NativeViewAccessibilityTest;
21 22
22 namespace { 23 namespace {
23 24
24 class TestButton : public Button { 25 class TestButton : public Button {
25 public: 26 public:
26 TestButton() : Button(NULL) {} 27 TestButton() : Button(NULL) {}
27 }; 28 };
28 29
29 } // namespace 30 } // namespace
30 31
31 class NativeViewAccessibilityTest : public ViewsTestBase { 32 class NativeViewAccessibilityTest : public ViewsTestBase {
32 public: 33 public:
33 NativeViewAccessibilityTest() {} 34 NativeViewAccessibilityTest() {}
34 ~NativeViewAccessibilityTest() override {} 35 ~NativeViewAccessibilityTest() override {}
35 36
36 void SetUp() override { 37 void SetUp() override {
37 ViewsTestBase::SetUp(); 38 ViewsTestBase::SetUp();
38 39
39 widget_ = new views::Widget; 40 widget_ = new Widget;
40 views::Widget::InitParams params = 41 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
41 CreateParams(views::Widget::InitParams::TYPE_WINDOW);
42 params.bounds = gfx::Rect(0, 0, 200, 200); 42 params.bounds = gfx::Rect(0, 0, 200, 200);
43 widget_->Init(params); 43 widget_->Init(params);
44 44
45 button_ = new TestButton(); 45 button_ = new TestButton();
46 button_->SetSize(gfx::Size(20, 20)); 46 button_->SetSize(gfx::Size(20, 20));
47 button_accessibility_ = NativeViewAccessibility::Create(button_); 47 button_accessibility_ = NativeViewAccessibility::Create(button_);
48 48
49 label_ = new Label(); 49 label_ = new Label();
50 button_->AddChildView(label_); 50 button_->AddChildView(label_);
51 label_accessibility_ = NativeViewAccessibility::Create(label_); 51 label_accessibility_ = NativeViewAccessibility::Create(label_);
(...skipping 19 matching lines...) Expand all
71 } 71 }
72 72
73 bool SetFocused(NativeViewAccessibilityBase* view_accessibility, 73 bool SetFocused(NativeViewAccessibilityBase* view_accessibility,
74 bool focused) { 74 bool focused) {
75 ui::AXActionData data; 75 ui::AXActionData data;
76 data.action = focused ? ui::AX_ACTION_FOCUS : ui::AX_ACTION_BLUR; 76 data.action = focused ? ui::AX_ACTION_FOCUS : ui::AX_ACTION_BLUR;
77 return view_accessibility->AccessibilityPerformAction(data); 77 return view_accessibility->AccessibilityPerformAction(data);
78 } 78 }
79 79
80 protected: 80 protected:
81 views::Widget* widget_; 81 Widget* widget_;
82 TestButton* button_; 82 TestButton* button_;
83 std::unique_ptr<NativeViewAccessibility> button_accessibility_; 83 std::unique_ptr<NativeViewAccessibility> button_accessibility_;
84 Label* label_; 84 Label* label_;
85 std::unique_ptr<NativeViewAccessibility> label_accessibility_; 85 std::unique_ptr<NativeViewAccessibility> label_accessibility_;
86
87 DISALLOW_COPY_AND_ASSIGN(NativeViewAccessibilityTest);
86 }; 88 };
87 89
88 TEST_F(NativeViewAccessibilityTest, RoleShouldMatch) { 90 TEST_F(NativeViewAccessibilityTest, RoleShouldMatch) {
89 EXPECT_EQ(ui::AX_ROLE_BUTTON, button_accessibility()->GetData().role); 91 EXPECT_EQ(ui::AX_ROLE_BUTTON, button_accessibility()->GetData().role);
92 // Since the label is a subview of |button_|, and the button is keyboard
93 // focusable, the label is assumed to form part of the button and not have a
94 // role of its own.
95 EXPECT_EQ(ui::AX_ROLE_IGNORED, label_accessibility()->GetData().role);
96 // This will happen for all potentially keyboard-focusable Views with
97 // non-keyboard-focusable children, so if we make the button unfocusable, the
98 // label will be allowed to have its own role again.
99 button_->SetFocusBehavior(View::FocusBehavior::NEVER);
90 EXPECT_EQ(ui::AX_ROLE_STATIC_TEXT, label_accessibility()->GetData().role); 100 EXPECT_EQ(ui::AX_ROLE_STATIC_TEXT, label_accessibility()->GetData().role);
91 } 101 }
92 102
93 TEST_F(NativeViewAccessibilityTest, BoundsShouldMatch) { 103 TEST_F(NativeViewAccessibilityTest, BoundsShouldMatch) {
94 gfx::Rect bounds = 104 gfx::Rect bounds =
95 gfx::ToEnclosingRect(button_accessibility()->GetData().location); 105 gfx::ToEnclosingRect(button_accessibility()->GetData().location);
96 gfx::Rect screen_bounds = button_accessibility()->GetScreenBoundsRect(); 106 gfx::Rect screen_bounds = button_accessibility()->GetScreenBoundsRect();
97 107
98 EXPECT_EQ(button_->GetBoundsInScreen(), bounds); 108 EXPECT_EQ(button_->GetBoundsInScreen(), bounds);
99 EXPECT_EQ(screen_bounds, bounds); 109 EXPECT_EQ(screen_bounds, bounds);
100 } 110 }
101 111
102 TEST_F(NativeViewAccessibilityTest, LabelIsChildOfButton) { 112 TEST_F(NativeViewAccessibilityTest, LabelIsChildOfButton) {
113 // |button_| is focusable, so |label_| (as its child) should be ignored.
114 EXPECT_EQ(View::FocusBehavior::ACCESSIBLE_ONLY, button_->focus_behavior());
115 EXPECT_EQ(1, button_accessibility()->GetChildCount());
116 EXPECT_EQ(button_->GetNativeViewAccessible(),
117 label_accessibility()->GetParent());
118 EXPECT_EQ(ui::AX_ROLE_IGNORED, label_accessibility()->GetData().role);
119
120 // If |button_| is no longer focusable, |label_| should show up again.
121 button_->SetFocusBehavior(View::FocusBehavior::NEVER);
103 EXPECT_EQ(1, button_accessibility()->GetChildCount()); 122 EXPECT_EQ(1, button_accessibility()->GetChildCount());
104 EXPECT_EQ(label_->GetNativeViewAccessible(), 123 EXPECT_EQ(label_->GetNativeViewAccessible(),
105 button_accessibility()->ChildAtIndex(0)); 124 button_accessibility()->ChildAtIndex(0));
106 EXPECT_EQ(button_->GetNativeViewAccessible(), 125 EXPECT_EQ(button_->GetNativeViewAccessible(),
107 label_accessibility()->GetParent()); 126 label_accessibility()->GetParent());
127 EXPECT_NE(ui::AX_ROLE_IGNORED, label_accessibility()->GetData().role);
108 } 128 }
109 129
110 // Verify Views with invisible ancestors have AX_STATE_INVISIBLE. 130 // Verify Views with invisible ancestors have AX_STATE_INVISIBLE.
111 TEST_F(NativeViewAccessibilityTest, InvisibleViews) { 131 TEST_F(NativeViewAccessibilityTest, InvisibleViews) {
112 EXPECT_TRUE(widget_->IsVisible()); 132 EXPECT_TRUE(widget_->IsVisible());
113 EXPECT_FALSE( 133 EXPECT_FALSE(
114 button_accessibility()->GetData().HasState(ui::AX_STATE_INVISIBLE)); 134 button_accessibility()->GetData().HasState(ui::AX_STATE_INVISIBLE));
115 EXPECT_FALSE( 135 EXPECT_FALSE(
116 label_accessibility()->GetData().HasState(ui::AX_STATE_INVISIBLE)); 136 label_accessibility()->GetData().HasState(ui::AX_STATE_INVISIBLE));
117 button_->SetVisible(false); 137 button_->SetVisible(false);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 bool is_destroying_parent_widget = (parent_widget_ == widget); 171 bool is_destroying_parent_widget = (parent_widget_ == widget);
152 NativeViewAccessibilityBase::OnWidgetDestroying(widget); 172 NativeViewAccessibilityBase::OnWidgetDestroying(widget);
153 if (is_destroying_parent_widget) 173 if (is_destroying_parent_widget)
154 delete this; 174 delete this;
155 } 175 }
156 }; 176 };
157 177
158 TEST_F(NativeViewAccessibilityTest, CrashOnWidgetDestroyed) { 178 TEST_F(NativeViewAccessibilityTest, CrashOnWidgetDestroyed) {
159 std::unique_ptr<Widget> parent_widget(new Widget); 179 std::unique_ptr<Widget> parent_widget(new Widget);
160 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); 180 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
161 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 181 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
162 params.bounds = gfx::Rect(50, 50, 650, 650); 182 params.bounds = gfx::Rect(50, 50, 650, 650);
163 parent_widget->Init(params); 183 parent_widget->Init(params);
164 184
165 std::unique_ptr<Widget> child_widget(new Widget); 185 std::unique_ptr<Widget> child_widget(new Widget);
166 child_widget->Init(params); 186 child_widget->Init(params);
167 187
168 // Make sure that deleting the parent widget can't cause a crash 188 // Make sure that deleting the parent widget can't cause a crash
169 // due to NativeViewAccessibility not unregistering itself as a 189 // due to NativeViewAccessibility not unregistering itself as a
170 // WidgetObserver. Note that TestNativeViewAccessibility is a subclass 190 // WidgetObserver. Note that TestNativeViewAccessibility is a subclass
171 // defined above that destroys itself when its parent widget is destroyed. 191 // defined above that destroys itself when its parent widget is destroyed.
(...skipping 10 matching lines...) Expand all
182 ~DerivedTestView() override {} 202 ~DerivedTestView() override {}
183 203
184 void OnBlur() override { SetVisible(false); } 204 void OnBlur() override { SetVisible(false); }
185 }; 205 };
186 206
187 class AxTestViewsDelegate : public TestViewsDelegate { 207 class AxTestViewsDelegate : public TestViewsDelegate {
188 public: 208 public:
189 AxTestViewsDelegate() {} 209 AxTestViewsDelegate() {}
190 ~AxTestViewsDelegate() override {} 210 ~AxTestViewsDelegate() override {}
191 211
192 void NotifyAccessibilityEvent(views::View* view, 212 void NotifyAccessibilityEvent(View* view, ui::AXEvent event_type) override {
193 ui::AXEvent event_type) override {
194 AXAuraObjCache* ax = AXAuraObjCache::GetInstance(); 213 AXAuraObjCache* ax = AXAuraObjCache::GetInstance();
195 std::vector<AXAuraObjWrapper*> out_children; 214 std::vector<AXAuraObjWrapper*> out_children;
196 AXAuraObjWrapper* ax_obj = ax->GetOrCreate(view->GetWidget()); 215 AXAuraObjWrapper* ax_obj = ax->GetOrCreate(view->GetWidget());
197 ax_obj->GetChildren(&out_children); 216 ax_obj->GetChildren(&out_children);
198 } 217 }
199 218
200 private: 219 private:
201 DISALLOW_COPY_AND_ASSIGN(AxTestViewsDelegate); 220 DISALLOW_COPY_AND_ASSIGN(AxTestViewsDelegate);
202 }; 221 };
203 222
204 class AXViewTest : public ViewsTestBase { 223 class AXViewTest : public ViewsTestBase {
205 public: 224 public:
206 AXViewTest() {} 225 AXViewTest() {}
207 ~AXViewTest() override {} 226 ~AXViewTest() override {}
208 void SetUp() override { 227 void SetUp() override {
209 std::unique_ptr<TestViewsDelegate> views_delegate( 228 std::unique_ptr<TestViewsDelegate> views_delegate(
210 new AxTestViewsDelegate()); 229 new AxTestViewsDelegate());
211 set_views_delegate(std::move(views_delegate)); 230 set_views_delegate(std::move(views_delegate));
212 views::ViewsTestBase::SetUp(); 231 ViewsTestBase::SetUp();
213 } 232 }
214 }; 233 };
215 234
216 // Check if the destruction of the widget ends successfully if |view|'s 235 // Check if the destruction of the widget ends successfully if |view|'s
217 // visibility changed during destruction. 236 // visibility changed during destruction.
218 TEST_F(AXViewTest, LayoutCalledInvalidateRootView) { 237 TEST_F(AXViewTest, LayoutCalledInvalidateRootView) {
219 std::unique_ptr<Widget> widget(new Widget); 238 std::unique_ptr<Widget> widget(new Widget);
220 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); 239 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
221 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 240 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
222 widget->Init(params); 241 widget->Init(params);
223 widget->Show(); 242 widget->Show();
224 243
225 View* root = widget->GetRootView(); 244 View* root = widget->GetRootView();
226 DerivedTestView* parent = new DerivedTestView(); 245 DerivedTestView* parent = new DerivedTestView();
227 DerivedTestView* child = new DerivedTestView(); 246 DerivedTestView* child = new DerivedTestView();
228 root->AddChildView(parent); 247 root->AddChildView(parent);
229 parent->AddChildView(child); 248 parent->AddChildView(child);
230 child->SetFocusBehavior(DerivedTestView::FocusBehavior::ALWAYS); 249 child->SetFocusBehavior(DerivedTestView::FocusBehavior::ALWAYS);
231 parent->SetFocusBehavior(DerivedTestView::FocusBehavior::ALWAYS); 250 parent->SetFocusBehavior(DerivedTestView::FocusBehavior::ALWAYS);
232 root->SetFocusBehavior(DerivedTestView::FocusBehavior::ALWAYS); 251 root->SetFocusBehavior(DerivedTestView::FocusBehavior::ALWAYS);
233 parent->RequestFocus(); 252 parent->RequestFocus();
234 // During the destruction of parent, OnBlur will be called and change the 253 // During the destruction of parent, OnBlur will be called and change the
235 // visibility to false. 254 // visibility to false.
236 parent->SetVisible(true); 255 parent->SetVisible(true);
237 AXAuraObjCache* ax = AXAuraObjCache::GetInstance(); 256 AXAuraObjCache* ax = AXAuraObjCache::GetInstance();
238 ax->GetOrCreate(widget.get()); 257 ax->GetOrCreate(widget.get());
239 } 258 }
240 #endif 259 #endif
241 260
242 } // namespace test 261 } // namespace test
243 } // namespace views 262 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/accessibility/native_view_accessibility_base.cc ('k') | ui/views/view.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698