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

Side by Side Diff: chrome/browser/accessibility_win_browsertest.cc

Issue 3591003: Make BrowserAccessibilityManager cross platform. Step 1.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Some cleanup. Created 10 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <atlbase.h>
6 #include <vector>
7
8 #include "base/scoped_comptr_win.h"
9 #include "chrome/browser/automation/ui_controls.h"
10 #include "chrome/browser/browser.h"
11 #include "chrome/browser/browser_window.h"
12 #include "chrome/browser/renderer_host/render_view_host.h"
13 #include "chrome/browser/renderer_host/render_widget_host_view_win.h"
14 #include "chrome/browser/tab_contents/tab_contents.h"
15 #include "chrome/common/chrome_switches.h"
16 #include "chrome/common/notification_type.h"
17 #include "chrome/test/in_process_browser_test.h"
18 #include "chrome/test/ui_test_utils.h"
19 #include "ia2_api_all.h" // Generated
20
21 using std::auto_ptr;
22 using std::vector;
23 using std::wstring;
24
25 namespace {
26
27 class AccessibilityWinBrowserTest : public InProcessBrowserTest {
28 public:
29 AccessibilityWinBrowserTest() {}
30
31 // InProcessBrowserTest
32 void SetUpInProcessBrowserTestFixture();
33
34 protected:
35 IAccessible* GetRendererAccessible();
36 void ExecuteScript(wstring script);
37 };
38
39 void AccessibilityWinBrowserTest::SetUpInProcessBrowserTestFixture() {
40 // If the mouse happens to be on the document then it will have the unexpected
41 // STATE_SYSTEM_HOTTRACKED state. Move it to a non-document location.
42 ui_controls::SendMouseMove(0, 0);
43 }
44
45 class AccessibleChecker {
46 public:
47 AccessibleChecker(
48 wstring expected_name,
49 int32 expected_role,
50 wstring expected_value);
51 AccessibleChecker(
52 wstring expected_name,
53 wstring expected_role,
54 wstring expected_value);
55
56 // Append an AccessibleChecker that verifies accessibility information for
57 // a child IAccessible. Order is important.
58 void AppendExpectedChild(AccessibleChecker* expected_child);
59
60 // Check that the name and role of the given IAccessible instance and its
61 // descendants match the expected names and roles that this object was
62 // initialized with.
63 void CheckAccessible(IAccessible* accessible);
64
65 // Set the expected value for this AccessibleChecker.
66 void SetExpectedValue(wstring expected_value);
67
68 // Set the expected state for this AccessibleChecker.
69 void SetExpectedState(LONG expected_state);
70
71 private:
72 void CheckAccessibleName(IAccessible* accessible);
73 void CheckAccessibleRole(IAccessible* accessible);
74 void CheckAccessibleValue(IAccessible* accessible);
75 void CheckAccessibleState(IAccessible* accessible);
76 void CheckAccessibleChildren(IAccessible* accessible);
77
78 private:
79 typedef vector<AccessibleChecker*> AccessibleCheckerVector;
80
81 // Expected accessible name. Checked against IAccessible::get_accName.
82 wstring name_;
83
84 // Expected accessible role. Checked against IAccessible::get_accRole.
85 CComVariant role_;
86
87 // Expected accessible value. Checked against IAccessible::get_accValue.
88 wstring value_;
89
90 // Expected accessible state. Checked against IAccessible::get_accState.
91 LONG state_;
92
93 // Expected accessible children. Checked using IAccessible::get_accChildCount
94 // and ::AccessibleChildren.
95 AccessibleCheckerVector children_;
96 };
97
98 VARIANT CreateI4Variant(LONG value) {
99 VARIANT variant = {0};
100
101 V_VT(&variant) = VT_I4;
102 V_I4(&variant) = value;
103
104 return variant;
105 }
106
107 IAccessible* GetAccessibleFromResultVariant(IAccessible* parent, VARIANT *var) {
108 switch (V_VT(var)) {
109 case VT_DISPATCH:
110 return CComQIPtr<IAccessible>(V_DISPATCH(var)).Detach();
111 break;
112
113 case VT_I4: {
114 CComPtr<IDispatch> dispatch;
115 HRESULT hr = parent->get_accChild(CreateI4Variant(V_I4(var)), &dispatch);
116 EXPECT_TRUE(SUCCEEDED(hr));
117 return CComQIPtr<IAccessible>(dispatch).Detach();
118 break;
119 }
120 }
121
122 return NULL;
123 }
124
125 HRESULT QueryIAccessible2(IAccessible* accessible, IAccessible2** accessible2) {
126 // TODO(ctguil): For some reason querying the IAccessible2 interface from
127 // IAccessible fails.
128 ScopedComPtr<IServiceProvider> service_provider;
129 HRESULT hr = accessible->QueryInterface(service_provider.Receive());
130 if (FAILED(hr))
131 return hr;
132
133 hr = service_provider->QueryService(IID_IAccessible2, accessible2);
134 return hr;
135 }
136
137 // Sets result to true if the child is located in the parent's tree. An
138 // exhustive search is perform here because we determine equality using
139 // IAccessible2::get_uniqueID which is only supported by the child node.
140 void AccessibleContainsAccessible(
141 IAccessible* parent, IAccessible2* child, bool* result) {
142 vector<ScopedComPtr<IAccessible>> accessible_list;
143 accessible_list.push_back(ScopedComPtr<IAccessible>(parent));
144
145 LONG unique_id;
146 HRESULT hr = child->get_uniqueID(&unique_id);
147 ASSERT_EQ(hr, S_OK);
148 *result = false;
149
150 while (accessible_list.size()) {
151 ScopedComPtr<IAccessible> accessible = accessible_list.back();
152 accessible_list.pop_back();
153
154 ScopedComPtr<IAccessible2> accessible2;
155 hr = QueryIAccessible2(accessible, accessible2.Receive());
156 if (SUCCEEDED(hr)) {
157 LONG child_id;
158 accessible2->get_uniqueID(&child_id);
159 if (child_id == unique_id) {
160 *result = true;
161 break;
162 }
163 }
164
165 LONG child_count;
166 hr = accessible->get_accChildCount(&child_count);
167 ASSERT_EQ(hr, S_OK);
168 if (child_count == 0)
169 continue;
170
171 auto_ptr<VARIANT> child_array(new VARIANT[child_count]);
172 LONG obtained_count = 0;
173 hr = AccessibleChildren(
174 accessible, 0, child_count, child_array.get(), &obtained_count);
175 ASSERT_EQ(hr, S_OK);
176 ASSERT_EQ(child_count, obtained_count);
177
178 for (int index = 0; index < obtained_count; index++) {
179 ScopedComPtr<IAccessible> child_accessible(
180 GetAccessibleFromResultVariant(accessible, &child_array.get()[index]));
181 if (child_accessible.get())
182 accessible_list.push_back(ScopedComPtr<IAccessible>(child_accessible));
183 }
184 }
185 }
186
187 // Retrieve the MSAA client accessibility object for the Render Widget Host View
188 // of the selected tab.
189 IAccessible*
190 AccessibilityWinBrowserTest::GetRendererAccessible() {
191 HWND hwnd_render_widget_host_view =
192 browser()->GetSelectedTabContents()->GetRenderWidgetHostView()->
193 GetNativeView();
194
195 // By requesting an accessible chrome will believe a screen reader has been
196 // detected.
197 IAccessible* accessible;
198 HRESULT hr = AccessibleObjectFromWindow(
199 hwnd_render_widget_host_view, OBJID_CLIENT,
200 IID_IAccessible, reinterpret_cast<void**>(&accessible));
201 EXPECT_EQ(S_OK, hr);
202 EXPECT_NE(accessible, reinterpret_cast<IAccessible*>(NULL));
203
204 return accessible;
205 }
206
207 void AccessibilityWinBrowserTest::ExecuteScript(wstring script) {
208 browser()->GetSelectedTabContents()->render_view_host()->
209 ExecuteJavascriptInWebFrame(L"", script);
210 }
211
212 AccessibleChecker::AccessibleChecker(
213 wstring expected_name, int32 expected_role, wstring expected_value) :
214 name_(expected_name),
215 role_(expected_role),
216 value_(expected_value),
217 state_(-1) {
218 }
219
220 AccessibleChecker::AccessibleChecker(
221 wstring expected_name, wstring expected_role, wstring expected_value) :
222 name_(expected_name),
223 role_(expected_role.c_str()),
224 value_(expected_value),
225 state_(-1) {
226 }
227
228 void AccessibleChecker::AppendExpectedChild(
229 AccessibleChecker* expected_child) {
230 children_.push_back(expected_child);
231 }
232
233 void AccessibleChecker::CheckAccessible(IAccessible* accessible) {
234 CheckAccessibleName(accessible);
235 CheckAccessibleRole(accessible);
236 CheckAccessibleValue(accessible);
237 CheckAccessibleState(accessible);
238 CheckAccessibleChildren(accessible);
239 }
240
241 void AccessibleChecker::SetExpectedValue(wstring expected_value) {
242 value_ = expected_value;
243 }
244
245 void AccessibleChecker::SetExpectedState(LONG expected_state) {
246 state_ = expected_state;
247 }
248
249 void AccessibleChecker::CheckAccessibleName(IAccessible* accessible) {
250 CComBSTR name;
251 HRESULT hr =
252 accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);
253
254 if (name_.empty()) {
255 // If the object doesn't have name S_FALSE should be returned.
256 EXPECT_EQ(hr, S_FALSE);
257 } else {
258 // Test that the correct string was returned.
259 EXPECT_EQ(hr, S_OK);
260 EXPECT_STREQ(name_.c_str(),
261 wstring(name.m_str, SysStringLen(name)).c_str());
262 }
263 }
264
265 void AccessibleChecker::CheckAccessibleRole(IAccessible* accessible) {
266 VARIANT var_role = {0};
267 HRESULT hr =
268 accessible->get_accRole(CreateI4Variant(CHILDID_SELF), &var_role);
269 ASSERT_EQ(hr, S_OK);
270 EXPECT_TRUE(role_ == var_role);
271 }
272
273 void AccessibleChecker::CheckAccessibleValue(IAccessible* accessible) {
274 CComBSTR value;
275 HRESULT hr =
276 accessible->get_accValue(CreateI4Variant(CHILDID_SELF), &value);
277 EXPECT_EQ(S_OK, hr);
278
279 // Test that the correct string was returned.
280 EXPECT_STREQ(value_.c_str(),
281 wstring(value.m_str, SysStringLen(value)).c_str());
282 }
283
284 void AccessibleChecker::CheckAccessibleState(IAccessible* accessible) {
285 if (state_ < 0)
286 return;
287
288 VARIANT var_state = {0};
289 HRESULT hr =
290 accessible->get_accState(CreateI4Variant(CHILDID_SELF), &var_state);
291 EXPECT_EQ(hr, S_OK);
292 ASSERT_EQ(VT_I4, V_VT(&var_state));
293 EXPECT_EQ(state_, V_I4(&var_state));
294 }
295
296 void AccessibleChecker::CheckAccessibleChildren(IAccessible* parent) {
297 LONG child_count = 0;
298 HRESULT hr = parent->get_accChildCount(&child_count);
299 EXPECT_EQ(hr, S_OK);
300 ASSERT_EQ(child_count, children_.size());
301
302 auto_ptr<VARIANT> child_array(new VARIANT[child_count]);
303 LONG obtained_count = 0;
304 hr = AccessibleChildren(parent, 0, child_count,
305 child_array.get(), &obtained_count);
306 ASSERT_EQ(hr, S_OK);
307 ASSERT_EQ(child_count, obtained_count);
308
309 VARIANT* child = child_array.get();
310 for (AccessibleCheckerVector::iterator child_checker = children_.begin();
311 child_checker != children_.end();
312 ++child_checker, ++child) {
313 ScopedComPtr<IAccessible> child_accessible;
314 child_accessible.Attach(GetAccessibleFromResultVariant(parent, child));
315 ASSERT_TRUE(child_accessible.get());
316 (*child_checker)->CheckAccessible(child_accessible);
317 }
318 }
319
320 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
321 TestRendererAccessibilityTree) {
322 // The initial accessible returned should have state STATE_SYSTEM_BUSY while
323 // the accessibility tree is being requested from the renderer.
324 AccessibleChecker document1_checker(L"", ROLE_SYSTEM_DOCUMENT, L"");
325 document1_checker.SetExpectedState(
326 STATE_SYSTEM_READONLY | STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_FOCUSED |
327 STATE_SYSTEM_BUSY);
328 document1_checker.CheckAccessible(GetRendererAccessible());
329
330 // Wait for the initial accessibility tree to load. Busy state should clear.
331 ui_test_utils::WaitForNotification(
332 NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
333 document1_checker.SetExpectedState(
334 STATE_SYSTEM_READONLY | STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_FOCUSED);
335 document1_checker.CheckAccessible(GetRendererAccessible());
336
337 GURL tree_url(
338 "data:text/html,<html><head><title>Accessibility Win Test</title></head>"
339 "<body><input type='button' value='push' /><input type='checkbox' />"
340 "</body></html>");
341 browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
342 ui_test_utils::WaitForNotification(
343 NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
344
345 // Check the browser's copy of the renderer accessibility tree.
346 AccessibleChecker button_checker(L"push", ROLE_SYSTEM_PUSHBUTTON, L"push");
347 AccessibleChecker checkbox_checker(L"", ROLE_SYSTEM_CHECKBUTTON, L"");
348 AccessibleChecker body_checker(L"", L"body", L"");
349 AccessibleChecker document2_checker(
350 L"Accessibility Win Test", ROLE_SYSTEM_DOCUMENT, L"");
351 body_checker.AppendExpectedChild(&button_checker);
352 body_checker.AppendExpectedChild(&checkbox_checker);
353 document2_checker.AppendExpectedChild(&body_checker);
354 document2_checker.CheckAccessible(GetRendererAccessible());
355
356 // Check that document accessible has a parent accessible.
357 ScopedComPtr<IAccessible> document_accessible(GetRendererAccessible());
358 ASSERT_NE(document_accessible.get(), reinterpret_cast<IAccessible*>(NULL));
359 ScopedComPtr<IDispatch> parent_dispatch;
360 HRESULT hr = document_accessible->get_accParent(parent_dispatch.Receive());
361 EXPECT_EQ(hr, S_OK);
362 EXPECT_NE(parent_dispatch, reinterpret_cast<IDispatch*>(NULL));
363
364 // Navigate to another page.
365 GURL about_url("about:");
366 ui_test_utils::NavigateToURL(browser(), about_url);
367
368 // Verify that the IAccessible reference still points to a valid object and
369 // that calls to its methods fail since the tree is no longer valid after
370 // the page navagation.
371 CComBSTR name;
372 hr = document_accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);
373 ASSERT_EQ(E_FAIL, hr);
374 }
375
376 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
377 TestNotificationActiveDescendantChanged) {
378 GURL tree_url("data:text/html,<ul tabindex='-1' role='radiogroup'><li id='li'"
379 ">li</li></ul>");
380 browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
381 GetRendererAccessible();
382 ui_test_utils::WaitForNotification(
383 NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
384
385 // Check the browser's copy of the renderer accessibility tree.
386 AccessibleChecker list_marker_checker(L"", ROLE_SYSTEM_LISTITEM, L"\x2022");
387 AccessibleChecker static_text_checker(L"", ROLE_SYSTEM_TEXT, L"li");
388 AccessibleChecker list_item_checker(L"", ROLE_SYSTEM_LISTITEM, L"");
389 list_item_checker.SetExpectedState(
390 STATE_SYSTEM_READONLY);
391 AccessibleChecker radio_group_checker(L"", ROLE_SYSTEM_GROUPING, L"");
392 radio_group_checker.SetExpectedState(
393 STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_READONLY);
394 AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT, L"");
395 list_item_checker.AppendExpectedChild(&list_marker_checker);
396 list_item_checker.AppendExpectedChild(&static_text_checker);
397 radio_group_checker.AppendExpectedChild(&list_item_checker);
398 document_checker.AppendExpectedChild(&radio_group_checker);
399 document_checker.CheckAccessible(GetRendererAccessible());
400
401 // Set focus to the radio group.
402 ExecuteScript(L"document.body.children[0].focus()");
403 ui_test_utils::WaitForNotification(
404 NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
405
406 // Check that the accessibility tree of the browser has been updated.
407 radio_group_checker.SetExpectedState(
408 STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_READONLY | STATE_SYSTEM_FOCUSED);
409 document_checker.CheckAccessible(GetRendererAccessible());
410
411 // Set the active descendant of the radio group
412 ExecuteScript(
413 L"document.body.children[0].setAttribute('aria-activedescendant', 'li')");
414 ui_test_utils::WaitForNotification(
415 NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
416
417 // Check that the accessibility tree of the browser has been updated.
418 list_item_checker.SetExpectedState(
419 STATE_SYSTEM_READONLY | STATE_SYSTEM_FOCUSED);
420 radio_group_checker.SetExpectedState(
421 STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_READONLY);
422 document_checker.CheckAccessible(GetRendererAccessible());
423 }
424
425 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
426 TestNotificationCheckedStateChanged) {
427 GURL tree_url("data:text/html,<body><input type='checkbox' /></body>");
428 browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
429 GetRendererAccessible();
430 ui_test_utils::WaitForNotification(
431 NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
432
433 // Check the browser's copy of the renderer accessibility tree.
434 AccessibleChecker checkbox_checker(L"", ROLE_SYSTEM_CHECKBUTTON, L"");
435 checkbox_checker.SetExpectedState(
436 STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_READONLY);
437 AccessibleChecker body_checker(L"", L"body", L"");
438 AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT, L"");
439 body_checker.AppendExpectedChild(&checkbox_checker);
440 document_checker.AppendExpectedChild(&body_checker);
441 document_checker.CheckAccessible(GetRendererAccessible());
442
443 // Check the checkbox.
444 ExecuteScript(L"document.body.children[0].checked=true");
445 ui_test_utils::WaitForNotification(
446 NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
447
448 // Check that the accessibility tree of the browser has been updated.
449 checkbox_checker.SetExpectedState(
450 STATE_SYSTEM_CHECKED | STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_READONLY);
451 document_checker.CheckAccessible(GetRendererAccessible());
452 }
453
454 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
455 TestNotificationChildrenChanged) {
456 // The role attribute causes the node to be in the accessibility tree.
457 GURL tree_url(
458 "data:text/html,<body role=group></body>");
459 browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
460 GetRendererAccessible();
461 ui_test_utils::WaitForNotification(
462 NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
463
464 // Check the browser's copy of the renderer accessibility tree.
465 AccessibleChecker body_checker(L"", L"body", L"");
466 AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT, L"");
467 document_checker.AppendExpectedChild(&body_checker);
468 document_checker.CheckAccessible(GetRendererAccessible());
469
470 // Change the children of the document body.
471 ExecuteScript(L"document.body.innerHTML='<b>new text</b>'");
472 ui_test_utils::WaitForNotification(
473 NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
474
475 // Check that the accessibility tree of the browser has been updated.
476 AccessibleChecker text_checker(L"", ROLE_SYSTEM_TEXT, L"new text");
477 body_checker.AppendExpectedChild(&text_checker);
478 document_checker.CheckAccessible(GetRendererAccessible());
479 }
480
481 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
482 TestNotificationFocusChanged) {
483 // The role attribute causes the node to be in the accessibility tree.
484 GURL tree_url(
485 "data:text/html,<div role=group tabindex='-1'></div>");
486 browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
487 GetRendererAccessible();
488 ui_test_utils::WaitForNotification(
489 NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
490
491 // Check the browser's copy of the renderer accessibility tree.
492 AccessibleChecker div_checker(L"", L"div", L"");
493 div_checker.SetExpectedState(
494 STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_OFFSCREEN | STATE_SYSTEM_READONLY);
495 AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT, L"");
496 document_checker.AppendExpectedChild(&div_checker);
497 document_checker.CheckAccessible(GetRendererAccessible());
498
499 // Focus the div in the document
500 ExecuteScript(L"document.body.children[0].focus()");
501 ui_test_utils::WaitForNotification(
502 NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
503
504 // Check that the accessibility tree of the browser has been updated.
505 div_checker.SetExpectedState(
506 STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_READONLY | STATE_SYSTEM_FOCUSED);
507 document_checker.CheckAccessible(GetRendererAccessible());
508
509 // TODO(ctguil): The renderer should notify the browser when focus is cleared.
510 // Uncomment code below when fixed.
511 // Focus the document accessible. This will un-focus the current node.
512 // http://crbug.com/57045
513 ScopedComPtr<IAccessible> document_accessible(GetRendererAccessible());
514 ASSERT_NE(document_accessible.get(), reinterpret_cast<IAccessible*>(NULL));
515 HRESULT hr = document_accessible->accSelect(
516 SELFLAG_TAKEFOCUS, CreateI4Variant(CHILDID_SELF));
517 ASSERT_EQ(hr, S_OK);
518 // ui_test_utils::WaitForNotification(
519 // NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
520
521 // Check that the accessibility tree of the browser has been updated.
522 // div_checker.SetExpectedState(
523 // STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_READONLY);
524 // document_checker.CheckAccessible(GetRendererAccessible());
525 }
526
527 // http://crbug.com/46209
528 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
529 DISABLED_TestNotificationChildrenChanged2) {
530 // The role attribute causes the node to be in the accessibility tree.
531 GURL tree_url(
532 "data:text/html,<div role=group style='visibility: hidden'>text"
533 "</div>");
534 browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
535 GetRendererAccessible();
536 ui_test_utils::WaitForNotification(
537 NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
538
539 // Check the accessible tree of the browser.
540 AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT, L"");
541 document_checker.CheckAccessible(GetRendererAccessible());
542
543 // Change the children of the document body.
544 ExecuteScript(L"document.body.children[0].style.visibility='visible'");
545 ui_test_utils::WaitForNotification(
546 NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
547
548 // Check that the accessibility tree of the browser has been updated.
549 AccessibleChecker static_text_checker(L"", ROLE_SYSTEM_TEXT, L"text");
550 AccessibleChecker div_checker(L"", L"div", L"");
551 document_checker.AppendExpectedChild(&div_checker);
552 div_checker.AppendExpectedChild(&static_text_checker);
553 document_checker.CheckAccessible(GetRendererAccessible());
554 }
555
556 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
557 TestNotificationValueChanged) {
558 GURL tree_url("data:text/html,<body><input type='text' value='old value'/>"
559 "</body>");
560 browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
561 GetRendererAccessible();
562 ui_test_utils::WaitForNotification(
563 NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
564
565 // Check the browser's copy of the renderer accessibility tree.
566 AccessibleChecker static_text_checker(L"", ROLE_SYSTEM_TEXT, L"old value");
567 AccessibleChecker text_field_div_checker(L"", L"div", L"");
568 AccessibleChecker text_field_checker(L"", ROLE_SYSTEM_TEXT, L"old value");
569 text_field_checker.SetExpectedState(STATE_SYSTEM_FOCUSABLE);
570 AccessibleChecker body_checker(L"", L"body", L"");
571 AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT, L"");
572 text_field_div_checker.AppendExpectedChild(&static_text_checker);
573 text_field_checker.AppendExpectedChild(&text_field_div_checker);
574 body_checker.AppendExpectedChild(&text_field_checker);
575 document_checker.AppendExpectedChild(&body_checker);
576 document_checker.CheckAccessible(GetRendererAccessible());
577
578 // Set the value of the text control
579 ExecuteScript(L"document.body.children[0].value='new value'");
580 ui_test_utils::WaitForNotification(
581 NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
582
583 // Check that the accessibility tree of the browser has been updated.
584 text_field_checker.SetExpectedValue(L"new value");
585 static_text_checker.SetExpectedValue(L"new value");
586 document_checker.CheckAccessible(GetRendererAccessible());
587 }
588
589 // FAILS crbug.com/54220
590 // This test verifies that browser-side cache of the renderer accessibility
591 // tree is reachable from the browser's tree. Tools that analyze windows
592 // accessibility trees like AccExplorer32 should be able to drill into the
593 // cached renderer accessibility tree.
594 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
595 DISABLED_ContainsRendererAccessibilityTree) {
596 GURL tree_url("data:text/html,<body><input type='checkbox' /></body>");
597 browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
598 GetRendererAccessible();
599 ui_test_utils::WaitForNotification(
600 NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
601
602 // Get the accessibility object for the browser window.
603 HWND browser_hwnd = browser()->window()->GetNativeHandle();
604 ScopedComPtr<IAccessible> browser_accessible;
605 HRESULT hr = AccessibleObjectFromWindow(
606 browser_hwnd,
607 OBJID_WINDOW,
608 IID_IAccessible,
609 reinterpret_cast<void**>(browser_accessible.Receive()));
610 ASSERT_EQ(S_OK, hr);
611
612 // Get the accessibility object for the renderer client document.
613 ScopedComPtr<IAccessible> document_accessible(GetRendererAccessible());
614 ASSERT_NE(document_accessible.get(), reinterpret_cast<IAccessible*>(NULL));
615 ScopedComPtr<IAccessible2> document_accessible2;
616 hr = QueryIAccessible2(document_accessible, document_accessible2.Receive());
617 ASSERT_EQ(S_OK, hr);
618
619 // TODO(ctguil): Pointer comparison of retrieved IAccessible pointers dosen't
620 // seem to work for here. Perhaps make IAccessible2 available in views to make
621 // unique id comparison available.
622 bool found = false;
623 ScopedComPtr<IAccessible> parent = document_accessible;
624 while (parent.get()) {
625 ScopedComPtr<IDispatch> parent_dispatch;
626 hr = parent->get_accParent(parent_dispatch.Receive());
627 ASSERT_TRUE(SUCCEEDED(hr));
628 if (!parent_dispatch.get()) {
629 ASSERT_EQ(hr, S_FALSE);
630 break;
631 }
632
633 parent.Release();
634 hr = parent_dispatch.QueryInterface(parent.Receive());
635 ASSERT_EQ(S_OK, hr);
636
637 if (parent.get() == browser_accessible.get()) {
638 found = true;
639 break;
640 }
641 }
642
643 // If pointer comparison fails resort to the exhuasive search that can use
644 // IAccessible2::get_uniqueID for equality comparison.
645 if (!found) {
646 AccessibleContainsAccessible(
647 browser_accessible, document_accessible2, &found);
648 }
649
650 ASSERT_EQ(found, true);
651 }
652 } // namespace.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698