OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 <memory> | 5 #include <memory> |
6 | 6 |
7 #import <Cocoa/Cocoa.h> | 7 #import <Cocoa/Cocoa.h> |
8 | 8 |
9 #include "base/strings/sys_string_conversions.h" | 9 #include "base/strings/sys_string_conversions.h" |
10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
11 #import "testing/gtest_mac.h" | 11 #import "testing/gtest_mac.h" |
12 #include "ui/accessibility/ax_enums.h" | 12 #include "ui/accessibility/ax_enums.h" |
13 #include "ui/accessibility/ax_view_state.h" | 13 #include "ui/accessibility/ax_view_state.h" |
14 #import "ui/accessibility/platform/ax_platform_node_mac.h" | 14 #import "ui/accessibility/platform/ax_platform_node_mac.h" |
15 #include "ui/base/ime/text_input_type.h" | 15 #include "ui/base/ime/text_input_type.h" |
16 #import "ui/gfx/mac/coordinate_conversion.h" | 16 #import "ui/gfx/mac/coordinate_conversion.h" |
| 17 #include "ui/views/accessibility/native_view_accessibility.h" |
17 #include "ui/views/controls/label.h" | 18 #include "ui/views/controls/label.h" |
18 #include "ui/views/controls/textfield/textfield.h" | 19 #include "ui/views/controls/textfield/textfield.h" |
19 #include "ui/views/test/widget_test.h" | 20 #include "ui/views/test/widget_test.h" |
20 #include "ui/views/widget/widget.h" | 21 #include "ui/views/widget/widget.h" |
21 | 22 |
22 // Expose some methods from AXPlatformNodeCocoa for testing purposes only. | 23 // Expose some methods from AXPlatformNodeCocoa for testing purposes only. |
23 @interface AXPlatformNodeCocoa (Testing) | 24 @interface AXPlatformNodeCocoa (Testing) |
24 - (NSString*)AXRole; | 25 - (NSString*)AXRole; |
25 @end | 26 @end |
26 | 27 |
27 namespace views { | 28 namespace views { |
28 | 29 |
29 namespace { | 30 namespace { |
30 | 31 |
31 NSString* const kTestPlaceholderText = @"Test placeholder text"; | 32 NSString* const kTestPlaceholderText = @"Test placeholder text"; |
32 NSString* const kTestStringValue = @"Test string value"; | 33 NSString* const kTestStringValue = @"Test string value"; |
33 NSString* const kTestTitle = @"Test textfield"; | 34 NSString* const kTestTitle = @"Test textfield"; |
34 | 35 |
35 class FlexibleRoleTestView : public View { | 36 class FlexibleRoleTestView : public View { |
36 public: | 37 public: |
37 explicit FlexibleRoleTestView(ui::AXRole role) : role_(role) {} | 38 explicit FlexibleRoleTestView(ui::AXRole role) : role_(role) { |
| 39 SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY); |
| 40 } |
| 41 |
38 void set_role(ui::AXRole role) { role_ = role; } | 42 void set_role(ui::AXRole role) { role_ = role; } |
39 | 43 |
40 // Add a child view and resize to fit the child. | 44 // Add a child view and resize to fit the child. |
41 void FitBoundsToNewChild(View* view) { | 45 void FitBoundsToNewChild(View* view) { |
42 View::AddChildView(view); | 46 View::AddChildView(view); |
43 // Fit the parent widget to the size of the child for accurate hit tests. | 47 // Fit the parent widget to the size of the child for accurate hit tests. |
44 SetBoundsRect(view->bounds()); | 48 SetBoundsRect(view->bounds()); |
45 } | 49 } |
46 | 50 |
47 // View: | 51 // View: |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 | 108 |
105 // Test for NSAccessibilityChildrenAttribute, and ensure it excludes ignored | 109 // Test for NSAccessibilityChildrenAttribute, and ensure it excludes ignored |
106 // children from the accessibility tree. | 110 // children from the accessibility tree. |
107 TEST_F(NativeWidgetMacAccessibilityTest, ChildrenAttribute) { | 111 TEST_F(NativeWidgetMacAccessibilityTest, ChildrenAttribute) { |
108 // Check childless views don't have accessibility children. | 112 // Check childless views don't have accessibility children. |
109 EXPECT_EQ(0u, | 113 EXPECT_EQ(0u, |
110 [AttributeValueAtMidpoint(NSAccessibilityChildrenAttribute) count]); | 114 [AttributeValueAtMidpoint(NSAccessibilityChildrenAttribute) count]); |
111 | 115 |
112 const size_t kNumChildren = 3; | 116 const size_t kNumChildren = 3; |
113 for (size_t i = 0; i < kNumChildren; ++i) { | 117 for (size_t i = 0; i < kNumChildren; ++i) { |
114 // Make sure the labels won't interfere with the hit test. | 118 // Add children sized 0x0 to ensure they won't interfere with the hit tests. |
115 AddChildTextfield(gfx::Size()); | 119 AddChildTextfield(gfx::Size()); |
116 } | 120 } |
117 | 121 |
118 EXPECT_EQ(kNumChildren, | 122 EXPECT_EQ(kNumChildren, |
119 [AttributeValueAtMidpoint(NSAccessibilityChildrenAttribute) count]); | 123 [AttributeValueAtMidpoint(NSAccessibilityChildrenAttribute) count]); |
120 | 124 |
121 // Check ignored children don't show up in the accessibility tree. | 125 // Check ignored children don't show up in the accessibility tree. |
122 widget()->GetContentsView()->AddChildView( | 126 widget()->GetContentsView()->AddChildView( |
123 new FlexibleRoleTestView(ui::AX_ROLE_IGNORED)); | 127 new FlexibleRoleTestView(ui::AX_ROLE_IGNORED)); |
124 EXPECT_EQ(kNumChildren, | 128 EXPECT_EQ(kNumChildren, |
125 [AttributeValueAtMidpoint(NSAccessibilityChildrenAttribute) count]); | 129 [AttributeValueAtMidpoint(NSAccessibilityChildrenAttribute) count]); |
126 } | 130 } |
127 | 131 |
128 // Test for NSAccessibilityParentAttribute, including for a Widget with no | 132 // Test for NSAccessibilityParentAttribute, including for a Widget with no |
129 // parent. | 133 // parent. |
130 TEST_F(NativeWidgetMacAccessibilityTest, ParentAttribute) { | 134 TEST_F(NativeWidgetMacAccessibilityTest, ParentAttribute) { |
131 Textfield* child = AddChildTextfield(widget()->GetContentsView()->size()); | 135 Textfield* child = AddChildTextfield(widget()->GetContentsView()->size()); |
132 | 136 |
133 // Views with Widget parents will have a NSWindow parent. | 137 // Views with Widget parents will have a RootView (BridgedContentView) parent, |
134 EXPECT_NSEQ( | 138 // which doesn't use the legacy NSAccessibility Informal Protocol Reference, |
135 NSAccessibilityWindowRole, | 139 // so retrieve the AXRole via accessibilityAttributeValue instead. |
136 [AttributeValueAtMidpoint(NSAccessibilityParentAttribute) AXRole]); | 140 EXPECT_NSEQ(NSAccessibilityWindowRole, |
| 141 [AttributeValueAtMidpoint(NSAccessibilityParentAttribute) |
| 142 accessibilityAttributeValue:NSAccessibilityRoleAttribute]); |
137 | 143 |
138 // Views with non-Widget parents will have the role of the parent view. | 144 // Children of other Views will report their View parent's role. |
139 widget()->GetContentsView()->RemoveChildView(child); | 145 widget()->GetContentsView()->RemoveChildView(child); |
140 FlexibleRoleTestView* parent = new FlexibleRoleTestView(ui::AX_ROLE_GROUP); | 146 FlexibleRoleTestView* parent = new FlexibleRoleTestView(ui::AX_ROLE_GROUP); |
141 parent->FitBoundsToNewChild(child); | 147 parent->FitBoundsToNewChild(child); |
142 widget()->GetContentsView()->AddChildView(parent); | 148 widget()->GetContentsView()->AddChildView(parent); |
143 EXPECT_NSEQ( | 149 EXPECT_NSEQ( |
144 NSAccessibilityGroupRole, | 150 NSAccessibilityGroupRole, |
145 [AttributeValueAtMidpoint(NSAccessibilityParentAttribute) AXRole]); | 151 [AttributeValueAtMidpoint(NSAccessibilityParentAttribute) AXRole]); |
146 | 152 |
147 // Test an ignored role parent is skipped in favor of the grandparent. | 153 // Test an ignored role parent is skipped in favor of the grandparent. |
148 parent->set_role(ui::AX_ROLE_IGNORED); | 154 parent->set_role(ui::AX_ROLE_IGNORED); |
149 EXPECT_NSEQ( | 155 EXPECT_NSEQ(NSAccessibilityWindowRole, |
150 NSAccessibilityWindowRole, | 156 [AttributeValueAtMidpoint(NSAccessibilityParentAttribute) |
151 [AttributeValueAtMidpoint(NSAccessibilityParentAttribute) AXRole]); | 157 accessibilityAttributeValue:NSAccessibilityRoleAttribute]); |
152 } | 158 } |
153 | 159 |
154 // Test for NSAccessibilityPositionAttribute, including on Widget movement | 160 // Test for NSAccessibilityPositionAttribute, including on Widget movement |
155 // updates. | 161 // updates. |
156 TEST_F(NativeWidgetMacAccessibilityTest, PositionAttribute) { | 162 TEST_F(NativeWidgetMacAccessibilityTest, PositionAttribute) { |
157 NSValue* widget_origin = | 163 NSValue* widget_origin = |
158 [NSValue valueWithPoint:gfx::ScreenPointToNSPoint( | 164 [NSValue valueWithPoint:gfx::ScreenPointToNSPoint( |
159 GetWidgetBounds().bottom_left())]; | 165 GetWidgetBounds().bottom_left())]; |
160 EXPECT_NSEQ(widget_origin, | 166 EXPECT_NSEQ(widget_origin, |
161 AttributeValueAtMidpoint(NSAccessibilityPositionAttribute)); | 167 AttributeValueAtMidpoint(NSAccessibilityPositionAttribute)); |
162 | 168 |
163 // Check the attribute is updated when the Widget is moved. | 169 // Check the attribute is updated when the Widget is moved. |
164 gfx::Rect new_bounds(60, 80, 100, 100); | 170 gfx::Rect new_bounds(60, 80, 100, 100); |
165 widget()->SetBounds(new_bounds); | 171 widget()->SetBounds(new_bounds); |
166 widget_origin = [NSValue | 172 widget_origin = [NSValue |
167 valueWithPoint:gfx::ScreenPointToNSPoint(new_bounds.bottom_left())]; | 173 valueWithPoint:gfx::ScreenPointToNSPoint(new_bounds.bottom_left())]; |
168 EXPECT_NSEQ(widget_origin, | 174 EXPECT_NSEQ(widget_origin, |
169 AttributeValueAtMidpoint(NSAccessibilityPositionAttribute)); | 175 AttributeValueAtMidpoint(NSAccessibilityPositionAttribute)); |
| 176 |
| 177 // Check the attribute is correct for a View. |
| 178 Textfield* textfield = AddChildTextfield(gfx::Size(70, 70)); |
| 179 widget_origin = [NSValue |
| 180 valueWithPoint:gfx::ScreenPointToNSPoint( |
| 181 textfield->GetBoundsInScreen().bottom_left())]; |
| 182 EXPECT_NSEQ(NSAccessibilityTextFieldRole, |
| 183 AttributeValueAtMidpoint(NSAccessibilityRoleAttribute)); |
| 184 EXPECT_NSEQ(widget_origin, |
| 185 AttributeValueAtMidpoint(NSAccessibilityPositionAttribute)); |
170 } | 186 } |
171 | 187 |
172 // Test for NSAccessibilityHelpAttribute. | 188 // Test for NSAccessibilityHelpAttribute. |
173 TEST_F(NativeWidgetMacAccessibilityTest, HelpAttribute) { | 189 TEST_F(NativeWidgetMacAccessibilityTest, HelpAttribute) { |
174 Label* label = new Label(base::SysNSStringToUTF16(kTestPlaceholderText)); | 190 Label* label = new Label(base::SysNSStringToUTF16(kTestPlaceholderText)); |
| 191 label->SetFocusBehavior(ClientView::FocusBehavior::ACCESSIBLE_ONLY); |
175 label->SetSize(GetWidgetBounds().size()); | 192 label->SetSize(GetWidgetBounds().size()); |
176 EXPECT_NSEQ(nil, AttributeValueAtMidpoint(NSAccessibilityHelpAttribute)); | 193 EXPECT_NSEQ(nil, AttributeValueAtMidpoint(NSAccessibilityHelpAttribute)); |
177 label->SetTooltipText(base::SysNSStringToUTF16(kTestPlaceholderText)); | 194 label->SetTooltipText(base::SysNSStringToUTF16(kTestPlaceholderText)); |
178 widget()->GetContentsView()->AddChildView(label); | 195 widget()->GetContentsView()->AddChildView(label); |
179 EXPECT_NSEQ(kTestPlaceholderText, | 196 EXPECT_NSEQ(kTestPlaceholderText, |
180 AttributeValueAtMidpoint(NSAccessibilityHelpAttribute)); | 197 AttributeValueAtMidpoint(NSAccessibilityHelpAttribute)); |
181 } | 198 } |
182 | 199 |
183 // Test for NSAccessibilityWindowAttribute and | 200 // Test for NSAccessibilityWindowAttribute and |
184 // NSAccessibilityTopLevelUIElementAttribute. | 201 // NSAccessibilityTopLevelUIElementAttribute. |
(...skipping 12 matching lines...) Expand all Loading... |
197 } | 214 } |
198 | 215 |
199 // Tests for accessibility attributes on a views::Textfield. | 216 // Tests for accessibility attributes on a views::Textfield. |
200 // TODO(patricialor): Test against Cocoa-provided attributes as well to ensure | 217 // TODO(patricialor): Test against Cocoa-provided attributes as well to ensure |
201 // consistency between Cocoa and toolkit-views. | 218 // consistency between Cocoa and toolkit-views. |
202 TEST_F(NativeWidgetMacAccessibilityTest, TextfieldGenericAttributes) { | 219 TEST_F(NativeWidgetMacAccessibilityTest, TextfieldGenericAttributes) { |
203 Textfield* textfield = AddChildTextfield(GetWidgetBounds().size()); | 220 Textfield* textfield = AddChildTextfield(GetWidgetBounds().size()); |
204 | 221 |
205 // NSAccessibilityEnabledAttribute. | 222 // NSAccessibilityEnabledAttribute. |
206 textfield->SetEnabled(false); | 223 textfield->SetEnabled(false); |
| 224 // Disabled items should be unfocusable but shouldn't be ignored. |
| 225 EXPECT_FALSE(textfield->IsAccessibilityFocusable()); |
| 226 EXPECT_FALSE(textfield->GetNativeViewAccessibility()->IsIgnored()); |
207 EXPECT_EQ(NO, [AttributeValueAtMidpoint(NSAccessibilityEnabledAttribute) | 227 EXPECT_EQ(NO, [AttributeValueAtMidpoint(NSAccessibilityEnabledAttribute) |
208 boolValue]); | 228 boolValue]); |
209 textfield->SetEnabled(true); | 229 textfield->SetEnabled(true); |
210 EXPECT_EQ(YES, [AttributeValueAtMidpoint(NSAccessibilityEnabledAttribute) | 230 EXPECT_EQ(YES, [AttributeValueAtMidpoint(NSAccessibilityEnabledAttribute) |
211 boolValue]); | 231 boolValue]); |
212 | 232 |
213 // NSAccessibilityFocusedAttribute. | 233 // NSAccessibilityFocusedAttribute. |
214 EXPECT_EQ(NO, [AttributeValueAtMidpoint(NSAccessibilityFocusedAttribute) | 234 EXPECT_EQ(NO, [AttributeValueAtMidpoint(NSAccessibilityFocusedAttribute) |
215 boolValue]); | 235 boolValue]); |
216 textfield->RequestFocus(); | 236 textfield->RequestFocus(); |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 EXPECT_FALSE( | 352 EXPECT_FALSE( |
333 [ax_node accessibilityIsAttributeSettable:NSAccessibilityValueAttribute]); | 353 [ax_node accessibilityIsAttributeSettable:NSAccessibilityValueAttribute]); |
334 [ax_node accessibilitySetValue:kTestStringValue | 354 [ax_node accessibilitySetValue:kTestStringValue |
335 forAttribute:NSAccessibilityValueAttribute]; | 355 forAttribute:NSAccessibilityValueAttribute]; |
336 EXPECT_NSEQ(kTestPlaceholderText, | 356 EXPECT_NSEQ(kTestPlaceholderText, |
337 AttributeValueAtMidpoint(NSAccessibilityValueAttribute)); | 357 AttributeValueAtMidpoint(NSAccessibilityValueAttribute)); |
338 EXPECT_EQ(base::SysNSStringToUTF16(kTestPlaceholderText), textfield->text()); | 358 EXPECT_EQ(base::SysNSStringToUTF16(kTestPlaceholderText), textfield->text()); |
339 } | 359 } |
340 | 360 |
341 } // namespace views | 361 } // namespace views |
OLD | NEW |