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

Side by Side Diff: content/browser/accessibility/accessibility_win_browsertest.cc

Issue 660633002: Fixed IAccessibleText::TextAtOffset with IA2_TEXT_BOUNDARY_WORD to return text that spans from the … (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Broke up different boundary tests in their own test cases. Created 6 years, 1 month 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 (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 "net/base/escape.h"
dmazzoni 2014/11/17 19:06:46 nit: sort this
8 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_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"
25 #include "third_party/iaccessible2/ia2_api_all.h" 27 #include "third_party/iaccessible2/ia2_api_all.h"
26 #include "third_party/isimpledom/ISimpleDOMNode.h" 28 #include "third_party/isimpledom/ISimpleDOMNode.h"
27 #include "ui/aura/window.h" 29 #include "ui/aura/window.h"
28 #include "ui/aura/window_tree_host.h" 30 #include "ui/aura/window_tree_host.h"
29 31
30 namespace content { 32 namespace content {
31 33
32 namespace { 34 namespace {
33 35
34 // Helpers --------------------------------------------------------------------
35 36
36 base::win::ScopedComPtr<IAccessible> GetAccessibleFromResultVariant( 37 const char INPUT_CONTENTS[] = "Moz/5.0 (ST 6.x; WWW33) "
38 "WebKit \"KHTML, like\".";
39 const char TEXTAREA_CONTENTS[] = "Moz/5.0 (ST 6.x; WWW33)\n"
40 "WebKit \n\"KHTML, like\".";
41 const LONG CONTENTS_LENGTH = static_cast<LONG>(
42 (sizeof(INPUT_CONTENTS) - 1) / sizeof(char));
43
44
45 // AccessibilityWinBrowserTest ------------------------------------------------
46
47 class AccessibilityWinBrowserTest : public ContentBrowserTest {
48 public:
49 AccessibilityWinBrowserTest();
50 virtual ~AccessibilityWinBrowserTest();
51
52 protected:
53 class AccessibleChecker;
54 void LoadInitialAccessibilityTreeFromHtml(const std::string& html);
55 IAccessible* GetRendererAccessible();
56 void ExecuteScript(const std::wstring& script);
57 void SetUpTextFields(
58 base::win::ScopedComPtr<IAccessibleText>* input_text,
59 base::win::ScopedComPtr<IAccessibleText>* textarea_text);
60
61 static base::win::ScopedComPtr<IAccessible>
62 AccessibilityWinBrowserTest::GetAccessibleFromVariant(
63 IAccessible* parent,
64 VARIANT* var);
65 static HRESULT QueryIAccessible2(IAccessible* accessible,
66 IAccessible2** accessible2);
67 static void FindNodeInAccessibilityTree(IAccessible* node,
68 int32 expected_role,
69 const std::wstring& expected_name,
70 int32 depth,
71 bool* found);
72 static void CheckTextAtOffset(IAccessibleText* element,
73 LONG offset,
74 IA2TextBoundaryType boundary_type,
75 LONG expected_start_offset,
76 LONG expected_end_offset,
77 const std::wstring& expected_text);
78 static std::vector<base::win::ScopedVariant> GetAllAccessibleChildren(
79 IAccessible* element);
80
81 private:
82 DISALLOW_COPY_AND_ASSIGN(AccessibilityWinBrowserTest);
83 };
84
85 AccessibilityWinBrowserTest::AccessibilityWinBrowserTest() {
86 }
87
88 AccessibilityWinBrowserTest::~AccessibilityWinBrowserTest() {
89 }
90
91 void AccessibilityWinBrowserTest::LoadInitialAccessibilityTreeFromHtml(
92 const std::string& html) {
93 AccessibilityNotificationWaiter waiter(
94 shell(), AccessibilityModeComplete,
95 ui::AX_EVENT_LOAD_COMPLETE);
96 GURL html_data_url("data:text/html," + html);
97 NavigateToURL(shell(), html_data_url);
98 waiter.WaitForNotification();
99 }
100
101 // Retrieve the MSAA client accessibility object for the Render Widget Host View
102 // of the selected tab.
103 IAccessible* AccessibilityWinBrowserTest::GetRendererAccessible() {
104 content::WebContents* web_contents = shell()->web_contents();
105 base::string16 contents;
106 AccessibilityTreeFormatter* atf = AccessibilityTreeFormatter::Create(web_conte nts);
dmazzoni 2014/11/17 19:06:46 Use a scoped_ptr rather than manually deleting a p
107 atf->FormatAccessibilityTree(&contents);
108 DLOG(INFO) << contents;
109 delete atf;
110 return web_contents->GetRenderWidgetHostView()->GetNativeViewAccessible();
111 }
112
113 void AccessibilityWinBrowserTest::ExecuteScript(const std::wstring& script) {
114 shell()->web_contents()->GetMainFrame()->ExecuteJavaScript(script);
115 }
116
117 // Loads a page with two text fields, one using the input and one the textarea
118 // tags, and places the same sample text in both. Also, places the caret on the
119 // last character.
120 // Returns true if successful and false otherwise.
dmazzoni 2014/11/17 19:06:46 nit: no longer returns a bool
121 void AccessibilityWinBrowserTest::SetUpTextFields(
122 base::win::ScopedComPtr<IAccessibleText>* input_text,
123 base::win::ScopedComPtr<IAccessibleText>* textarea_text) {
124 ASSERT_NE(nullptr, input_text);
125 ASSERT_NE(nullptr, textarea_text);
126 LoadInitialAccessibilityTreeFromHtml(std::string("<!DOCTYPE html>"
127 "<html><body><form>"
128 "<label for='name'>Browser name:</label>"
129 "<input type='text' id='name' name='name' value='") +
130 net::EscapeQueryParamValue(INPUT_CONTENTS, false) + std::string(
131 "'></form><textarea rows='3' cols='60'>") +
132 net::EscapeQueryParamValue(TEXTAREA_CONTENTS, false) + std::string(
133 "</textarea></body></html>"));
134
135 // Retrieve the IAccessible interface for the web page.
136 base::win::ScopedComPtr<IAccessible> document(GetRendererAccessible());
137 std::vector<base::win::ScopedVariant> document_children =
138 GetAllAccessibleChildren(document);
139 ASSERT_EQ(2, document_children.size());
140
141 base::win::ScopedComPtr<IAccessible2> form;
142 HRESULT hr = QueryIAccessible2(GetAccessibleFromVariant(
143 document, document_children[0].AsInput()), form.Receive());
144 ASSERT_EQ(S_OK, hr);
145 std::vector<base::win::ScopedVariant> form_children =
146 GetAllAccessibleChildren(form);
147 ASSERT_EQ(2, form_children.size());
148 base::win::ScopedComPtr<IAccessible2> div;
149 hr = QueryIAccessible2(GetAccessibleFromVariant(
150 document, document_children[1].AsInput()), div.Receive());
151 ASSERT_EQ(S_OK, hr);
152 std::vector<base::win::ScopedVariant> div_children =
153 GetAllAccessibleChildren(div);
154 ASSERT_EQ(1, div_children.size());
155
156 // Find the two edit fields (simple and text area).
157 base::win::ScopedComPtr<IAccessible2> input;
158 hr = QueryIAccessible2(GetAccessibleFromVariant(
159 form, form_children[1].AsInput()), input.Receive());
160 ASSERT_EQ(S_OK, hr);
161 LONG input_role = 0;
162 hr = input->role(&input_role);
163 ASSERT_EQ(S_OK, hr);
164 ASSERT_EQ(ROLE_SYSTEM_TEXT, input_role);
165
166 base::win::ScopedComPtr<IAccessible2> textarea;
167 hr = QueryIAccessible2(GetAccessibleFromVariant(
168 div, div_children[0].AsInput()), textarea.Receive());
169 ASSERT_EQ(S_OK, hr);
170 LONG textarea_role = 0;
171 hr = textarea->role(&textarea_role);
172 ASSERT_EQ(S_OK, hr);
173 ASSERT_EQ(ROLE_SYSTEM_TEXT, input_role);
174
175 // Retrieve the IAccessibleText interface for both of the fields.
176 hr = input_text->QueryFrom(input);
177 ASSERT_EQ(S_OK, hr);
178 hr = textarea_text->QueryFrom(textarea);
179 ASSERT_EQ(S_OK, hr);
180 // Set the caret on the last character.
181 LONG caret_offset = CONTENTS_LENGTH - 1;
182 hr = (*input_text)->setCaretOffset(caret_offset);
183 ASSERT_EQ(S_OK, hr);
184 hr = (*textarea_text)->setCaretOffset(caret_offset);
185 ASSERT_EQ(S_OK, hr);
186 }
187
188 // Static helpers ------------------------------------------------
189
190 base::win::ScopedComPtr<IAccessible>
191 AccessibilityWinBrowserTest::GetAccessibleFromVariant(
37 IAccessible* parent, 192 IAccessible* parent,
38 VARIANT* var) { 193 VARIANT* var) {
39 base::win::ScopedComPtr<IAccessible> ptr; 194 base::win::ScopedComPtr<IAccessible> ptr;
40 switch (V_VT(var)) { 195 switch (V_VT(var)) {
41 case VT_DISPATCH: { 196 case VT_DISPATCH: {
42 IDispatch* dispatch = V_DISPATCH(var); 197 IDispatch* dispatch = V_DISPATCH(var);
43 if (dispatch) 198 if (dispatch)
44 ptr.QueryFrom(dispatch); 199 ptr.QueryFrom(dispatch);
45 break; 200 break;
46 } 201 }
47 202
48 case VT_I4: { 203 case VT_I4: {
49 base::win::ScopedComPtr<IDispatch> dispatch; 204 base::win::ScopedComPtr<IDispatch> dispatch;
50 HRESULT hr = parent->get_accChild(*var, dispatch.Receive()); 205 HRESULT hr = parent->get_accChild(*var, dispatch.Receive());
51 EXPECT_TRUE(SUCCEEDED(hr)); 206 EXPECT_TRUE(SUCCEEDED(hr));
52 if (dispatch) 207 if (dispatch)
53 dispatch.QueryInterface(ptr.Receive()); 208 dispatch.QueryInterface(ptr.Receive());
54 break; 209 break;
55 } 210 }
56 } 211 }
57 return ptr; 212 return ptr;
58 } 213 }
59 214
60 HRESULT QueryIAccessible2(IAccessible* accessible, IAccessible2** accessible2) { 215 HRESULT AccessibilityWinBrowserTest::QueryIAccessible2(
61 // TODO(ctguil): For some reason querying the IAccessible2 interface from 216 IAccessible* accessible,
62 // IAccessible fails. 217 IAccessible2** accessible2) {
218 // IA2 Spec dictates that IServiceProvider should be used instead of
219 // QueryInterface when retrieving IAccessible2.
63 base::win::ScopedComPtr<IServiceProvider> service_provider; 220 base::win::ScopedComPtr<IServiceProvider> service_provider;
64 HRESULT hr = accessible->QueryInterface(service_provider.Receive()); 221 HRESULT hr = accessible->QueryInterface(service_provider.Receive());
65 return SUCCEEDED(hr) ? 222 return SUCCEEDED(hr) ?
66 service_provider->QueryService(IID_IAccessible2, accessible2) : hr; 223 service_provider->QueryService(IID_IAccessible2, accessible2) : hr;
67 } 224 }
68 225
69 // Recursively search through all of the descendants reachable from an 226 // Recursively search through all of the descendants reachable from an
70 // IAccessible node and return true if we find one with the given role 227 // IAccessible node and return true if we find one with the given role
71 // and name. 228 // and name.
72 void RecursiveFindNodeInAccessibilityTree(IAccessible* node, 229 void AccessibilityWinBrowserTest::FindNodeInAccessibilityTree(
73 int32 expected_role, 230 IAccessible* node,
74 const std::wstring& expected_name, 231 int32 expected_role,
75 int32 depth, 232 const std::wstring& expected_name,
76 bool* found) { 233 int32 depth,
234 bool* found) {
77 base::win::ScopedBstr name_bstr; 235 base::win::ScopedBstr name_bstr;
78 base::win::ScopedVariant childid_self(CHILDID_SELF); 236 base::win::ScopedVariant childid_self(CHILDID_SELF);
79 node->get_accName(childid_self, name_bstr.Receive()); 237 node->get_accName(childid_self, name_bstr.Receive());
80 std::wstring name(name_bstr, name_bstr.Length()); 238 std::wstring name(name_bstr, name_bstr.Length());
81 base::win::ScopedVariant role; 239 base::win::ScopedVariant role;
82 node->get_accRole(childid_self, role.Receive()); 240 node->get_accRole(childid_self, role.Receive());
83 ASSERT_EQ(VT_I4, role.type()); 241 ASSERT_EQ(VT_I4, role.type());
84 242
85 // Print the accessibility tree as we go, because if this test fails 243 // Print the accessibility tree as we go, because if this test fails
86 // on the bots, this is really helpful in figuring out why. 244 // on the bots, this is really helpful in figuring out why.
87 for (int i = 0; i < depth; i++) 245 for (int i = 0; i < depth; i++)
88 printf(" "); 246 printf(" ");
89 printf("role=%s name=%s\n", 247 printf("role=%s name=%s\n",
90 base::WideToUTF8(IAccessibleRoleToString(V_I4(&role))).c_str(), 248 base::WideToUTF8(IAccessibleRoleToString(V_I4(&role))).c_str(),
91 base::WideToUTF8(name).c_str()); 249 base::WideToUTF8(name).c_str());
92 250
93 if (expected_role == V_I4(&role) && expected_name == name) { 251 if (expected_role == V_I4(&role) && expected_name == name) {
94 *found = true; 252 *found = true;
95 return; 253 return;
96 } 254 }
97 255
98 LONG child_count = 0; 256 std::vector<base::win::ScopedVariant> children = GetAllAccessibleChildren(
99 HRESULT hr = node->get_accChildCount(&child_count); 257 node);
100 ASSERT_EQ(S_OK, hr); 258 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( 259 base::win::ScopedComPtr<IAccessible> child_accessible(
111 GetAccessibleFromResultVariant(node, &child_array.get()[index])); 260 GetAccessibleFromVariant(node, children[i].AsInput()));
112 if (child_accessible) { 261 if (child_accessible) {
113 RecursiveFindNodeInAccessibilityTree( 262 FindNodeInAccessibilityTree(
114 child_accessible.get(), expected_role, expected_name, depth + 1, 263 child_accessible.get(), expected_role, expected_name, depth + 1,
115 found); 264 found);
116 if (*found) 265 if (*found)
117 return; 266 return;
118 } 267 }
119 } 268 }
120 } 269 }
121 270
271 // Ensures that the text and the start and end offsets retrieved using
272 // get_textAtOffset match the expected values.
273 void AccessibilityWinBrowserTest::CheckTextAtOffset(IAccessibleText* element,
274 LONG offset,
275 IA2TextBoundaryType boundar y_type,
276 LONG expected_start_offset,
277 LONG expected_end_offset,
278 const std::wstring& expecte d_text) {
279 testing::Message message;
280 message << "While checking for \'" << expected_text << "\' at " <<
281 expected_start_offset << '-' << expected_end_offset << '.';
282 SCOPED_TRACE(message);
122 283
123 // AccessibilityWinBrowserTest ------------------------------------------------ 284 LONG start_offset = 0;
124 285 LONG end_offset = 0;
125 class AccessibilityWinBrowserTest : public ContentBrowserTest { 286 base::win::ScopedBstr text;
126 public: 287 HRESULT hr = element->get_textAtOffset(
127 AccessibilityWinBrowserTest(); 288 offset, boundary_type,
128 virtual ~AccessibilityWinBrowserTest(); 289 &start_offset, &end_offset, text.Receive());
129 290 EXPECT_EQ(S_OK, hr);
130 protected: 291 EXPECT_EQ(expected_start_offset, start_offset);
131 void LoadInitialAccessibilityTreeFromHtml(const std::string& html); 292 EXPECT_EQ(expected_end_offset, end_offset);
132 IAccessible* GetRendererAccessible(); 293 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 } 294 }
141 295
142 AccessibilityWinBrowserTest::~AccessibilityWinBrowserTest() { 296 std::vector<base::win::ScopedVariant>
143 } 297 AccessibilityWinBrowserTest::GetAllAccessibleChildren(
298 IAccessible* element) {
299 LONG child_count = 0;
300 HRESULT hr = element->get_accChildCount(&child_count);
301 EXPECT_EQ(S_OK, hr);
302 if (child_count <= 0)
303 return std::vector<base::win::ScopedVariant>();
144 304
145 void AccessibilityWinBrowserTest::LoadInitialAccessibilityTreeFromHtml( 305 scoped_ptr<VARIANT[]> children_array(new VARIANT[child_count]);
146 const std::string& html) { 306 LONG obtained_count = 0;
147 AccessibilityNotificationWaiter waiter( 307 hr = AccessibleChildren(
148 shell(), AccessibilityModeComplete, 308 element, 0, child_count, children_array.get(), &obtained_count);
149 ui::AX_EVENT_LOAD_COMPLETE); 309 EXPECT_EQ(S_OK, hr);
150 GURL html_data_url("data:text/html," + html); 310 EXPECT_EQ(child_count, obtained_count);
151 NavigateToURL(shell(), html_data_url);
152 waiter.WaitForNotification();
153 }
154 311
155 // Retrieve the MSAA client accessibility object for the Render Widget Host View 312 std::vector<base::win::ScopedVariant> children(
156 // of the selected tab. 313 static_cast<size_t>(child_count));
157 IAccessible* AccessibilityWinBrowserTest::GetRendererAccessible() { 314 for (size_t i = 0; i < children.size(); i++) {
158 content::WebContents* web_contents = shell()->web_contents(); 315 children[i].Reset(children_array[i]);
159 return web_contents->GetRenderWidgetHostView()->GetNativeViewAccessible(); 316 }
160 } 317 return children;
161
162 void AccessibilityWinBrowserTest::ExecuteScript(const std::wstring& script) {
163 shell()->web_contents()->GetMainFrame()->ExecuteJavaScript(script);
164 } 318 }
165 319
166 320
167 // AccessibleChecker ---------------------------------------------------------- 321 // AccessibleChecker ----------------------------------------------------------
168 322
169 class AccessibleChecker { 323 class AccessibilityWinBrowserTest::AccessibleChecker {
170 public: 324 public:
171 // This constructor can be used if the IA2 role will be the same as the MSAA 325 // This constructor can be used if the IA2 role will be the same as the MSAA
172 // role. 326 // role.
173 AccessibleChecker(const std::wstring& expected_name, 327 AccessibleChecker(const std::wstring& expected_name,
174 int32 expected_role, 328 int32 expected_role,
175 const std::wstring& expected_value); 329 const std::wstring& expected_value);
176 AccessibleChecker(const std::wstring& expected_name, 330 AccessibleChecker(const std::wstring& expected_name,
177 int32 expected_role, 331 int32 expected_role,
178 int32 expected_ia2_role, 332 int32 expected_ia2_role,
179 const std::wstring& expected_value); 333 const std::wstring& expected_value);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 std::wstring value_; 375 std::wstring value_;
222 376
223 // Expected accessible state. Checked against IAccessible::get_accState. 377 // Expected accessible state. Checked against IAccessible::get_accState.
224 LONG state_; 378 LONG state_;
225 379
226 // Expected accessible children. Checked using IAccessible::get_accChildCount 380 // Expected accessible children. Checked using IAccessible::get_accChildCount
227 // and ::AccessibleChildren. 381 // and ::AccessibleChildren.
228 AccessibleCheckerVector children_; 382 AccessibleCheckerVector children_;
229 }; 383 };
230 384
231 AccessibleChecker::AccessibleChecker(const std::wstring& expected_name, 385 AccessibilityWinBrowserTest::AccessibleChecker::AccessibleChecker(
232 int32 expected_role, 386 const std::wstring& expected_name,
233 const std::wstring& expected_value) 387 int32 expected_role,
388 const std::wstring& expected_value)
234 : name_(expected_name), 389 : name_(expected_name),
235 role_(expected_role), 390 role_(expected_role),
236 ia2_role_(expected_role), 391 ia2_role_(expected_role),
237 value_(expected_value), 392 value_(expected_value),
238 state_(-1) { 393 state_(-1) {
239 } 394 }
240 395
241 AccessibleChecker::AccessibleChecker(const std::wstring& expected_name, 396 AccessibilityWinBrowserTest::AccessibleChecker::AccessibleChecker(
242 int32 expected_role, 397 const std::wstring& expected_name,
243 int32 expected_ia2_role, 398 int32 expected_role,
244 const std::wstring& expected_value) 399 int32 expected_ia2_role,
400 const std::wstring& expected_value)
245 : name_(expected_name), 401 : name_(expected_name),
246 role_(expected_role), 402 role_(expected_role),
247 ia2_role_(expected_ia2_role), 403 ia2_role_(expected_ia2_role),
248 value_(expected_value), 404 value_(expected_value),
249 state_(-1) { 405 state_(-1) {
250 } 406 }
251 407
252 AccessibleChecker::AccessibleChecker(const std::wstring& expected_name, 408 AccessibilityWinBrowserTest::AccessibleChecker::AccessibleChecker(
253 const std::wstring& expected_role, 409 const std::wstring& expected_name,
254 int32 expected_ia2_role, 410 const std::wstring& expected_role,
255 const std::wstring& expected_value) 411 int32 expected_ia2_role,
412 const std::wstring& expected_value)
256 : name_(expected_name), 413 : name_(expected_name),
257 role_(expected_role.c_str()), 414 role_(expected_role.c_str()),
258 ia2_role_(expected_ia2_role), 415 ia2_role_(expected_ia2_role),
259 value_(expected_value), 416 value_(expected_value),
260 state_(-1) { 417 state_(-1) {
261 } 418 }
262 419
263 void AccessibleChecker::AppendExpectedChild( 420 void AccessibilityWinBrowserTest::AccessibleChecker::AppendExpectedChild(
264 AccessibleChecker* expected_child) { 421 AccessibleChecker* expected_child) {
265 children_.push_back(expected_child); 422 children_.push_back(expected_child);
266 } 423 }
267 424
268 void AccessibleChecker::CheckAccessible(IAccessible* accessible) { 425 void AccessibilityWinBrowserTest::AccessibleChecker::CheckAccessible(
269 SCOPED_TRACE("while checking " + 426 IAccessible* accessible) {
270 base::UTF16ToUTF8(RoleVariantToString(role_))); 427 SCOPED_TRACE("While checking "
428 + base::UTF16ToUTF8(RoleVariantToString(role_)));
271 CheckAccessibleName(accessible); 429 CheckAccessibleName(accessible);
272 CheckAccessibleRole(accessible); 430 CheckAccessibleRole(accessible);
273 CheckIA2Role(accessible); 431 CheckIA2Role(accessible);
274 CheckAccessibleValue(accessible); 432 CheckAccessibleValue(accessible);
275 CheckAccessibleState(accessible); 433 CheckAccessibleState(accessible);
276 CheckAccessibleChildren(accessible); 434 CheckAccessibleChildren(accessible);
277 } 435 }
278 436
279 void AccessibleChecker::SetExpectedValue(const std::wstring& expected_value) { 437 void AccessibilityWinBrowserTest::AccessibleChecker::SetExpectedValue(
438 const std::wstring& expected_value) {
280 value_ = expected_value; 439 value_ = expected_value;
281 } 440 }
282 441
283 void AccessibleChecker::SetExpectedState(LONG expected_state) { 442 void AccessibilityWinBrowserTest::AccessibleChecker::SetExpectedState(
443 LONG expected_state) {
284 state_ = expected_state; 444 state_ = expected_state;
285 } 445 }
286 446
287 void AccessibleChecker::CheckAccessibleName(IAccessible* accessible) { 447 void AccessibilityWinBrowserTest::AccessibleChecker::CheckAccessibleName(
448 IAccessible* accessible) {
288 base::win::ScopedBstr name; 449 base::win::ScopedBstr name;
289 base::win::ScopedVariant childid_self(CHILDID_SELF); 450 base::win::ScopedVariant childid_self(CHILDID_SELF);
290 HRESULT hr = accessible->get_accName(childid_self, name.Receive()); 451 HRESULT hr = accessible->get_accName(childid_self, name.Receive());
291 452
292 if (name_.empty()) { 453 if (name_.empty()) {
293 // If the object doesn't have name S_FALSE should be returned. 454 // If the object doesn't have name S_FALSE should be returned.
294 EXPECT_EQ(S_FALSE, hr); 455 EXPECT_EQ(S_FALSE, hr);
295 } else { 456 } else {
296 // Test that the correct string was returned. 457 // Test that the correct string was returned.
297 EXPECT_EQ(S_OK, hr); 458 EXPECT_EQ(S_OK, hr);
298 EXPECT_EQ(name_, std::wstring(name, name.Length())); 459 EXPECT_EQ(name_, std::wstring(name, name.Length()));
299 } 460 }
300 } 461 }
301 462
302 void AccessibleChecker::CheckAccessibleRole(IAccessible* accessible) { 463 void AccessibilityWinBrowserTest::AccessibleChecker::CheckAccessibleRole(
464 IAccessible* accessible) {
303 base::win::ScopedVariant role; 465 base::win::ScopedVariant role;
304 base::win::ScopedVariant childid_self(CHILDID_SELF); 466 base::win::ScopedVariant childid_self(CHILDID_SELF);
305 HRESULT hr = accessible->get_accRole(childid_self, role.Receive()); 467 HRESULT hr = accessible->get_accRole(childid_self, role.Receive());
306 ASSERT_EQ(S_OK, hr); 468 ASSERT_EQ(S_OK, hr);
307 EXPECT_EQ(0, role_.Compare(role)) 469 EXPECT_EQ(0, role_.Compare(role))
308 << "Expected role: " << RoleVariantToString(role_) 470 << "Expected role: " << RoleVariantToString(role_)
309 << "\nGot role: " << RoleVariantToString(role); 471 << "\nGot role: " << RoleVariantToString(role);
310 } 472 }
311 473
312 void AccessibleChecker::CheckIA2Role(IAccessible* accessible) { 474 void AccessibilityWinBrowserTest::AccessibleChecker::CheckIA2Role(
475 IAccessible* accessible) {
313 base::win::ScopedComPtr<IAccessible2> accessible2; 476 base::win::ScopedComPtr<IAccessible2> accessible2;
314 HRESULT hr = QueryIAccessible2(accessible, accessible2.Receive()); 477 HRESULT hr = QueryIAccessible2(accessible, accessible2.Receive());
315 ASSERT_EQ(S_OK, hr); 478 ASSERT_EQ(S_OK, hr);
316 long ia2_role = 0; 479 long ia2_role = 0;
317 hr = accessible2->role(&ia2_role); 480 hr = accessible2->role(&ia2_role);
318 ASSERT_EQ(S_OK, hr); 481 ASSERT_EQ(S_OK, hr);
319 EXPECT_EQ(ia2_role_, ia2_role) 482 EXPECT_EQ(ia2_role_, ia2_role)
320 << "Expected ia2 role: " << IAccessible2RoleToString(ia2_role_) 483 << "Expected ia2 role: " << IAccessible2RoleToString(ia2_role_)
321 << "\nGot ia2 role: " << IAccessible2RoleToString(ia2_role); 484 << "\nGot ia2 role: " << IAccessible2RoleToString(ia2_role);
322 } 485 }
323 486
324 void AccessibleChecker::CheckAccessibleValue(IAccessible* accessible) { 487 void AccessibilityWinBrowserTest::AccessibleChecker::CheckAccessibleValue(
488 IAccessible* accessible) {
325 // Don't check the value if if's a DOCUMENT role, because the value 489 // 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 490 // is supposed to be the url (and we don't keep track of that in the
327 // test expectations). 491 // test expectations).
328 base::win::ScopedVariant role; 492 base::win::ScopedVariant role;
329 base::win::ScopedVariant childid_self(CHILDID_SELF); 493 base::win::ScopedVariant childid_self(CHILDID_SELF);
330 HRESULT hr = accessible->get_accRole(childid_self, role.Receive()); 494 HRESULT hr = accessible->get_accRole(childid_self, role.Receive());
331 ASSERT_EQ(S_OK, hr); 495 ASSERT_EQ(S_OK, hr);
332 if (role.type() == VT_I4 && V_I4(&role) == ROLE_SYSTEM_DOCUMENT) 496 if (role.type() == VT_I4 && V_I4(&role) == ROLE_SYSTEM_DOCUMENT)
333 return; 497 return;
334 498
335 // Get the value. 499 // Get the value.
336 base::win::ScopedBstr value; 500 base::win::ScopedBstr value;
337 hr = accessible->get_accValue(childid_self, value.Receive()); 501 hr = accessible->get_accValue(childid_self, value.Receive());
338 EXPECT_EQ(S_OK, hr); 502 EXPECT_EQ(S_OK, hr);
339 503
340 // Test that the correct string was returned. 504 // Test that the correct string was returned.
341 EXPECT_EQ(value_, std::wstring(value, value.Length())); 505 EXPECT_EQ(value_, std::wstring(value, value.Length()));
342 } 506 }
343 507
344 void AccessibleChecker::CheckAccessibleState(IAccessible* accessible) { 508 void AccessibilityWinBrowserTest::AccessibleChecker::CheckAccessibleState(
509 IAccessible* accessible) {
345 if (state_ < 0) 510 if (state_ < 0)
346 return; 511 return;
347 512
348 base::win::ScopedVariant state; 513 base::win::ScopedVariant state;
349 base::win::ScopedVariant childid_self(CHILDID_SELF); 514 base::win::ScopedVariant childid_self(CHILDID_SELF);
350 HRESULT hr = accessible->get_accState(childid_self, state.Receive()); 515 HRESULT hr = accessible->get_accState(childid_self, state.Receive());
351 EXPECT_EQ(S_OK, hr); 516 EXPECT_EQ(S_OK, hr);
352 ASSERT_EQ(VT_I4, state.type()); 517 ASSERT_EQ(VT_I4, state.type());
353 LONG obj_state = V_I4(&state); 518 LONG obj_state = V_I4(&state);
354 // Avoid flakiness. The "offscreen" state depends on whether the browser 519 // Avoid flakiness. The "offscreen" state depends on whether the browser
355 // window is frontmost or not, and "hottracked" depends on whether the 520 // window is frontmost or not, and "hottracked" depends on whether the
356 // mouse cursor happens to be over the element. 521 // mouse cursor happens to be over the element.
357 obj_state &= ~(STATE_SYSTEM_OFFSCREEN | STATE_SYSTEM_HOTTRACKED); 522 obj_state &= ~(STATE_SYSTEM_OFFSCREEN | STATE_SYSTEM_HOTTRACKED);
358 EXPECT_EQ(state_, obj_state) 523 EXPECT_EQ(state_, obj_state)
359 << "Expected state: " << IAccessibleStateToString(state_) 524 << "Expected state: " << IAccessibleStateToString(state_)
360 << "\nGot state: " << IAccessibleStateToString(obj_state); 525 << "\nGot state: " << IAccessibleStateToString(obj_state);
361 } 526 }
362 527
363 void AccessibleChecker::CheckAccessibleChildren(IAccessible* parent) { 528 void AccessibilityWinBrowserTest::AccessibleChecker::CheckAccessibleChildren(
364 LONG child_count = 0; 529 IAccessible* parent) {
365 HRESULT hr = parent->get_accChildCount(&child_count); 530 std::vector<base::win::ScopedVariant> obtained_children =
366 EXPECT_EQ(S_OK, hr); 531 GetAllAccessibleChildren(parent);
532 size_t child_count = obtained_children.size();
367 ASSERT_EQ(child_count, children_.size()); 533 ASSERT_EQ(child_count, children_.size());
368 534
369 scoped_ptr<VARIANT[]> child_array(new VARIANT[child_count]); 535 AccessibleCheckerVector::iterator child_checker;
370 LONG obtained_count = 0; 536 std::vector<base::win::ScopedVariant>::iterator child;
371 hr = AccessibleChildren(parent, 0, child_count, 537 for (child_checker = children_.begin(),
372 child_array.get(), &obtained_count); 538 child = obtained_children.begin();
373 ASSERT_EQ(S_OK, hr); 539 child_checker != children_.end()
374 ASSERT_EQ(child_count, obtained_count); 540 && 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) { 541 ++child_checker, ++child) {
380 base::win::ScopedComPtr<IAccessible> child_accessible( 542 base::win::ScopedComPtr<IAccessible> child_accessible(
381 GetAccessibleFromResultVariant(parent, child)); 543 GetAccessibleFromVariant(parent, child->AsInput()));
382 ASSERT_TRUE(child_accessible.get()); 544 ASSERT_TRUE(child_accessible.get());
383 (*child_checker)->CheckAccessible(child_accessible); 545 (*child_checker)->CheckAccessible(child_accessible);
384 } 546 }
385 } 547 }
386 548
387 base::string16 AccessibleChecker::RoleVariantToString( 549 base::string16
550 AccessibilityWinBrowserTest::AccessibleChecker::RoleVariantToString(
388 const base::win::ScopedVariant& role) { 551 const base::win::ScopedVariant& role) {
389 if (role.type() == VT_I4) 552 if (role.type() == VT_I4)
390 return IAccessibleRoleToString(V_I4(&role)); 553 return IAccessibleRoleToString(V_I4(&role));
391 if (role.type() == VT_BSTR) 554 if (role.type() == VT_BSTR)
392 return base::string16(V_BSTR(&role), SysStringLen(V_BSTR(&role))); 555 return base::string16(V_BSTR(&role), SysStringLen(V_BSTR(&role)));
393 return base::string16(); 556 return base::string16();
394 } 557 }
395 558
396 } // namespace 559 } // namespace
397 560
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 CHECK(hwnd); 823 CHECK(hwnd);
661 base::win::ScopedComPtr<IAccessible> browser_accessible; 824 base::win::ScopedComPtr<IAccessible> browser_accessible;
662 HRESULT hr = AccessibleObjectFromWindow( 825 HRESULT hr = AccessibleObjectFromWindow(
663 hwnd, 826 hwnd,
664 OBJID_WINDOW, 827 OBJID_WINDOW,
665 IID_IAccessible, 828 IID_IAccessible,
666 reinterpret_cast<void**>(browser_accessible.Receive())); 829 reinterpret_cast<void**>(browser_accessible.Receive()));
667 ASSERT_EQ(S_OK, hr); 830 ASSERT_EQ(S_OK, hr);
668 831
669 bool found = false; 832 bool found = false;
670 RecursiveFindNodeInAccessibilityTree( 833 FindNodeInAccessibilityTree(
671 browser_accessible.get(), ROLE_SYSTEM_DOCUMENT, L"MyDocument", 0, &found); 834 browser_accessible.get(), ROLE_SYSTEM_DOCUMENT, L"MyDocument", 0, &found);
672 ASSERT_EQ(found, true); 835 ASSERT_EQ(found, true);
673 } 836 }
674 837
675 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, 838 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
676 SupportsISimpleDOM) { 839 SupportsISimpleDOM) {
677 LoadInitialAccessibilityTreeFromHtml( 840 LoadInitialAccessibilityTreeFromHtml(
678 "<body><input type='checkbox' /></body>"); 841 "<body><input type='checkbox' /></body>");
679 842
680 // Get the IAccessible object for the document. 843 // Get the IAccessible object for the document.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 std::wstring()); 909 std::wstring());
747 AccessibleChecker grouping2_checker(std::wstring(), ROLE_SYSTEM_GROUPING, 910 AccessibleChecker grouping2_checker(std::wstring(), ROLE_SYSTEM_GROUPING,
748 std::wstring()); 911 std::wstring());
749 AccessibleChecker document_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT, 912 AccessibleChecker document_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT,
750 std::wstring()); 913 std::wstring());
751 document_checker.AppendExpectedChild(&grouping1_checker); 914 document_checker.AppendExpectedChild(&grouping1_checker);
752 document_checker.AppendExpectedChild(&grouping2_checker); 915 document_checker.AppendExpectedChild(&grouping2_checker);
753 document_checker.CheckAccessible(GetRendererAccessible()); 916 document_checker.CheckAccessible(GetRendererAccessible());
754 } 917 }
755 918
919 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
920 TestTextAtOffsetWithInvalidArgs) {
921 base::win::ScopedComPtr<IAccessibleText> input_text;
922 base::win::ScopedComPtr<IAccessibleText> textarea_text;
923 SetUpTextFields(&input_text, &textarea_text);
924 HRESULT hr = input_text->get_textAtOffset(
925 0, IA2_TEXT_BOUNDARY_CHAR, NULL, NULL, NULL);
926 EXPECT_EQ(E_INVALIDARG, hr);
927 hr = textarea_text->get_textAtOffset(
928 0, IA2_TEXT_BOUNDARY_CHAR, NULL, NULL, NULL);
929 EXPECT_EQ(E_INVALIDARG, hr);
930
931 // Test invalid offset.
932 LONG start_offset = 0;
933 LONG end_offset = 0;
934 base::win::ScopedBstr text;
935 LONG invalid_offset = -5;
936 hr = input_text->get_textAtOffset(
937 invalid_offset, IA2_TEXT_BOUNDARY_CHAR,
938 &start_offset, &end_offset, text.Receive());
939 EXPECT_EQ(E_INVALIDARG, hr);
940 hr = textarea_text->get_textAtOffset(
941 invalid_offset, IA2_TEXT_BOUNDARY_WORD,
942 &start_offset, &end_offset, text.Receive());
943 EXPECT_EQ(E_INVALIDARG, hr);
944
945 // According to the IA2 Spec, only line boundaries should succeed when
946 // the offset is one past the end of the text.
947 invalid_offset = CONTENTS_LENGTH;
948 hr = input_text->get_textAtOffset(
949 invalid_offset, IA2_TEXT_BOUNDARY_LINE,
950 &start_offset, &end_offset, text.Receive());
951 EXPECT_EQ(S_OK, hr);
952 hr = textarea_text->get_textAtOffset(
953 invalid_offset, IA2_TEXT_BOUNDARY_LINE,
954 &start_offset, &end_offset, text.Receive());
955 EXPECT_EQ(S_OK, hr);
956
957 hr = input_text->get_textAtOffset(
958 invalid_offset, IA2_TEXT_BOUNDARY_CHAR,
959 &start_offset, &end_offset, text.Receive());
960 EXPECT_EQ(S_FALSE, hr);
961 hr = input_text->get_textAtOffset(
962 invalid_offset, IA2_TEXT_BOUNDARY_WORD,
963 &start_offset, &end_offset, text.Receive());
964 EXPECT_EQ(S_FALSE, hr);
965 hr = textarea_text->get_textAtOffset(
966 invalid_offset, IA2_TEXT_BOUNDARY_SENTENCE,
967 &start_offset, &end_offset, text.Receive());
968 EXPECT_EQ(S_FALSE, hr);
969 hr = textarea_text->get_textAtOffset(
970 invalid_offset, IA2_TEXT_BOUNDARY_ALL,
971 &start_offset, &end_offset, text.Receive());
972 EXPECT_EQ(S_FALSE, hr);
973 }
974
975 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
976 TestTextAtOffsetWithBoundaryCharacter) {
977 base::win::ScopedComPtr<IAccessibleText> input_text;
978 base::win::ScopedComPtr<IAccessibleText> textarea_text;
979 SetUpTextFields(&input_text, &textarea_text);
980 for (LONG offset = 0; offset < CONTENTS_LENGTH; ++offset) {
981 std::wstring expected_text(1, INPUT_CONTENTS[offset]);
982 LONG expected_start_offset = offset;
983 LONG expected_end_offset = offset + 1;
984 CheckTextAtOffset(input_text, offset, IA2_TEXT_BOUNDARY_CHAR,
985 expected_start_offset, expected_end_offset, expected_text);
986 }
987 for (LONG offset = CONTENTS_LENGTH - 1; offset >= 0; --offset) {
988 std::wstring expected_text(1, TEXTAREA_CONTENTS[offset]);
989 LONG expected_start_offset = offset;
990 LONG expected_end_offset = offset + 1;
991 CheckTextAtOffset(textarea_text, offset, IA2_TEXT_BOUNDARY_CHAR,
992 expected_start_offset, expected_end_offset, expected_text);
993 }
994 // Test special offsets.
995 CheckTextAtOffset(input_text, IA2_TEXT_OFFSET_LENGTH,
996 IA2_TEXT_BOUNDARY_CHAR, CONTENTS_LENGTH - 1, CONTENTS_LENGTH, L".");
997 CheckTextAtOffset(input_text, IA2_TEXT_OFFSET_CARET,
998 IA2_TEXT_BOUNDARY_CHAR, CONTENTS_LENGTH - 1, CONTENTS_LENGTH, L".");
999 CheckTextAtOffset(textarea_text, IA2_TEXT_OFFSET_LENGTH,
1000 IA2_TEXT_BOUNDARY_CHAR, CONTENTS_LENGTH - 1, CONTENTS_LENGTH, L".");
1001 CheckTextAtOffset(textarea_text, IA2_TEXT_OFFSET_CARET,
1002 IA2_TEXT_BOUNDARY_CHAR, CONTENTS_LENGTH - 1, CONTENTS_LENGTH, L".");
1003 }
1004
1005 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
1006 TestTextAtOffsetWithBoundaryWord) {
1007 base::win::ScopedComPtr<IAccessibleText> input_text;
1008 base::win::ScopedComPtr<IAccessibleText> textarea_text;
1009 SetUpTextFields(&input_text, &textarea_text);
1010
1011 // Trailing punctuation should be included as part of the previous word.
1012 CheckTextAtOffset(input_text, 0, IA2_TEXT_BOUNDARY_WORD,
1013 0, 4, L"Moz/");
1014 CheckTextAtOffset(textarea_text, 2, IA2_TEXT_BOUNDARY_WORD,
1015 0, 4, L"Moz/");
1016
1017 // If the offset is at the punctuation, it should return
1018 // the previous word.
1019 CheckTextAtOffset(textarea_text, 3, IA2_TEXT_BOUNDARY_WORD,
1020 0, 4, L"Moz/");
1021
1022 // Numbers with a decimal point ("." for U.S), should be treated as one word.
1023 // Also, trailing punctuation that occurs after empty space should be part of
1024 // the word. ("5.0 (" and not "5.0 ".)
1025 CheckTextAtOffset(input_text, 4, IA2_TEXT_BOUNDARY_WORD,
1026 4, 9, L"5.0 (");
1027 CheckTextAtOffset(textarea_text, 5, IA2_TEXT_BOUNDARY_WORD,
1028 4, 9, L"5.0 (");
1029 CheckTextAtOffset(input_text, 6, IA2_TEXT_BOUNDARY_WORD,
1030 4, 9, L"5.0 (");
1031 CheckTextAtOffset(textarea_text, 7, IA2_TEXT_BOUNDARY_WORD,
1032 4, 9, L"5.0 (");
1033
1034 // Leading punctuation should not be included with the word after it.
1035 CheckTextAtOffset(input_text, 8, IA2_TEXT_BOUNDARY_WORD,
1036 4, 9, L"5.0 (");
1037 CheckTextAtOffset(textarea_text, 11, IA2_TEXT_BOUNDARY_WORD,
1038 9, 12, L"ST ");
1039
1040 // Numbers separated from letters with trailing punctuation should
1041 // be split into two words. Same for abreviations like "i.e.".
1042 CheckTextAtOffset(input_text, 12, IA2_TEXT_BOUNDARY_WORD,
1043 12, 14, L"6.");
1044 CheckTextAtOffset(textarea_text, 15, IA2_TEXT_BOUNDARY_WORD,
1045 14, 17, L"x; ");
1046
1047 // Words with numbers should be treated like ordinary words.
1048 CheckTextAtOffset(input_text, 17, IA2_TEXT_BOUNDARY_WORD,
1049 17, 24, L"WWW33) ");
1050 CheckTextAtOffset(textarea_text, 23, IA2_TEXT_BOUNDARY_WORD,
1051 17, 24, L"WWW33)\n");
1052 // Multiple trailing empty spaces should be part of the word preceding it.
1053 CheckTextAtOffset(input_text, 28, IA2_TEXT_BOUNDARY_WORD,
1054 24, 33, L"WebKit \"");
1055 CheckTextAtOffset(textarea_text, 31, IA2_TEXT_BOUNDARY_WORD,
1056 24, 33, L"WebKit \n\"");
1057 // Leading punctuation such as quotation marks should not be part of the word.
1058 CheckTextAtOffset(input_text, 32, IA2_TEXT_BOUNDARY_WORD,
1059 24, 33, L"WebKit \"");
1060 CheckTextAtOffset(textarea_text, 32, IA2_TEXT_BOUNDARY_WORD,
1061 24, 33, L"WebKit \n\"");
1062 CheckTextAtOffset(input_text, 33, IA2_TEXT_BOUNDARY_WORD,
1063 33, 40, L"KHTML, ");
1064 CheckTextAtOffset(textarea_text, 38, IA2_TEXT_BOUNDARY_WORD,
1065 33, 40, L"KHTML, ");
1066 // Trailing final punctuation should be part of the last word.
1067 CheckTextAtOffset(input_text, 45, IA2_TEXT_BOUNDARY_WORD,
1068 40, CONTENTS_LENGTH, L"like\".");
1069 CheckTextAtOffset(textarea_text, 41, IA2_TEXT_BOUNDARY_WORD,
1070 40, CONTENTS_LENGTH, L"like\".");
1071 // Test special offsets.
1072 CheckTextAtOffset(input_text, IA2_TEXT_OFFSET_LENGTH,
1073 IA2_TEXT_BOUNDARY_WORD, 40, CONTENTS_LENGTH, L"like\".");
1074 CheckTextAtOffset(input_text, IA2_TEXT_OFFSET_CARET,
1075 IA2_TEXT_BOUNDARY_WORD, 40, CONTENTS_LENGTH, L"like\".");
1076 CheckTextAtOffset(textarea_text, IA2_TEXT_OFFSET_LENGTH,
1077 IA2_TEXT_BOUNDARY_WORD, 40, CONTENTS_LENGTH, L"like\".");
1078 CheckTextAtOffset(textarea_text, IA2_TEXT_OFFSET_CARET,
1079 IA2_TEXT_BOUNDARY_WORD, 40, CONTENTS_LENGTH, L"like\".");
1080 }
1081
1082 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
1083 TestTextAtOffsetWithBoundarySentence) {
1084 base::win::ScopedComPtr<IAccessibleText> input_text;
1085 base::win::ScopedComPtr<IAccessibleText> textarea_text;
1086 SetUpTextFields(&input_text, &textarea_text);
1087
1088 // Sentence navigation is not currently implemented.
1089 LONG start_offset = 0;
1090 LONG end_offset = 0;
1091 base::win::ScopedBstr text;
1092 HRESULT hr = input_text->get_textAtOffset(
1093 5, IA2_TEXT_BOUNDARY_SENTENCE,
1094 &start_offset, &end_offset, text.Receive());
1095 EXPECT_EQ(S_FALSE, hr);
1096 hr = textarea_text->get_textAtOffset(
1097 25, IA2_TEXT_BOUNDARY_SENTENCE,
1098 &start_offset, &end_offset, text.Receive());
1099 EXPECT_EQ(S_FALSE, hr);
1100 }
1101
1102 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
1103 TestTextAtOffsetWithBoundaryLine) {
1104 base::win::ScopedComPtr<IAccessibleText> input_text;
1105 base::win::ScopedComPtr<IAccessibleText> textarea_text;
1106 SetUpTextFields(&input_text, &textarea_text);
1107
1108 // Single line text fields should return the whole text.
1109 CheckTextAtOffset(input_text, 0, IA2_TEXT_BOUNDARY_LINE,
1110 0, CONTENTS_LENGTH, base::ASCIIToWide(INPUT_CONTENTS));
1111 // Textarea is a multi-line text field.
1112 CheckTextAtOffset(textarea_text, 0, IA2_TEXT_BOUNDARY_LINE,
1113 0, 24, L"Moz/5.0 (ST 6.x; WWW33)\n");
1114 // If the offset is at the newline, return the line preceding it.
1115 CheckTextAtOffset(textarea_text, 31, IA2_TEXT_BOUNDARY_LINE,
1116 24, 32, L"WebKit \n");
1117 // Last line does not have a trailing newline.
1118 CheckTextAtOffset(textarea_text, 32, IA2_TEXT_BOUNDARY_LINE,
1119 32, CONTENTS_LENGTH, L"\"KHTML, like\".");
1120 // An offset one past the last character should return the last line.
1121 CheckTextAtOffset(textarea_text, CONTENTS_LENGTH, IA2_TEXT_BOUNDARY_LINE,
1122 32, CONTENTS_LENGTH, L"\"KHTML, like\".");
1123 // Test special offsets.
1124 CheckTextAtOffset(textarea_text, IA2_TEXT_OFFSET_LENGTH,
1125 IA2_TEXT_BOUNDARY_LINE, 32, CONTENTS_LENGTH, L"\"KHTML, like\".");
1126 CheckTextAtOffset(textarea_text, IA2_TEXT_OFFSET_CARET,
1127 IA2_TEXT_BOUNDARY_LINE, 32, CONTENTS_LENGTH, L"\"KHTML, like\".");
1128 }
1129
1130 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
1131 TestTextAtOffsetWithBoundaryAll) {
1132 base::win::ScopedComPtr<IAccessibleText> input_text;
1133 base::win::ScopedComPtr<IAccessibleText> textarea_text;
1134 SetUpTextFields(&input_text, &textarea_text);
1135
1136 CheckTextAtOffset(input_text, 0, IA2_TEXT_BOUNDARY_ALL,
1137 0, CONTENTS_LENGTH, base::ASCIIToWide(INPUT_CONTENTS));
1138 CheckTextAtOffset(textarea_text, CONTENTS_LENGTH - 1, IA2_TEXT_BOUNDARY_ALL,
1139 0, CONTENTS_LENGTH, base::ASCIIToWide(TEXTAREA_CONTENTS));
1140 }
1141
756 } // namespace content 1142 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698