OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <vector> | 5 #include <vector> |
6 | 6 |
7 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
9 #include "base/strings/sys_string_conversions.h" | |
9 #include "base/win/scoped_bstr.h" | 10 #include "base/win/scoped_bstr.h" |
10 #include "base/win/scoped_comptr.h" | 11 #include "base/win/scoped_comptr.h" |
11 #include "base/win/scoped_variant.h" | 12 #include "base/win/scoped_variant.h" |
12 #include "content/browser/accessibility/accessibility_mode_helper.h" | 13 #include "content/browser/accessibility/accessibility_mode_helper.h" |
14 #include "content/browser/accessibility/accessibility_tree_formatter.h" | |
13 #include "content/browser/accessibility/accessibility_tree_formatter_utils_win.h " | 15 #include "content/browser/accessibility/accessibility_tree_formatter_utils_win.h " |
14 #include "content/browser/renderer_host/render_view_host_impl.h" | 16 #include "content/browser/renderer_host/render_view_host_impl.h" |
15 #include "content/public/browser/notification_service.h" | 17 #include "content/public/browser/notification_service.h" |
16 #include "content/public/browser/notification_types.h" | 18 #include "content/public/browser/notification_types.h" |
17 #include "content/public/browser/render_frame_host.h" | 19 #include "content/public/browser/render_frame_host.h" |
18 #include "content/public/browser/render_widget_host_view.h" | 20 #include "content/public/browser/render_widget_host_view.h" |
19 #include "content/public/browser/web_contents.h" | 21 #include "content/public/browser/web_contents.h" |
20 #include "content/public/common/url_constants.h" | 22 #include "content/public/common/url_constants.h" |
21 #include "content/public/test/content_browser_test.h" | 23 #include "content/public/test/content_browser_test.h" |
22 #include "content/public/test/content_browser_test_utils.h" | 24 #include "content/public/test/content_browser_test_utils.h" |
23 #include "content/shell/browser/shell.h" | 25 #include "content/shell/browser/shell.h" |
24 #include "content/test/accessibility_browser_test_utils.h" | 26 #include "content/test/accessibility_browser_test_utils.h" |
27 #include "net/base/escape.h" | |
25 #include "third_party/iaccessible2/ia2_api_all.h" | 28 #include "third_party/iaccessible2/ia2_api_all.h" |
26 #include "third_party/isimpledom/ISimpleDOMNode.h" | 29 #include "third_party/isimpledom/ISimpleDOMNode.h" |
27 #include "ui/aura/window.h" | 30 #include "ui/aura/window.h" |
28 #include "ui/aura/window_tree_host.h" | 31 #include "ui/aura/window_tree_host.h" |
29 | 32 |
30 namespace content { | 33 namespace content { |
31 | 34 |
32 namespace { | 35 namespace { |
33 | 36 |
34 // Helpers -------------------------------------------------------------------- | |
35 | 37 |
36 base::win::ScopedComPtr<IAccessible> GetAccessibleFromResultVariant( | 38 const char INPUT_CONTENTS[] = "Moz/5.0 (ST 6.x; WWW33) " |
39 "WebKit \"KHTML, like\"."; | |
40 const char TEXTAREA_CONTENTS[] = "Moz/5.0 (ST 6.x; WWW33)\n" | |
41 "WebKit \n\"KHTML, like\"."; | |
42 const LONG CONTENTS_LENGTH = static_cast<LONG>( | |
43 (sizeof(INPUT_CONTENTS) - 1) / sizeof(char)); | |
44 | |
45 | |
46 // AccessibilityWinBrowserTest ------------------------------------------------ | |
47 | |
48 class AccessibilityWinBrowserTest : public ContentBrowserTest { | |
49 public: | |
50 AccessibilityWinBrowserTest(); | |
51 virtual ~AccessibilityWinBrowserTest(); | |
52 | |
53 protected: | |
54 class AccessibleChecker; | |
55 void LoadInitialAccessibilityTreeFromHtml(const std::string& html); | |
56 IAccessible* GetRendererAccessible(); | |
57 void ExecuteScript(const std::wstring& script); | |
58 void SetUpInputField( | |
59 base::win::ScopedComPtr<IAccessibleText>* input_text); | |
60 void SetUpTextareaField( | |
61 base::win::ScopedComPtr<IAccessibleText>* textarea_text); | |
62 | |
63 | |
64 static base::win::ScopedComPtr<IAccessible> | |
65 AccessibilityWinBrowserTest::GetAccessibleFromVariant( | |
66 IAccessible* parent, | |
67 VARIANT* var); | |
68 static HRESULT QueryIAccessible2(IAccessible* accessible, | |
69 IAccessible2** accessible2); | |
70 static void FindNodeInAccessibilityTree(IAccessible* node, | |
71 int32 expected_role, | |
72 const std::wstring& expected_name, | |
73 int32 depth, | |
74 bool* found); | |
75 static void CheckTextAtOffset( | |
76 base::win::ScopedComPtr<IAccessibleText>& element, | |
77 LONG offset, | |
78 IA2TextBoundaryType boundary_type, | |
79 LONG expected_start_offset, | |
80 LONG expected_end_offset, | |
81 const std::wstring& expected_text); | |
82 static std::vector<base::win::ScopedVariant> GetAllAccessibleChildren( | |
83 IAccessible* element); | |
84 | |
85 private: | |
86 DISALLOW_COPY_AND_ASSIGN(AccessibilityWinBrowserTest); | |
87 }; | |
88 | |
89 AccessibilityWinBrowserTest::AccessibilityWinBrowserTest() { | |
90 } | |
91 | |
92 AccessibilityWinBrowserTest::~AccessibilityWinBrowserTest() { | |
93 } | |
94 | |
95 void AccessibilityWinBrowserTest::LoadInitialAccessibilityTreeFromHtml( | |
96 const std::string& html) { | |
97 AccessibilityNotificationWaiter waiter( | |
98 shell(), AccessibilityModeComplete, | |
99 ui::AX_EVENT_LOAD_COMPLETE); | |
100 GURL html_data_url("data:text/html," + html); | |
101 NavigateToURL(shell(), html_data_url); | |
102 waiter.WaitForNotification(); | |
103 } | |
104 | |
105 // Retrieve the MSAA client accessibility object for the Render Widget Host View | |
106 // of the selected tab. | |
107 IAccessible* AccessibilityWinBrowserTest::GetRendererAccessible() { | |
108 content::WebContents* web_contents = shell()->web_contents(); | |
109 return web_contents->GetRenderWidgetHostView()->GetNativeViewAccessible(); | |
110 } | |
111 | |
112 void AccessibilityWinBrowserTest::ExecuteScript(const std::wstring& script) { | |
113 shell()->web_contents()->GetMainFrame()->ExecuteJavaScript(script); | |
114 } | |
115 | |
116 // Loads a page with an input text field and places sample text in it. Also, | |
117 // places the caret on the last character. | |
118 void AccessibilityWinBrowserTest::SetUpInputField( | |
119 base::win::ScopedComPtr<IAccessibleText>* input_text) { | |
120 ASSERT_NE(nullptr, input_text); | |
121 LoadInitialAccessibilityTreeFromHtml(std::string("<!DOCTYPE html><html><body>" | |
122 "<form><label for='textField'>Browser name:</label>" | |
123 "<input type='text' id='textField' name='name' value='") + | |
124 net::EscapeQueryParamValue(INPUT_CONTENTS, false) + std::string( | |
125 "'></form></body></html>")); | |
126 | |
127 // Retrieve the IAccessible interface for the web page. | |
128 base::win::ScopedComPtr<IAccessible> document(GetRendererAccessible()); | |
129 std::vector<base::win::ScopedVariant> document_children = | |
130 GetAllAccessibleChildren(document.get()); | |
131 ASSERT_EQ(1, document_children.size()); | |
132 | |
133 base::win::ScopedComPtr<IAccessible2> form; | |
134 HRESULT hr = QueryIAccessible2(GetAccessibleFromVariant( | |
135 document.get(), document_children[0].AsInput()).get(), form.Receive()); | |
136 ASSERT_EQ(S_OK, hr); | |
137 std::vector<base::win::ScopedVariant> form_children = | |
138 GetAllAccessibleChildren(form.get()); | |
139 ASSERT_EQ(2, form_children.size()); | |
140 | |
141 // Find the input text field. | |
142 base::win::ScopedComPtr<IAccessible2> input; | |
143 hr = QueryIAccessible2(GetAccessibleFromVariant( | |
144 form.get(), form_children[1].AsInput()).get(), input.Receive()); | |
145 ASSERT_EQ(S_OK, hr); | |
146 LONG input_role = 0; | |
147 hr = input->role(&input_role); | |
148 ASSERT_EQ(S_OK, hr); | |
149 ASSERT_EQ(ROLE_SYSTEM_TEXT, input_role); | |
150 | |
151 // Retrieve the IAccessibleText interface for the field. | |
152 hr = input.QueryInterface(input_text->Receive()); | |
153 ASSERT_EQ(S_OK, hr); | |
154 | |
155 // Set the caret on the last character. | |
156 AccessibilityNotificationWaiter waiter( | |
157 shell(), AccessibilityModeComplete, | |
158 ui::AX_EVENT_TEXT_SELECTION_CHANGED); | |
159 std::wstring caret_offset = base::UTF16ToWide(base::IntToString16( | |
160 static_cast<int>(CONTENTS_LENGTH - 1))); | |
161 ExecuteScript(std::wstring( | |
162 L"var textField = document.getElementById('textField');" | |
163 L"textField.focus();" | |
164 L"textField.setSelectionRange(") + | |
165 caret_offset + L"," + caret_offset + L");"); | |
166 waiter.WaitForNotification(); | |
167 } | |
168 | |
169 // Loads a page with a textarea text field and places sample text in it. Also, | |
170 // places the caret on the last character. | |
171 void AccessibilityWinBrowserTest::SetUpTextareaField( | |
172 base::win::ScopedComPtr<IAccessibleText>* textarea_text) { | |
173 ASSERT_NE(nullptr, textarea_text); | |
174 LoadInitialAccessibilityTreeFromHtml(std::string("<!DOCTYPE html><html><body>" | |
175 "<textarea id='textField' rows='3' cols='60'>") + | |
176 net::EscapeQueryParamValue(TEXTAREA_CONTENTS, false) + std::string( | |
177 "</textarea></body></html>")); | |
178 | |
179 // Retrieve the IAccessible interface for the web page. | |
180 base::win::ScopedComPtr<IAccessible> document(GetRendererAccessible()); | |
181 std::vector<base::win::ScopedVariant> document_children = | |
182 GetAllAccessibleChildren(document.get()); | |
183 ASSERT_EQ(1, document_children.size()); | |
184 | |
185 base::win::ScopedComPtr<IAccessible2> section; | |
186 HRESULT hr = QueryIAccessible2(GetAccessibleFromVariant( | |
187 document.get(), document_children[0].AsInput()).get(), section.Receive()); | |
188 ASSERT_EQ(S_OK, hr); | |
189 std::vector<base::win::ScopedVariant> section_children = | |
190 GetAllAccessibleChildren(section.get()); | |
191 ASSERT_EQ(1, section_children.size()); | |
192 | |
193 // Find the textarea text field. | |
194 base::win::ScopedComPtr<IAccessible2> textarea; | |
195 hr = QueryIAccessible2(GetAccessibleFromVariant( | |
196 section.get(), section_children[0].AsInput()).get(), textarea.Receive()); | |
197 ASSERT_EQ(S_OK, hr); | |
198 LONG textarea_role = 0; | |
199 hr = textarea->role(&textarea_role); | |
200 ASSERT_EQ(S_OK, hr); | |
201 ASSERT_EQ(ROLE_SYSTEM_TEXT, textarea_role); | |
202 | |
203 // Retrieve the IAccessibleText interface for the field. | |
204 hr = textarea.QueryInterface(textarea_text->Receive()); | |
205 ASSERT_EQ(S_OK, hr); | |
206 | |
207 // Set the caret on the last character. | |
208 AccessibilityNotificationWaiter waiter( | |
209 shell(), AccessibilityModeComplete, | |
210 ui::AX_EVENT_TEXT_SELECTION_CHANGED); | |
211 std::wstring caret_offset = base::UTF16ToWide(base::IntToString16( | |
212 static_cast<int>(CONTENTS_LENGTH - 1))); | |
213 ExecuteScript(std::wstring( | |
214 L"var textField = document.getElementById('textField');" | |
215 L"textField.focus();" | |
216 L"textField.setSelectionRange(") + | |
217 caret_offset + L"," + caret_offset + L");"); | |
218 waiter.WaitForNotification(); | |
219 } | |
220 | |
221 | |
222 // Static helpers ------------------------------------------------ | |
223 | |
224 base::win::ScopedComPtr<IAccessible> | |
225 AccessibilityWinBrowserTest::GetAccessibleFromVariant( | |
37 IAccessible* parent, | 226 IAccessible* parent, |
38 VARIANT* var) { | 227 VARIANT* var) { |
39 base::win::ScopedComPtr<IAccessible> ptr; | 228 base::win::ScopedComPtr<IAccessible> ptr; |
40 switch (V_VT(var)) { | 229 switch (V_VT(var)) { |
41 case VT_DISPATCH: { | 230 case VT_DISPATCH: { |
42 IDispatch* dispatch = V_DISPATCH(var); | 231 IDispatch* dispatch = V_DISPATCH(var); |
43 if (dispatch) | 232 if (dispatch) |
44 ptr.QueryFrom(dispatch); | 233 dispatch->QueryInterface(ptr.Receive()); |
45 break; | 234 break; |
46 } | 235 } |
47 | 236 |
48 case VT_I4: { | 237 case VT_I4: { |
49 base::win::ScopedComPtr<IDispatch> dispatch; | 238 base::win::ScopedComPtr<IDispatch> dispatch; |
50 HRESULT hr = parent->get_accChild(*var, dispatch.Receive()); | 239 HRESULT hr = parent->get_accChild(*var, dispatch.Receive()); |
51 EXPECT_TRUE(SUCCEEDED(hr)); | 240 EXPECT_TRUE(SUCCEEDED(hr)); |
52 if (dispatch.get()) | 241 if (dispatch.get()) |
53 dispatch.QueryInterface(ptr.Receive()); | 242 dispatch.QueryInterface(ptr.Receive()); |
54 break; | 243 break; |
55 } | 244 } |
56 } | 245 } |
57 return ptr; | 246 return ptr; |
58 } | 247 } |
59 | 248 |
60 HRESULT QueryIAccessible2(IAccessible* accessible, IAccessible2** accessible2) { | 249 HRESULT AccessibilityWinBrowserTest::QueryIAccessible2( |
61 // TODO(ctguil): For some reason querying the IAccessible2 interface from | 250 IAccessible* accessible, |
62 // IAccessible fails. | 251 IAccessible2** accessible2) { |
252 // IA2 Spec dictates that IServiceProvider should be used instead of | |
253 // QueryInterface when retrieving IAccessible2. | |
63 base::win::ScopedComPtr<IServiceProvider> service_provider; | 254 base::win::ScopedComPtr<IServiceProvider> service_provider; |
64 HRESULT hr = accessible->QueryInterface(service_provider.Receive()); | 255 HRESULT hr = accessible->QueryInterface(service_provider.Receive()); |
65 return SUCCEEDED(hr) ? | 256 return SUCCEEDED(hr) ? |
66 service_provider->QueryService(IID_IAccessible2, accessible2) : hr; | 257 service_provider->QueryService(IID_IAccessible2, accessible2) : hr; |
67 } | 258 } |
68 | 259 |
69 // Recursively search through all of the descendants reachable from an | 260 // Recursively search through all of the descendants reachable from an |
70 // IAccessible node and return true if we find one with the given role | 261 // IAccessible node and return true if we find one with the given role |
71 // and name. | 262 // and name. |
72 void RecursiveFindNodeInAccessibilityTree(IAccessible* node, | 263 void AccessibilityWinBrowserTest::FindNodeInAccessibilityTree( |
73 int32 expected_role, | 264 IAccessible* node, |
74 const std::wstring& expected_name, | 265 int32 expected_role, |
75 int32 depth, | 266 const std::wstring& expected_name, |
76 bool* found) { | 267 int32 depth, |
268 bool* found) { | |
77 base::win::ScopedBstr name_bstr; | 269 base::win::ScopedBstr name_bstr; |
78 base::win::ScopedVariant childid_self(CHILDID_SELF); | 270 base::win::ScopedVariant childid_self(CHILDID_SELF); |
79 node->get_accName(childid_self, name_bstr.Receive()); | 271 node->get_accName(childid_self, name_bstr.Receive()); |
80 std::wstring name(name_bstr, name_bstr.Length()); | 272 std::wstring name(name_bstr, name_bstr.Length()); |
81 base::win::ScopedVariant role; | 273 base::win::ScopedVariant role; |
82 node->get_accRole(childid_self, role.Receive()); | 274 node->get_accRole(childid_self, role.Receive()); |
83 ASSERT_EQ(VT_I4, role.type()); | 275 ASSERT_EQ(VT_I4, role.type()); |
84 | 276 |
85 // Print the accessibility tree as we go, because if this test fails | 277 // Print the accessibility tree as we go, because if this test fails |
86 // on the bots, this is really helpful in figuring out why. | 278 // on the bots, this is really helpful in figuring out why. |
87 for (int i = 0; i < depth; i++) | 279 for (int i = 0; i < depth; i++) |
88 printf(" "); | 280 printf(" "); |
89 printf("role=%s name=%s\n", | 281 printf("role=%s name=%s\n", |
90 base::WideToUTF8(IAccessibleRoleToString(V_I4(&role))).c_str(), | 282 base::WideToUTF8(IAccessibleRoleToString(V_I4(&role))).c_str(), |
91 base::WideToUTF8(name).c_str()); | 283 base::WideToUTF8(name).c_str()); |
92 | 284 |
93 if (expected_role == V_I4(&role) && expected_name == name) { | 285 if (expected_role == V_I4(&role) && expected_name == name) { |
94 *found = true; | 286 *found = true; |
95 return; | 287 return; |
96 } | 288 } |
97 | 289 |
98 LONG child_count = 0; | 290 std::vector<base::win::ScopedVariant> children = GetAllAccessibleChildren( |
99 HRESULT hr = node->get_accChildCount(&child_count); | 291 node); |
100 ASSERT_EQ(S_OK, hr); | 292 for (size_t i = 0; i < children.size(); ++i) { |
101 | |
102 scoped_ptr<VARIANT[]> child_array(new VARIANT[child_count]); | |
103 LONG obtained_count = 0; | |
104 hr = AccessibleChildren( | |
105 node, 0, child_count, child_array.get(), &obtained_count); | |
106 ASSERT_EQ(S_OK, hr); | |
107 ASSERT_EQ(child_count, obtained_count); | |
108 | |
109 for (int index = 0; index < obtained_count; index++) { | |
110 base::win::ScopedComPtr<IAccessible> child_accessible( | 293 base::win::ScopedComPtr<IAccessible> child_accessible( |
111 GetAccessibleFromResultVariant(node, &child_array.get()[index])); | 294 GetAccessibleFromVariant(node, children[i].AsInput())); |
112 if (child_accessible.get()) { | 295 if (child_accessible) { |
113 RecursiveFindNodeInAccessibilityTree( | 296 FindNodeInAccessibilityTree( |
114 child_accessible.get(), expected_role, expected_name, depth + 1, | 297 child_accessible.get(), expected_role, expected_name, depth + 1, |
115 found); | 298 found); |
116 if (*found) | 299 if (*found) |
117 return; | 300 return; |
118 } | 301 } |
119 } | 302 } |
120 } | 303 } |
121 | 304 |
305 // Ensures that the text and the start and end offsets retrieved using | |
306 // get_textAtOffset match the expected values. | |
307 void AccessibilityWinBrowserTest::CheckTextAtOffset( | |
308 base::win::ScopedComPtr<IAccessibleText>& element, | |
309 LONG offset, | |
310 IA2TextBoundaryType boundary_type, | |
311 LONG expected_start_offset, | |
312 LONG expected_end_offset, | |
313 const std::wstring& expected_text) { | |
314 testing::Message message; | |
315 message << "While checking for \'" << expected_text << "\' at " << | |
316 expected_start_offset << '-' << expected_end_offset << '.'; | |
317 SCOPED_TRACE(message); | |
122 | 318 |
123 // AccessibilityWinBrowserTest ------------------------------------------------ | 319 LONG start_offset = 0; |
124 | 320 LONG end_offset = 0; |
125 class AccessibilityWinBrowserTest : public ContentBrowserTest { | 321 base::win::ScopedBstr text; |
126 public: | 322 HRESULT hr = element->get_textAtOffset( |
127 AccessibilityWinBrowserTest(); | 323 offset, boundary_type, |
128 virtual ~AccessibilityWinBrowserTest(); | 324 &start_offset, &end_offset, text.Receive()); |
129 | 325 EXPECT_EQ(S_OK, hr); |
130 protected: | 326 EXPECT_EQ(expected_start_offset, start_offset); |
131 void LoadInitialAccessibilityTreeFromHtml(const std::string& html); | 327 EXPECT_EQ(expected_end_offset, end_offset); |
132 IAccessible* GetRendererAccessible(); | 328 EXPECT_EQ(expected_text, std::wstring(text, text.Length())); |
133 void ExecuteScript(const std::wstring& script); | |
134 | |
135 private: | |
136 DISALLOW_COPY_AND_ASSIGN(AccessibilityWinBrowserTest); | |
137 }; | |
138 | |
139 AccessibilityWinBrowserTest::AccessibilityWinBrowserTest() { | |
140 } | 329 } |
141 | 330 |
142 AccessibilityWinBrowserTest::~AccessibilityWinBrowserTest() { | 331 std::vector<base::win::ScopedVariant> |
143 } | 332 AccessibilityWinBrowserTest::GetAllAccessibleChildren( |
333 IAccessible* element) { | |
334 LONG child_count = 0; | |
335 HRESULT hr = element->get_accChildCount(&child_count); | |
336 EXPECT_EQ(S_OK, hr); | |
337 if (child_count <= 0) | |
338 return std::vector<base::win::ScopedVariant>(); | |
144 | 339 |
145 void AccessibilityWinBrowserTest::LoadInitialAccessibilityTreeFromHtml( | 340 scoped_ptr<VARIANT[]> children_array(new VARIANT[child_count]); |
146 const std::string& html) { | 341 LONG obtained_count = 0; |
147 AccessibilityNotificationWaiter waiter( | 342 hr = AccessibleChildren( |
148 shell(), AccessibilityModeComplete, | 343 element, 0, child_count, children_array.get(), &obtained_count); |
149 ui::AX_EVENT_LOAD_COMPLETE); | 344 EXPECT_EQ(S_OK, hr); |
150 GURL html_data_url("data:text/html," + html); | 345 EXPECT_EQ(child_count, obtained_count); |
151 NavigateToURL(shell(), html_data_url); | |
152 waiter.WaitForNotification(); | |
153 } | |
154 | 346 |
155 // Retrieve the MSAA client accessibility object for the Render Widget Host View | 347 std::vector<base::win::ScopedVariant> children( |
156 // of the selected tab. | 348 static_cast<size_t>(child_count)); |
157 IAccessible* AccessibilityWinBrowserTest::GetRendererAccessible() { | 349 for (size_t i = 0; i < children.size(); i++) { |
158 content::WebContents* web_contents = shell()->web_contents(); | 350 children[i].Reset(children_array[i]); |
159 return web_contents->GetRenderWidgetHostView()->GetNativeViewAccessible(); | 351 } |
160 } | 352 return children; |
161 | |
162 void AccessibilityWinBrowserTest::ExecuteScript(const std::wstring& script) { | |
163 shell()->web_contents()->GetMainFrame()->ExecuteJavaScript(script); | |
164 } | 353 } |
165 | 354 |
166 | 355 |
167 // AccessibleChecker ---------------------------------------------------------- | 356 // AccessibleChecker ---------------------------------------------------------- |
168 | 357 |
169 class AccessibleChecker { | 358 class AccessibilityWinBrowserTest::AccessibleChecker { |
170 public: | 359 public: |
171 // This constructor can be used if the IA2 role will be the same as the MSAA | 360 // This constructor can be used if the IA2 role will be the same as the MSAA |
172 // role. | 361 // role. |
173 AccessibleChecker(const std::wstring& expected_name, | 362 AccessibleChecker(const std::wstring& expected_name, |
174 int32 expected_role, | 363 int32 expected_role, |
175 const std::wstring& expected_value); | 364 const std::wstring& expected_value); |
176 AccessibleChecker(const std::wstring& expected_name, | 365 AccessibleChecker(const std::wstring& expected_name, |
177 int32 expected_role, | 366 int32 expected_role, |
178 int32 expected_ia2_role, | 367 int32 expected_ia2_role, |
179 const std::wstring& expected_value); | 368 const std::wstring& expected_value); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
221 std::wstring value_; | 410 std::wstring value_; |
222 | 411 |
223 // Expected accessible state. Checked against IAccessible::get_accState. | 412 // Expected accessible state. Checked against IAccessible::get_accState. |
224 LONG state_; | 413 LONG state_; |
225 | 414 |
226 // Expected accessible children. Checked using IAccessible::get_accChildCount | 415 // Expected accessible children. Checked using IAccessible::get_accChildCount |
227 // and ::AccessibleChildren. | 416 // and ::AccessibleChildren. |
228 AccessibleCheckerVector children_; | 417 AccessibleCheckerVector children_; |
229 }; | 418 }; |
230 | 419 |
231 AccessibleChecker::AccessibleChecker(const std::wstring& expected_name, | 420 AccessibilityWinBrowserTest::AccessibleChecker::AccessibleChecker( |
232 int32 expected_role, | 421 const std::wstring& expected_name, |
233 const std::wstring& expected_value) | 422 int32 expected_role, |
423 const std::wstring& expected_value) | |
234 : name_(expected_name), | 424 : name_(expected_name), |
235 role_(expected_role), | 425 role_(expected_role), |
236 ia2_role_(expected_role), | 426 ia2_role_(expected_role), |
237 value_(expected_value), | 427 value_(expected_value), |
238 state_(-1) { | 428 state_(-1) { |
239 } | 429 } |
240 | 430 |
241 AccessibleChecker::AccessibleChecker(const std::wstring& expected_name, | 431 AccessibilityWinBrowserTest::AccessibleChecker::AccessibleChecker( |
242 int32 expected_role, | 432 const std::wstring& expected_name, |
243 int32 expected_ia2_role, | 433 int32 expected_role, |
244 const std::wstring& expected_value) | 434 int32 expected_ia2_role, |
435 const std::wstring& expected_value) | |
245 : name_(expected_name), | 436 : name_(expected_name), |
246 role_(expected_role), | 437 role_(expected_role), |
247 ia2_role_(expected_ia2_role), | 438 ia2_role_(expected_ia2_role), |
248 value_(expected_value), | 439 value_(expected_value), |
249 state_(-1) { | 440 state_(-1) { |
250 } | 441 } |
251 | 442 |
252 AccessibleChecker::AccessibleChecker(const std::wstring& expected_name, | 443 AccessibilityWinBrowserTest::AccessibleChecker::AccessibleChecker( |
253 const std::wstring& expected_role, | 444 const std::wstring& expected_name, |
254 int32 expected_ia2_role, | 445 const std::wstring& expected_role, |
255 const std::wstring& expected_value) | 446 int32 expected_ia2_role, |
447 const std::wstring& expected_value) | |
256 : name_(expected_name), | 448 : name_(expected_name), |
257 role_(expected_role.c_str()), | 449 role_(expected_role.c_str()), |
258 ia2_role_(expected_ia2_role), | 450 ia2_role_(expected_ia2_role), |
259 value_(expected_value), | 451 value_(expected_value), |
260 state_(-1) { | 452 state_(-1) { |
261 } | 453 } |
262 | 454 |
263 void AccessibleChecker::AppendExpectedChild( | 455 void AccessibilityWinBrowserTest::AccessibleChecker::AppendExpectedChild( |
264 AccessibleChecker* expected_child) { | 456 AccessibleChecker* expected_child) { |
265 children_.push_back(expected_child); | 457 children_.push_back(expected_child); |
266 } | 458 } |
267 | 459 |
268 void AccessibleChecker::CheckAccessible(IAccessible* accessible) { | 460 void AccessibilityWinBrowserTest::AccessibleChecker::CheckAccessible( |
269 SCOPED_TRACE("while checking " + | 461 IAccessible* accessible) { |
270 base::UTF16ToUTF8(RoleVariantToString(role_))); | 462 SCOPED_TRACE("While checking " |
463 + base::UTF16ToUTF8(RoleVariantToString(role_))); | |
271 CheckAccessibleName(accessible); | 464 CheckAccessibleName(accessible); |
272 CheckAccessibleRole(accessible); | 465 CheckAccessibleRole(accessible); |
273 CheckIA2Role(accessible); | 466 CheckIA2Role(accessible); |
274 CheckAccessibleValue(accessible); | 467 CheckAccessibleValue(accessible); |
275 CheckAccessibleState(accessible); | 468 CheckAccessibleState(accessible); |
276 CheckAccessibleChildren(accessible); | 469 CheckAccessibleChildren(accessible); |
277 } | 470 } |
278 | 471 |
279 void AccessibleChecker::SetExpectedValue(const std::wstring& expected_value) { | 472 void AccessibilityWinBrowserTest::AccessibleChecker::SetExpectedValue( |
473 const std::wstring& expected_value) { | |
280 value_ = expected_value; | 474 value_ = expected_value; |
281 } | 475 } |
282 | 476 |
283 void AccessibleChecker::SetExpectedState(LONG expected_state) { | 477 void AccessibilityWinBrowserTest::AccessibleChecker::SetExpectedState( |
478 LONG expected_state) { | |
284 state_ = expected_state; | 479 state_ = expected_state; |
285 } | 480 } |
286 | 481 |
287 void AccessibleChecker::CheckAccessibleName(IAccessible* accessible) { | 482 void AccessibilityWinBrowserTest::AccessibleChecker::CheckAccessibleName( |
483 IAccessible* accessible) { | |
288 base::win::ScopedBstr name; | 484 base::win::ScopedBstr name; |
289 base::win::ScopedVariant childid_self(CHILDID_SELF); | 485 base::win::ScopedVariant childid_self(CHILDID_SELF); |
290 HRESULT hr = accessible->get_accName(childid_self, name.Receive()); | 486 HRESULT hr = accessible->get_accName(childid_self, name.Receive()); |
291 | 487 |
292 if (name_.empty()) { | 488 if (name_.empty()) { |
293 // If the object doesn't have name S_FALSE should be returned. | 489 // If the object doesn't have name S_FALSE should be returned. |
294 EXPECT_EQ(S_FALSE, hr); | 490 EXPECT_EQ(S_FALSE, hr); |
295 } else { | 491 } else { |
296 // Test that the correct string was returned. | 492 // Test that the correct string was returned. |
297 EXPECT_EQ(S_OK, hr); | 493 EXPECT_EQ(S_OK, hr); |
298 EXPECT_EQ(name_, std::wstring(name, name.Length())); | 494 EXPECT_EQ(name_, std::wstring(name, name.Length())); |
299 } | 495 } |
300 } | 496 } |
301 | 497 |
302 void AccessibleChecker::CheckAccessibleRole(IAccessible* accessible) { | 498 void AccessibilityWinBrowserTest::AccessibleChecker::CheckAccessibleRole( |
499 IAccessible* accessible) { | |
303 base::win::ScopedVariant role; | 500 base::win::ScopedVariant role; |
304 base::win::ScopedVariant childid_self(CHILDID_SELF); | 501 base::win::ScopedVariant childid_self(CHILDID_SELF); |
305 HRESULT hr = accessible->get_accRole(childid_self, role.Receive()); | 502 HRESULT hr = accessible->get_accRole(childid_self, role.Receive()); |
306 ASSERT_EQ(S_OK, hr); | 503 ASSERT_EQ(S_OK, hr); |
307 EXPECT_EQ(0, role_.Compare(role)) | 504 EXPECT_EQ(0, role_.Compare(role)) |
308 << "Expected role: " << RoleVariantToString(role_) | 505 << "Expected role: " << RoleVariantToString(role_) |
309 << "\nGot role: " << RoleVariantToString(role); | 506 << "\nGot role: " << RoleVariantToString(role); |
310 } | 507 } |
311 | 508 |
312 void AccessibleChecker::CheckIA2Role(IAccessible* accessible) { | 509 void AccessibilityWinBrowserTest::AccessibleChecker::CheckIA2Role( |
510 IAccessible* accessible) { | |
313 base::win::ScopedComPtr<IAccessible2> accessible2; | 511 base::win::ScopedComPtr<IAccessible2> accessible2; |
314 HRESULT hr = QueryIAccessible2(accessible, accessible2.Receive()); | 512 HRESULT hr = QueryIAccessible2(accessible, accessible2.Receive()); |
315 ASSERT_EQ(S_OK, hr); | 513 ASSERT_EQ(S_OK, hr); |
316 long ia2_role = 0; | 514 long ia2_role = 0; |
317 hr = accessible2->role(&ia2_role); | 515 hr = accessible2->role(&ia2_role); |
318 ASSERT_EQ(S_OK, hr); | 516 ASSERT_EQ(S_OK, hr); |
319 EXPECT_EQ(ia2_role_, ia2_role) | 517 EXPECT_EQ(ia2_role_, ia2_role) |
320 << "Expected ia2 role: " << IAccessible2RoleToString(ia2_role_) | 518 << "Expected ia2 role: " << IAccessible2RoleToString(ia2_role_) |
321 << "\nGot ia2 role: " << IAccessible2RoleToString(ia2_role); | 519 << "\nGot ia2 role: " << IAccessible2RoleToString(ia2_role); |
322 } | 520 } |
323 | 521 |
324 void AccessibleChecker::CheckAccessibleValue(IAccessible* accessible) { | 522 void AccessibilityWinBrowserTest::AccessibleChecker::CheckAccessibleValue( |
523 IAccessible* accessible) { | |
325 // Don't check the value if if's a DOCUMENT role, because the value | 524 // Don't check the value if if's a DOCUMENT role, because the value |
326 // is supposed to be the url (and we don't keep track of that in the | 525 // is supposed to be the url (and we don't keep track of that in the |
327 // test expectations). | 526 // test expectations). |
328 base::win::ScopedVariant role; | 527 base::win::ScopedVariant role; |
329 base::win::ScopedVariant childid_self(CHILDID_SELF); | 528 base::win::ScopedVariant childid_self(CHILDID_SELF); |
330 HRESULT hr = accessible->get_accRole(childid_self, role.Receive()); | 529 HRESULT hr = accessible->get_accRole(childid_self, role.Receive()); |
331 ASSERT_EQ(S_OK, hr); | 530 ASSERT_EQ(S_OK, hr); |
332 if (role.type() == VT_I4 && V_I4(&role) == ROLE_SYSTEM_DOCUMENT) | 531 if (role.type() == VT_I4 && V_I4(&role) == ROLE_SYSTEM_DOCUMENT) |
333 return; | 532 return; |
334 | 533 |
335 // Get the value. | 534 // Get the value. |
336 base::win::ScopedBstr value; | 535 base::win::ScopedBstr value; |
337 hr = accessible->get_accValue(childid_self, value.Receive()); | 536 hr = accessible->get_accValue(childid_self, value.Receive()); |
338 EXPECT_EQ(S_OK, hr); | 537 EXPECT_EQ(S_OK, hr); |
339 | 538 |
340 // Test that the correct string was returned. | 539 // Test that the correct string was returned. |
341 EXPECT_EQ(value_, std::wstring(value, value.Length())); | 540 EXPECT_EQ(value_, std::wstring(value, value.Length())); |
342 } | 541 } |
343 | 542 |
344 void AccessibleChecker::CheckAccessibleState(IAccessible* accessible) { | 543 void AccessibilityWinBrowserTest::AccessibleChecker::CheckAccessibleState( |
544 IAccessible* accessible) { | |
345 if (state_ < 0) | 545 if (state_ < 0) |
346 return; | 546 return; |
347 | 547 |
348 base::win::ScopedVariant state; | 548 base::win::ScopedVariant state; |
349 base::win::ScopedVariant childid_self(CHILDID_SELF); | 549 base::win::ScopedVariant childid_self(CHILDID_SELF); |
350 HRESULT hr = accessible->get_accState(childid_self, state.Receive()); | 550 HRESULT hr = accessible->get_accState(childid_self, state.Receive()); |
351 EXPECT_EQ(S_OK, hr); | 551 EXPECT_EQ(S_OK, hr); |
352 ASSERT_EQ(VT_I4, state.type()); | 552 ASSERT_EQ(VT_I4, state.type()); |
353 LONG obj_state = V_I4(&state); | 553 LONG obj_state = V_I4(&state); |
354 // Avoid flakiness. The "offscreen" state depends on whether the browser | 554 // Avoid flakiness. The "offscreen" state depends on whether the browser |
355 // window is frontmost or not, and "hottracked" depends on whether the | 555 // window is frontmost or not, and "hottracked" depends on whether the |
356 // mouse cursor happens to be over the element. | 556 // mouse cursor happens to be over the element. |
357 obj_state &= ~(STATE_SYSTEM_OFFSCREEN | STATE_SYSTEM_HOTTRACKED); | 557 obj_state &= ~(STATE_SYSTEM_OFFSCREEN | STATE_SYSTEM_HOTTRACKED); |
358 EXPECT_EQ(state_, obj_state) | 558 EXPECT_EQ(state_, obj_state) |
359 << "Expected state: " << IAccessibleStateToString(state_) | 559 << "Expected state: " << IAccessibleStateToString(state_) |
360 << "\nGot state: " << IAccessibleStateToString(obj_state); | 560 << "\nGot state: " << IAccessibleStateToString(obj_state); |
361 } | 561 } |
362 | 562 |
363 void AccessibleChecker::CheckAccessibleChildren(IAccessible* parent) { | 563 void AccessibilityWinBrowserTest::AccessibleChecker::CheckAccessibleChildren( |
364 LONG child_count = 0; | 564 IAccessible* parent) { |
365 HRESULT hr = parent->get_accChildCount(&child_count); | 565 std::vector<base::win::ScopedVariant> obtained_children = |
366 EXPECT_EQ(S_OK, hr); | 566 GetAllAccessibleChildren(parent); |
567 size_t child_count = obtained_children.size(); | |
367 ASSERT_EQ(child_count, children_.size()); | 568 ASSERT_EQ(child_count, children_.size()); |
368 | 569 |
369 scoped_ptr<VARIANT[]> child_array(new VARIANT[child_count]); | 570 AccessibleCheckerVector::iterator child_checker; |
370 LONG obtained_count = 0; | 571 std::vector<base::win::ScopedVariant>::iterator child; |
371 hr = AccessibleChildren(parent, 0, child_count, | 572 for (child_checker = children_.begin(), |
372 child_array.get(), &obtained_count); | 573 child = obtained_children.begin(); |
373 ASSERT_EQ(S_OK, hr); | 574 child_checker != children_.end() |
374 ASSERT_EQ(child_count, obtained_count); | 575 && child != obtained_children.end(); |
375 | |
376 VARIANT* child = child_array.get(); | |
377 for (AccessibleCheckerVector::iterator child_checker = children_.begin(); | |
378 child_checker != children_.end(); | |
379 ++child_checker, ++child) { | 576 ++child_checker, ++child) { |
380 base::win::ScopedComPtr<IAccessible> child_accessible( | 577 base::win::ScopedComPtr<IAccessible> child_accessible( |
381 GetAccessibleFromResultVariant(parent, child)); | 578 GetAccessibleFromVariant(parent, child->AsInput())); |
382 ASSERT_TRUE(child_accessible.get()); | 579 ASSERT_TRUE(child_accessible.get()); |
383 (*child_checker)->CheckAccessible(child_accessible.get()); | 580 (*child_checker)->CheckAccessible(child_accessible.get()); |
384 } | 581 } |
385 } | 582 } |
386 | 583 |
387 base::string16 AccessibleChecker::RoleVariantToString( | 584 base::string16 |
585 AccessibilityWinBrowserTest::AccessibleChecker::RoleVariantToString( | |
388 const base::win::ScopedVariant& role) { | 586 const base::win::ScopedVariant& role) { |
389 if (role.type() == VT_I4) | 587 if (role.type() == VT_I4) |
390 return IAccessibleRoleToString(V_I4(&role)); | 588 return IAccessibleRoleToString(V_I4(&role)); |
391 if (role.type() == VT_BSTR) | 589 if (role.type() == VT_BSTR) |
392 return base::string16(V_BSTR(&role), SysStringLen(V_BSTR(&role))); | 590 return base::string16(V_BSTR(&role), SysStringLen(V_BSTR(&role))); |
393 return base::string16(); | 591 return base::string16(); |
394 } | 592 } |
395 | 593 |
396 } // namespace | 594 } // namespace |
397 | 595 |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
660 CHECK(hwnd); | 858 CHECK(hwnd); |
661 base::win::ScopedComPtr<IAccessible> browser_accessible; | 859 base::win::ScopedComPtr<IAccessible> browser_accessible; |
662 HRESULT hr = AccessibleObjectFromWindow( | 860 HRESULT hr = AccessibleObjectFromWindow( |
663 hwnd, | 861 hwnd, |
664 OBJID_WINDOW, | 862 OBJID_WINDOW, |
665 IID_IAccessible, | 863 IID_IAccessible, |
666 reinterpret_cast<void**>(browser_accessible.Receive())); | 864 reinterpret_cast<void**>(browser_accessible.Receive())); |
667 ASSERT_EQ(S_OK, hr); | 865 ASSERT_EQ(S_OK, hr); |
668 | 866 |
669 bool found = false; | 867 bool found = false; |
670 RecursiveFindNodeInAccessibilityTree( | 868 FindNodeInAccessibilityTree( |
671 browser_accessible.get(), ROLE_SYSTEM_DOCUMENT, L"MyDocument", 0, &found); | 869 browser_accessible.get(), ROLE_SYSTEM_DOCUMENT, L"MyDocument", 0, &found); |
672 ASSERT_EQ(found, true); | 870 ASSERT_EQ(found, true); |
673 } | 871 } |
674 | 872 |
675 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, | 873 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, |
676 SupportsISimpleDOM) { | 874 SupportsISimpleDOM) { |
677 LoadInitialAccessibilityTreeFromHtml( | 875 LoadInitialAccessibilityTreeFromHtml( |
678 "<body><input type='checkbox' /></body>"); | 876 "<body><input type='checkbox' /></body>"); |
679 | 877 |
680 // Get the IAccessible object for the document. | 878 // Get the IAccessible object for the document. |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
747 std::wstring()); | 945 std::wstring()); |
748 AccessibleChecker grouping2_checker(std::wstring(), ROLE_SYSTEM_GROUPING, | 946 AccessibleChecker grouping2_checker(std::wstring(), ROLE_SYSTEM_GROUPING, |
749 std::wstring()); | 947 std::wstring()); |
750 AccessibleChecker document_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT, | 948 AccessibleChecker document_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT, |
751 std::wstring()); | 949 std::wstring()); |
752 document_checker.AppendExpectedChild(&grouping1_checker); | 950 document_checker.AppendExpectedChild(&grouping1_checker); |
753 document_checker.AppendExpectedChild(&grouping2_checker); | 951 document_checker.AppendExpectedChild(&grouping2_checker); |
754 document_checker.CheckAccessible(GetRendererAccessible()); | 952 document_checker.CheckAccessible(GetRendererAccessible()); |
755 } | 953 } |
756 | 954 |
955 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, | |
956 TestSetCaretOffset) { | |
957 base::win::ScopedComPtr<IAccessibleText> input_text; | |
958 SetUpInputField(&input_text); | |
959 | |
960 LONG caret_offset = 0; | |
961 HRESULT hr = input_text->get_caretOffset(&caret_offset); | |
962 EXPECT_EQ(S_OK, hr); | |
963 EXPECT_EQ(CONTENTS_LENGTH - 1, caret_offset); | |
964 | |
965 AccessibilityNotificationWaiter waiter( | |
966 shell(), AccessibilityModeComplete, | |
967 ui::AX_EVENT_TEXT_SELECTION_CHANGED); | |
968 caret_offset = 0; | |
969 hr = input_text->setCaretOffset(caret_offset); | |
970 EXPECT_EQ(S_OK, hr); | |
971 waiter.WaitForNotification(); | |
972 | |
973 hr = input_text->get_caretOffset(&caret_offset); | |
974 EXPECT_EQ(S_OK, hr); | |
975 EXPECT_EQ(0, caret_offset); | |
976 } | |
977 | |
978 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, | |
979 TestMultiLineSetCaretOffset) { | |
980 base::win::ScopedComPtr<IAccessibleText> textarea_text; | |
981 SetUpTextareaField(&textarea_text); | |
982 | |
983 LONG caret_offset = 0; | |
dmazzoni
2015/02/25 00:34:49
nit: indentation is wrong here, should be two spac
| |
984 HRESULT hr = textarea_text->get_caretOffset(&caret_offset); | |
985 EXPECT_EQ(S_OK, hr); | |
986 EXPECT_EQ(CONTENTS_LENGTH - 1, caret_offset); | |
987 | |
988 AccessibilityNotificationWaiter waiter( | |
989 shell(), AccessibilityModeComplete, | |
990 ui::AX_EVENT_TEXT_SELECTION_CHANGED); | |
991 caret_offset = 0; | |
992 hr = textarea_text->setCaretOffset(caret_offset); | |
993 EXPECT_EQ(S_OK, hr); | |
994 waiter.WaitForNotification(); | |
995 | |
996 hr = textarea_text->get_caretOffset(&caret_offset); | |
997 EXPECT_EQ(S_OK, hr); | |
998 EXPECT_EQ(0, caret_offset); | |
999 } | |
1000 | |
1001 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, | |
1002 TestTextAtOffsetWithInvalidArgs) { | |
1003 base::win::ScopedComPtr<IAccessibleText> input_text; | |
1004 SetUpInputField(&input_text); | |
1005 HRESULT hr = input_text->get_textAtOffset( | |
1006 0, IA2_TEXT_BOUNDARY_CHAR, NULL, NULL, NULL); | |
1007 EXPECT_EQ(E_INVALIDARG, hr); | |
1008 | |
1009 // Test invalid offset. | |
1010 LONG start_offset = 0; | |
1011 LONG end_offset = 0; | |
1012 base::win::ScopedBstr text; | |
1013 LONG invalid_offset = -5; | |
1014 hr = input_text->get_textAtOffset( | |
1015 invalid_offset, IA2_TEXT_BOUNDARY_CHAR, | |
1016 &start_offset, &end_offset, text.Receive()); | |
1017 EXPECT_EQ(E_INVALIDARG, hr); | |
1018 EXPECT_EQ(0, start_offset); | |
1019 EXPECT_EQ(0, end_offset); | |
1020 EXPECT_EQ(nullptr, static_cast<BSTR>(text)); | |
1021 invalid_offset = CONTENTS_LENGTH + 1; | |
1022 hr = input_text->get_textAtOffset( | |
1023 invalid_offset, IA2_TEXT_BOUNDARY_WORD, | |
1024 &start_offset, &end_offset, text.Receive()); | |
1025 EXPECT_EQ(E_INVALIDARG, hr); | |
1026 EXPECT_EQ(0, start_offset); | |
1027 EXPECT_EQ(0, end_offset); | |
1028 EXPECT_EQ(nullptr, static_cast<BSTR>(text)); | |
1029 | |
1030 // According to the IA2 Spec, only line boundaries should succeed when | |
1031 // the offset is one past the end of the text. | |
1032 invalid_offset = CONTENTS_LENGTH; | |
1033 hr = input_text->get_textAtOffset( | |
1034 invalid_offset, IA2_TEXT_BOUNDARY_CHAR, | |
1035 &start_offset, &end_offset, text.Receive()); | |
1036 EXPECT_EQ(S_FALSE, hr); | |
1037 EXPECT_EQ(0, start_offset); | |
1038 EXPECT_EQ(0, end_offset); | |
1039 EXPECT_EQ(nullptr, static_cast<BSTR>(text)); | |
1040 hr = input_text->get_textAtOffset( | |
1041 invalid_offset, IA2_TEXT_BOUNDARY_WORD, | |
1042 &start_offset, &end_offset, text.Receive()); | |
1043 EXPECT_EQ(S_FALSE, hr); | |
1044 EXPECT_EQ(0, start_offset); | |
1045 EXPECT_EQ(0, end_offset); | |
1046 EXPECT_EQ(nullptr, static_cast<BSTR>(text)); | |
1047 hr = input_text->get_textAtOffset( | |
1048 invalid_offset, IA2_TEXT_BOUNDARY_SENTENCE, | |
1049 &start_offset, &end_offset, text.Receive()); | |
1050 EXPECT_EQ(S_FALSE, hr); | |
1051 EXPECT_EQ(0, start_offset); | |
1052 EXPECT_EQ(0, end_offset); | |
1053 EXPECT_EQ(nullptr, static_cast<BSTR>(text)); | |
1054 hr = input_text->get_textAtOffset( | |
1055 invalid_offset, IA2_TEXT_BOUNDARY_ALL, | |
1056 &start_offset, &end_offset, text.Receive()); | |
1057 EXPECT_EQ(S_FALSE, hr); | |
1058 EXPECT_EQ(0, start_offset); | |
1059 EXPECT_EQ(0, end_offset); | |
1060 EXPECT_EQ(nullptr, static_cast<BSTR>(text)); | |
1061 | |
1062 // The same behavior should be observed when the special offset | |
1063 // IA2_TEXT_OFFSET_LENGTH is used. | |
1064 hr = input_text->get_textAtOffset( | |
1065 IA2_TEXT_OFFSET_LENGTH, IA2_TEXT_BOUNDARY_CHAR, | |
1066 &start_offset, &end_offset, text.Receive()); | |
1067 EXPECT_EQ(S_FALSE, hr); | |
1068 EXPECT_EQ(0, start_offset); | |
1069 EXPECT_EQ(0, end_offset); | |
1070 EXPECT_EQ(nullptr, static_cast<BSTR>(text)); | |
1071 hr = input_text->get_textAtOffset( | |
1072 IA2_TEXT_OFFSET_LENGTH, IA2_TEXT_BOUNDARY_WORD, | |
1073 &start_offset, &end_offset, text.Receive()); | |
1074 EXPECT_EQ(S_FALSE, hr); | |
1075 EXPECT_EQ(0, start_offset); | |
1076 EXPECT_EQ(0, end_offset); | |
1077 EXPECT_EQ(nullptr, static_cast<BSTR>(text)); | |
1078 hr = input_text->get_textAtOffset( | |
1079 IA2_TEXT_OFFSET_LENGTH, IA2_TEXT_BOUNDARY_SENTENCE, | |
1080 &start_offset, &end_offset, text.Receive()); | |
1081 EXPECT_EQ(S_FALSE, hr); | |
1082 EXPECT_EQ(0, start_offset); | |
1083 EXPECT_EQ(0, end_offset); | |
1084 EXPECT_EQ(nullptr, static_cast<BSTR>(text)); | |
1085 hr = input_text->get_textAtOffset( | |
1086 IA2_TEXT_OFFSET_LENGTH, IA2_TEXT_BOUNDARY_ALL, | |
1087 &start_offset, &end_offset, text.Receive()); | |
1088 EXPECT_EQ(S_FALSE, hr); | |
1089 EXPECT_EQ(0, start_offset); | |
1090 EXPECT_EQ(0, end_offset); | |
1091 EXPECT_EQ(nullptr, static_cast<BSTR>(text)); | |
1092 } | |
1093 | |
1094 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, | |
1095 TestMultiLineTextAtOffsetWithInvalidArgs) { | |
1096 base::win::ScopedComPtr<IAccessibleText> textarea_text; | |
1097 SetUpTextareaField(&textarea_text); | |
1098 HRESULT hr = textarea_text->get_textAtOffset( | |
1099 0, IA2_TEXT_BOUNDARY_CHAR, NULL, NULL, NULL); | |
1100 EXPECT_EQ(E_INVALIDARG, hr); | |
1101 | |
1102 // Test invalid offset. | |
1103 LONG start_offset = 0; | |
1104 LONG end_offset = 0; | |
1105 base::win::ScopedBstr text; | |
1106 LONG invalid_offset = -5; | |
1107 hr = textarea_text->get_textAtOffset( | |
1108 invalid_offset, IA2_TEXT_BOUNDARY_CHAR, | |
1109 &start_offset, &end_offset, text.Receive()); | |
1110 EXPECT_EQ(E_INVALIDARG, hr); | |
1111 EXPECT_EQ(0, start_offset); | |
1112 EXPECT_EQ(0, end_offset); | |
1113 EXPECT_EQ(nullptr, static_cast<BSTR>(text)); | |
1114 invalid_offset = CONTENTS_LENGTH + 1; | |
1115 hr = textarea_text->get_textAtOffset( | |
1116 invalid_offset, IA2_TEXT_BOUNDARY_WORD, | |
1117 &start_offset, &end_offset, text.Receive()); | |
1118 EXPECT_EQ(E_INVALIDARG, hr); | |
1119 EXPECT_EQ(0, start_offset); | |
1120 EXPECT_EQ(0, end_offset); | |
1121 EXPECT_EQ(nullptr, static_cast<BSTR>(text)); | |
1122 | |
1123 // According to the IA2 Spec, only line boundaries should succeed when | |
1124 // the offset is one past the end of the text. | |
1125 invalid_offset = CONTENTS_LENGTH; | |
1126 hr = textarea_text->get_textAtOffset( | |
1127 invalid_offset, IA2_TEXT_BOUNDARY_CHAR, | |
1128 &start_offset, &end_offset, text.Receive()); | |
1129 EXPECT_EQ(S_FALSE, hr); | |
1130 EXPECT_EQ(0, start_offset); | |
1131 EXPECT_EQ(0, end_offset); | |
1132 EXPECT_EQ(nullptr, static_cast<BSTR>(text)); | |
1133 hr = textarea_text->get_textAtOffset( | |
1134 invalid_offset, IA2_TEXT_BOUNDARY_WORD, | |
1135 &start_offset, &end_offset, text.Receive()); | |
1136 EXPECT_EQ(S_FALSE, hr); | |
1137 EXPECT_EQ(0, start_offset); | |
1138 EXPECT_EQ(0, end_offset); | |
1139 EXPECT_EQ(nullptr, static_cast<BSTR>(text)); | |
1140 hr = textarea_text->get_textAtOffset( | |
1141 invalid_offset, IA2_TEXT_BOUNDARY_SENTENCE, | |
1142 &start_offset, &end_offset, text.Receive()); | |
1143 EXPECT_EQ(S_FALSE, hr); | |
1144 EXPECT_EQ(0, start_offset); | |
1145 EXPECT_EQ(0, end_offset); | |
1146 EXPECT_EQ(nullptr, static_cast<BSTR>(text)); | |
1147 hr = textarea_text->get_textAtOffset( | |
1148 invalid_offset, IA2_TEXT_BOUNDARY_ALL, | |
1149 &start_offset, &end_offset, text.Receive()); | |
1150 EXPECT_EQ(S_FALSE, hr); | |
1151 EXPECT_EQ(0, start_offset); | |
1152 EXPECT_EQ(0, end_offset); | |
1153 EXPECT_EQ(nullptr, static_cast<BSTR>(text)); | |
1154 | |
1155 // The same behavior should be observed when the special offset | |
1156 // IA2_TEXT_OFFSET_LENGTH is used. | |
1157 hr = textarea_text->get_textAtOffset( | |
1158 IA2_TEXT_OFFSET_LENGTH, IA2_TEXT_BOUNDARY_CHAR, | |
1159 &start_offset, &end_offset, text.Receive()); | |
1160 EXPECT_EQ(S_FALSE, hr); | |
1161 EXPECT_EQ(0, start_offset); | |
1162 EXPECT_EQ(0, end_offset); | |
1163 EXPECT_EQ(nullptr, static_cast<BSTR>(text)); | |
1164 hr = textarea_text->get_textAtOffset( | |
1165 IA2_TEXT_OFFSET_LENGTH, IA2_TEXT_BOUNDARY_WORD, | |
1166 &start_offset, &end_offset, text.Receive()); | |
1167 EXPECT_EQ(S_FALSE, hr); | |
1168 EXPECT_EQ(0, start_offset); | |
1169 EXPECT_EQ(0, end_offset); | |
1170 EXPECT_EQ(nullptr, static_cast<BSTR>(text)); | |
1171 hr = textarea_text->get_textAtOffset( | |
1172 IA2_TEXT_OFFSET_LENGTH, IA2_TEXT_BOUNDARY_SENTENCE, | |
1173 &start_offset, &end_offset, text.Receive()); | |
1174 EXPECT_EQ(S_FALSE, hr); | |
1175 EXPECT_EQ(0, start_offset); | |
1176 EXPECT_EQ(0, end_offset); | |
1177 EXPECT_EQ(nullptr, static_cast<BSTR>(text)); | |
1178 hr = textarea_text->get_textAtOffset( | |
1179 IA2_TEXT_OFFSET_LENGTH, IA2_TEXT_BOUNDARY_ALL, | |
1180 &start_offset, &end_offset, text.Receive()); | |
1181 EXPECT_EQ(S_FALSE, hr); | |
1182 EXPECT_EQ(0, start_offset); | |
1183 EXPECT_EQ(0, end_offset); | |
1184 EXPECT_EQ(nullptr, static_cast<BSTR>(text)); | |
1185 } | |
1186 | |
1187 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, | |
1188 TestTextAtOffsetWithBoundaryCharacter) { | |
1189 base::win::ScopedComPtr<IAccessibleText> input_text; | |
1190 SetUpInputField(&input_text); | |
1191 for (LONG offset = 0; offset < CONTENTS_LENGTH; ++offset) { | |
1192 std::wstring expected_text(1, INPUT_CONTENTS[offset]); | |
1193 LONG expected_start_offset = offset; | |
1194 LONG expected_end_offset = offset + 1; | |
1195 CheckTextAtOffset(input_text, offset, IA2_TEXT_BOUNDARY_CHAR, | |
1196 expected_start_offset, expected_end_offset, expected_text); | |
1197 } | |
1198 | |
1199 for (LONG offset = CONTENTS_LENGTH - 1; offset >= 0; --offset) { | |
1200 std::wstring expected_text(1, INPUT_CONTENTS[offset]); | |
1201 LONG expected_start_offset = offset; | |
1202 LONG expected_end_offset = offset + 1; | |
1203 CheckTextAtOffset(input_text, offset, IA2_TEXT_BOUNDARY_CHAR, | |
1204 expected_start_offset, expected_end_offset, expected_text); | |
1205 } | |
1206 | |
1207 CheckTextAtOffset(input_text, IA2_TEXT_OFFSET_CARET, | |
1208 IA2_TEXT_BOUNDARY_CHAR, CONTENTS_LENGTH - 1, CONTENTS_LENGTH, L"."); | |
1209 } | |
1210 | |
1211 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, | |
1212 DISABLED_TestMultiLineTextAtOffsetWithBoundaryCharacter) { | |
1213 base::win::ScopedComPtr<IAccessibleText> textarea_text; | |
1214 SetUpTextareaField(&textarea_text); | |
1215 for (LONG offset = 0; offset < CONTENTS_LENGTH; ++offset) { | |
1216 std::wstring expected_text(1, TEXTAREA_CONTENTS[offset]); | |
1217 LONG expected_start_offset = offset; | |
1218 LONG expected_end_offset = offset + 1; | |
1219 CheckTextAtOffset(textarea_text, offset, IA2_TEXT_BOUNDARY_CHAR, | |
1220 expected_start_offset, expected_end_offset, expected_text); | |
1221 } | |
1222 | |
1223 for (LONG offset = CONTENTS_LENGTH - 1; offset >= 0; --offset) { | |
1224 std::wstring expected_text(1, TEXTAREA_CONTENTS[offset]); | |
1225 LONG expected_start_offset = offset; | |
1226 LONG expected_end_offset = offset + 1; | |
1227 CheckTextAtOffset(textarea_text, offset, IA2_TEXT_BOUNDARY_CHAR, | |
1228 expected_start_offset, expected_end_offset, expected_text); | |
1229 } | |
1230 | |
1231 CheckTextAtOffset(textarea_text, IA2_TEXT_OFFSET_CARET, | |
1232 IA2_TEXT_BOUNDARY_CHAR, CONTENTS_LENGTH - 1, CONTENTS_LENGTH, L"."); | |
1233 } | |
1234 | |
1235 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, | |
1236 TestTextAtOffsetWithBoundaryWord) { | |
1237 base::win::ScopedComPtr<IAccessibleText> input_text; | |
1238 SetUpInputField(&input_text); | |
1239 | |
1240 // Trailing punctuation should be included as part of the previous word. | |
1241 CheckTextAtOffset(input_text, 0, IA2_TEXT_BOUNDARY_WORD, | |
1242 0, 4, L"Moz/"); | |
1243 CheckTextAtOffset(input_text, 2, IA2_TEXT_BOUNDARY_WORD, | |
1244 0, 4, L"Moz/"); | |
1245 | |
1246 // If the offset is at the punctuation, it should return | |
1247 // the previous word. | |
1248 CheckTextAtOffset(input_text, 3, IA2_TEXT_BOUNDARY_WORD, | |
1249 0, 4, L"Moz/"); | |
1250 | |
1251 // Numbers with a decimal point ("." for U.S), should be treated as one word. | |
1252 // Also, trailing punctuation that occurs after empty space should be part of | |
1253 // the word. ("5.0 (" and not "5.0 ".) | |
1254 CheckTextAtOffset(input_text, 4, IA2_TEXT_BOUNDARY_WORD, | |
1255 4, 9, L"5.0 ("); | |
1256 CheckTextAtOffset(input_text, 5, IA2_TEXT_BOUNDARY_WORD, | |
1257 4, 9, L"5.0 ("); | |
1258 CheckTextAtOffset(input_text, 6, IA2_TEXT_BOUNDARY_WORD, | |
1259 4, 9, L"5.0 ("); | |
1260 CheckTextAtOffset(input_text, 7, IA2_TEXT_BOUNDARY_WORD, | |
1261 4, 9, L"5.0 ("); | |
1262 | |
1263 // Leading punctuation should not be included with the word after it. | |
1264 CheckTextAtOffset(input_text, 8, IA2_TEXT_BOUNDARY_WORD, | |
1265 4, 9, L"5.0 ("); | |
1266 CheckTextAtOffset(input_text, 11, IA2_TEXT_BOUNDARY_WORD, | |
1267 9, 12, L"ST "); | |
1268 | |
1269 // Numbers separated from letters with trailing punctuation should | |
1270 // be split into two words. Same for abreviations like "i.e.". | |
1271 CheckTextAtOffset(input_text, 12, IA2_TEXT_BOUNDARY_WORD, | |
1272 12, 14, L"6."); | |
1273 CheckTextAtOffset(input_text, 15, IA2_TEXT_BOUNDARY_WORD, | |
1274 14, 17, L"x; "); | |
1275 | |
1276 // Words with numbers should be treated like ordinary words. | |
1277 CheckTextAtOffset(input_text, 17, IA2_TEXT_BOUNDARY_WORD, | |
1278 17, 24, L"WWW33) "); | |
1279 CheckTextAtOffset(input_text, 23, IA2_TEXT_BOUNDARY_WORD, | |
1280 17, 24, L"WWW33) "); | |
1281 | |
1282 // Multiple trailing empty spaces should be part of the word preceding it. | |
1283 CheckTextAtOffset(input_text, 28, IA2_TEXT_BOUNDARY_WORD, | |
1284 24, 33, L"WebKit \""); | |
1285 CheckTextAtOffset(input_text, 31, IA2_TEXT_BOUNDARY_WORD, | |
1286 24, 33, L"WebKit \""); | |
1287 CheckTextAtOffset(input_text, 32, IA2_TEXT_BOUNDARY_WORD, | |
1288 24, 33, L"WebKit \""); | |
1289 | |
1290 // Leading punctuation such as quotation marks should not be part of the word. | |
1291 CheckTextAtOffset(input_text, 33, IA2_TEXT_BOUNDARY_WORD, | |
1292 33, 40, L"KHTML, "); | |
1293 CheckTextAtOffset(input_text, 38, IA2_TEXT_BOUNDARY_WORD, | |
1294 33, 40, L"KHTML, "); | |
1295 | |
1296 // Trailing final punctuation should be part of the last word. | |
1297 CheckTextAtOffset(input_text, 41, IA2_TEXT_BOUNDARY_WORD, | |
1298 40, CONTENTS_LENGTH, L"like\"."); | |
1299 CheckTextAtOffset(input_text, 45, IA2_TEXT_BOUNDARY_WORD, | |
1300 40, CONTENTS_LENGTH, L"like\"."); | |
1301 | |
1302 // Test special offsets. | |
1303 CheckTextAtOffset(input_text, IA2_TEXT_OFFSET_CARET, | |
1304 IA2_TEXT_BOUNDARY_WORD, 40, CONTENTS_LENGTH, L"like\"."); | |
1305 } | |
1306 | |
1307 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, | |
1308 DISABLED_TestMultiLineTextAtOffsetWithBoundaryWord) { | |
1309 base::win::ScopedComPtr<IAccessibleText> textarea_text; | |
1310 SetUpTextareaField(&textarea_text); | |
1311 | |
1312 // Trailing punctuation should be included as part of the previous word. | |
1313 CheckTextAtOffset(textarea_text, 0, IA2_TEXT_BOUNDARY_WORD, | |
1314 0, 4, L"Moz/"); | |
1315 CheckTextAtOffset(textarea_text, 2, IA2_TEXT_BOUNDARY_WORD, | |
1316 0, 4, L"Moz/"); | |
1317 | |
1318 // If the offset is at the punctuation, it should return | |
1319 // the previous word. | |
1320 CheckTextAtOffset(textarea_text, 3, IA2_TEXT_BOUNDARY_WORD, | |
1321 0, 4, L"Moz/"); | |
1322 | |
1323 // Numbers with a decimal point ("." for U.S), should be treated as one word. | |
1324 // Also, trailing punctuation that occurs after empty space should be part of | |
1325 // the word. ("5.0 (" and not "5.0 ".) | |
1326 CheckTextAtOffset(textarea_text, 4, IA2_TEXT_BOUNDARY_WORD, | |
1327 4, 9, L"5.0 ("); | |
1328 CheckTextAtOffset(textarea_text, 5, IA2_TEXT_BOUNDARY_WORD, | |
1329 4, 9, L"5.0 ("); | |
1330 CheckTextAtOffset(textarea_text, 6, IA2_TEXT_BOUNDARY_WORD, | |
1331 4, 9, L"5.0 ("); | |
1332 CheckTextAtOffset(textarea_text, 7, IA2_TEXT_BOUNDARY_WORD, | |
1333 4, 9, L"5.0 ("); | |
1334 | |
1335 // Leading punctuation should not be included with the word after it. | |
1336 CheckTextAtOffset(textarea_text, 8, IA2_TEXT_BOUNDARY_WORD, | |
1337 4, 9, L"5.0 ("); | |
1338 CheckTextAtOffset(textarea_text, 11, IA2_TEXT_BOUNDARY_WORD, | |
1339 9, 12, L"ST "); | |
1340 | |
1341 // Numbers separated from letters with trailing punctuation should | |
1342 // be split into two words. Same for abreviations like "i.e.". | |
1343 CheckTextAtOffset(textarea_text, 12, IA2_TEXT_BOUNDARY_WORD, | |
1344 12, 14, L"6."); | |
1345 CheckTextAtOffset(textarea_text, 15, IA2_TEXT_BOUNDARY_WORD, | |
1346 14, 17, L"x; "); | |
1347 | |
1348 // Words with numbers should be treated like ordinary words. | |
1349 CheckTextAtOffset(textarea_text, 17, IA2_TEXT_BOUNDARY_WORD, | |
1350 17, 24, L"WWW33)\n"); | |
1351 CheckTextAtOffset(textarea_text, 23, IA2_TEXT_BOUNDARY_WORD, | |
1352 17, 24, L"WWW33)\n"); | |
1353 | |
1354 // Multiple trailing empty spaces should be part of the word preceding it. | |
1355 CheckTextAtOffset(textarea_text, 28, IA2_TEXT_BOUNDARY_WORD, | |
1356 24, 33, L"WebKit \n\""); | |
1357 CheckTextAtOffset(textarea_text, 31, IA2_TEXT_BOUNDARY_WORD, | |
1358 24, 33, L"WebKit \n\""); | |
1359 CheckTextAtOffset(textarea_text, 32, IA2_TEXT_BOUNDARY_WORD, | |
1360 24, 33, L"WebKit \n\""); | |
1361 | |
1362 // Leading punctuation such as quotation marks should not be part of the word. | |
1363 CheckTextAtOffset(textarea_text, 33, IA2_TEXT_BOUNDARY_WORD, | |
1364 33, 40, L"KHTML, "); | |
1365 CheckTextAtOffset(textarea_text, 38, IA2_TEXT_BOUNDARY_WORD, | |
1366 33, 40, L"KHTML, "); | |
1367 | |
1368 // Trailing final punctuation should be part of the last word. | |
1369 CheckTextAtOffset(textarea_text, 41, IA2_TEXT_BOUNDARY_WORD, | |
1370 40, CONTENTS_LENGTH, L"like\"."); | |
1371 CheckTextAtOffset(textarea_text, 45, IA2_TEXT_BOUNDARY_WORD, | |
1372 40, CONTENTS_LENGTH, L"like\"."); | |
1373 | |
1374 // Test special offsets. | |
1375 CheckTextAtOffset(textarea_text, IA2_TEXT_OFFSET_CARET, | |
1376 IA2_TEXT_BOUNDARY_WORD, 40, CONTENTS_LENGTH, L"like\"."); | |
1377 } | |
1378 | |
1379 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, | |
1380 TestTextAtOffsetWithBoundarySentence) { | |
1381 base::win::ScopedComPtr<IAccessibleText> input_text; | |
1382 SetUpInputField(&input_text); | |
1383 | |
1384 // Sentence navigation is not currently implemented. | |
1385 LONG start_offset = 0; | |
1386 LONG end_offset = 0; | |
1387 base::win::ScopedBstr text; | |
1388 HRESULT hr = input_text->get_textAtOffset( | |
1389 5, IA2_TEXT_BOUNDARY_SENTENCE, | |
1390 &start_offset, &end_offset, text.Receive()); | |
1391 EXPECT_EQ(S_FALSE, hr); | |
1392 } | |
1393 | |
1394 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, | |
1395 TestMultiLineTextAtOffsetWithBoundarySentence) { | |
1396 base::win::ScopedComPtr<IAccessibleText> textarea_text; | |
1397 SetUpTextareaField(&textarea_text); | |
1398 | |
1399 // Sentence navigation is not currently implemented. | |
1400 LONG start_offset = 0; | |
1401 LONG end_offset = 0; | |
1402 base::win::ScopedBstr text; | |
1403 HRESULT hr = textarea_text->get_textAtOffset( | |
1404 25, IA2_TEXT_BOUNDARY_SENTENCE, | |
1405 &start_offset, &end_offset, text.Receive()); | |
1406 EXPECT_EQ(S_FALSE, hr); | |
1407 } | |
1408 | |
1409 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, | |
1410 TestTextAtOffsetWithBoundaryLine) { | |
1411 base::win::ScopedComPtr<IAccessibleText> input_text; | |
1412 SetUpInputField(&input_text); | |
1413 | |
1414 // Single line text fields should return the whole text. | |
1415 CheckTextAtOffset(input_text, 0, IA2_TEXT_BOUNDARY_LINE, | |
1416 0, CONTENTS_LENGTH, base::SysUTF8ToWide(INPUT_CONTENTS)); | |
1417 | |
1418 // Test special offsets. | |
1419 CheckTextAtOffset(input_text, IA2_TEXT_OFFSET_LENGTH, IA2_TEXT_BOUNDARY_LINE, | |
1420 0, CONTENTS_LENGTH, base::SysUTF8ToWide(INPUT_CONTENTS)); | |
1421 CheckTextAtOffset(input_text, IA2_TEXT_OFFSET_CARET, IA2_TEXT_BOUNDARY_LINE, | |
1422 0, CONTENTS_LENGTH, base::SysUTF8ToWide(INPUT_CONTENTS)); | |
1423 } | |
1424 | |
1425 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, | |
1426 DISABLED_TestMultiLineTextAtOffsetWithBoundaryLine) { | |
1427 base::win::ScopedComPtr<IAccessibleText> textarea_text; | |
1428 SetUpTextareaField(&textarea_text); | |
1429 | |
1430 CheckTextAtOffset(textarea_text, 0, IA2_TEXT_BOUNDARY_LINE, | |
1431 0, 24, L"Moz/5.0 (ST 6.x; WWW33)\n"); | |
1432 | |
1433 // If the offset is at the newline, return the line preceding it. | |
1434 CheckTextAtOffset(textarea_text, 31, IA2_TEXT_BOUNDARY_LINE, | |
1435 24, 32, L"WebKit \n"); | |
1436 | |
1437 // Last line does not have a trailing newline. | |
1438 CheckTextAtOffset(textarea_text, 32, IA2_TEXT_BOUNDARY_LINE, | |
1439 32, CONTENTS_LENGTH, L"\"KHTML, like\"."); | |
1440 | |
1441 // An offset one past the last character should return the last line. | |
1442 CheckTextAtOffset(textarea_text, CONTENTS_LENGTH, IA2_TEXT_BOUNDARY_LINE, | |
1443 32, CONTENTS_LENGTH, L"\"KHTML, like\"."); | |
1444 | |
1445 // Test special offsets. | |
1446 CheckTextAtOffset(textarea_text, IA2_TEXT_OFFSET_LENGTH, | |
1447 IA2_TEXT_BOUNDARY_LINE, 32, CONTENTS_LENGTH, L"\"KHTML, like\"."); | |
1448 CheckTextAtOffset(textarea_text, IA2_TEXT_OFFSET_CARET, | |
1449 IA2_TEXT_BOUNDARY_LINE, 32, CONTENTS_LENGTH, L"\"KHTML, like\"."); | |
1450 } | |
1451 | |
1452 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, | |
1453 TestTextAtOffsetWithBoundaryAll) { | |
1454 base::win::ScopedComPtr<IAccessibleText> input_text; | |
1455 SetUpInputField(&input_text); | |
1456 | |
1457 CheckTextAtOffset(input_text, 0, IA2_TEXT_BOUNDARY_ALL, | |
1458 0, CONTENTS_LENGTH, base::SysUTF8ToWide(INPUT_CONTENTS)); | |
1459 } | |
1460 | |
1461 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, | |
1462 TestMultiLineTextAtOffsetWithBoundaryAll) { | |
1463 base::win::ScopedComPtr<IAccessibleText> textarea_text; | |
1464 SetUpTextareaField(&textarea_text); | |
1465 | |
1466 CheckTextAtOffset(textarea_text, CONTENTS_LENGTH - 1, IA2_TEXT_BOUNDARY_ALL, | |
1467 0, CONTENTS_LENGTH, base::SysUTF8ToWide(TEXTAREA_CONTENTS)); | |
1468 } | |
1469 | |
757 } // namespace content | 1470 } // namespace content |
OLD | NEW |