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

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

Issue 6995126: Make web content accessibility tree a descendant of main window's tree again (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | chrome/browser/accessibility/browser_views_accessibility_browsertest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 <atlbase.h> 5 #include <atlbase.h>
6 #include <vector> 6 #include <vector>
7 7
8 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "base/utf_string_conversions.h"
9 #include "base/win/scoped_comptr.h" 10 #include "base/win/scoped_comptr.h"
10 #include "chrome/browser/automation/ui_controls.h" 11 #include "chrome/browser/automation/ui_controls.h"
11 #include "chrome/browser/renderer_host/render_widget_host_view_win.h" 12 #include "chrome/browser/renderer_host/render_widget_host_view_win.h"
12 #include "chrome/browser/ui/browser.h" 13 #include "chrome/browser/ui/browser.h"
13 #include "chrome/browser/ui/browser_window.h" 14 #include "chrome/browser/ui/browser_window.h"
14 #include "chrome/common/url_constants.h" 15 #include "chrome/common/url_constants.h"
15 #include "chrome/test/in_process_browser_test.h" 16 #include "chrome/test/in_process_browser_test.h"
16 #include "chrome/test/ui_test_utils.h" 17 #include "chrome/test/ui_test_utils.h"
17 #include "content/browser/renderer_host/render_view_host.h" 18 #include "content/browser/renderer_host/render_view_host.h"
18 #include "content/browser/tab_contents/tab_contents.h" 19 #include "content/browser/tab_contents/tab_contents.h"
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 // IAccessible fails. 130 // IAccessible fails.
130 base::win::ScopedComPtr<IServiceProvider> service_provider; 131 base::win::ScopedComPtr<IServiceProvider> service_provider;
131 HRESULT hr = accessible->QueryInterface(service_provider.Receive()); 132 HRESULT hr = accessible->QueryInterface(service_provider.Receive());
132 if (FAILED(hr)) 133 if (FAILED(hr))
133 return hr; 134 return hr;
134 135
135 hr = service_provider->QueryService(IID_IAccessible2, accessible2); 136 hr = service_provider->QueryService(IID_IAccessible2, accessible2);
136 return hr; 137 return hr;
137 } 138 }
138 139
139 // Sets result to true if the child is located in the parent's tree. An 140 // Recursively search through all of the descendants reachable from an
140 // exhustive search is perform here because we determine equality using 141 // IAccessible node and return true if we find one with the given role
141 // IAccessible2::get_unique_id which is only supported by the child node. 142 // and name.
142 void AccessibleContainsAccessible( 143 void RecursiveFindNodeInAccessibilityTree(
143 IAccessible* parent, IAccessible2* child, bool* result) { 144 IAccessible* node,
144 vector<base::win::ScopedComPtr<IAccessible>> accessible_list; 145 int32 expected_role,
145 accessible_list.push_back(base::win::ScopedComPtr<IAccessible>(parent)); 146 const wstring& expected_name,
147 int32 depth,
148 bool* found) {
149 CComBSTR name_bstr;
150 node->get_accName(CreateI4Variant(CHILDID_SELF), &name_bstr);
151 wstring name(name_bstr.m_str, SysStringLen(name_bstr));
152 VARIANT role = {0};
153 node->get_accRole(CreateI4Variant(CHILDID_SELF), &role);
146 154
147 LONG unique_id; 155 // Print the accessibility tree as we go, because if this test fails
148 HRESULT hr = child->get_uniqueID(&unique_id); 156 // on the bots, this is really helpful in figuring out why.
157 for (int i = 0; i < depth; i++) {
158 printf(" ");
159 }
160 printf("role=%d name=%s\n", role.lVal, WideToUTF8(name).c_str());
161
162 if (expected_role == role.lVal && expected_name == name) {
163 *found = true;
164 return;
165 }
166
167 LONG child_count = 0;
168 HRESULT hr = node->get_accChildCount(&child_count);
149 ASSERT_EQ(S_OK, hr); 169 ASSERT_EQ(S_OK, hr);
150 *result = false;
151 170
152 while (accessible_list.size()) { 171 scoped_array<VARIANT> child_array(new VARIANT[child_count]);
153 base::win::ScopedComPtr<IAccessible> accessible = accessible_list.back(); 172 LONG obtained_count = 0;
154 accessible_list.pop_back(); 173 hr = AccessibleChildren(
174 node, 0, child_count, child_array.get(), &obtained_count);
175 ASSERT_EQ(S_OK, hr);
176 ASSERT_EQ(child_count, obtained_count);
155 177
156 base::win::ScopedComPtr<IAccessible2> accessible2; 178 for (int index = 0; index < obtained_count; index++) {
157 hr = QueryIAccessible2(accessible, accessible2.Receive()); 179 base::win::ScopedComPtr<IAccessible> child_accessible(
158 if (SUCCEEDED(hr)) { 180 GetAccessibleFromResultVariant(node, &child_array.get()[index]));
159 LONG child_id; 181 if (child_accessible.get()) {
160 accessible2->get_uniqueID(&child_id); 182 RecursiveFindNodeInAccessibilityTree(
161 if (child_id == unique_id) { 183 child_accessible.get(), expected_role, expected_name, depth + 1,
162 *result = true; 184 found);
163 break; 185 if (*found)
164 } 186 return;
165 }
166
167 LONG child_count;
168 hr = accessible->get_accChildCount(&child_count);
169 ASSERT_EQ(S_OK, hr);
170 if (child_count == 0)
171 continue;
172
173 scoped_array<VARIANT> child_array(new VARIANT[child_count]);
174 LONG obtained_count = 0;
175 hr = AccessibleChildren(
176 accessible, 0, child_count, child_array.get(), &obtained_count);
177 ASSERT_EQ(S_OK, hr);
178 ASSERT_EQ(child_count, obtained_count);
179
180 for (int index = 0; index < obtained_count; index++) {
181 base::win::ScopedComPtr<IAccessible> child_accessible(
182 GetAccessibleFromResultVariant(accessible, &child_array.get()[index]));
183 if (child_accessible.get()) {
184 accessible_list.push_back(
185 base::win::ScopedComPtr<IAccessible>(child_accessible));
186 }
187 } 187 }
188 } 188 }
189 } 189 }
190 190
191 // Retrieve the MSAA client accessibility object for the Render Widget Host View 191 // Retrieve the MSAA client accessibility object for the Render Widget Host View
192 // of the selected tab. 192 // of the selected tab.
193 IAccessible* 193 IAccessible*
194 AccessibilityWinBrowserTest::GetRendererAccessible() { 194 AccessibilityWinBrowserTest::GetRendererAccessible() {
195 HWND hwnd_render_widget_host_view = 195 HWND hwnd_render_widget_host_view =
196 browser()->GetSelectedTabContents()->GetRenderWidgetHostView()-> 196 browser()->GetSelectedTabContents()->GetRenderWidgetHostView()->
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 // Set the value of the text control 582 // Set the value of the text control
583 ExecuteScript(L"document.body.children[0].value='new value'"); 583 ExecuteScript(L"document.body.children[0].value='new value'");
584 ui_test_utils::WaitForNotification( 584 ui_test_utils::WaitForNotification(
585 NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED); 585 NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
586 586
587 // Check that the accessibility tree of the browser has been updated. 587 // Check that the accessibility tree of the browser has been updated.
588 text_field_checker.SetExpectedValue(L"new value"); 588 text_field_checker.SetExpectedValue(L"new value");
589 document_checker.CheckAccessible(GetRendererAccessible()); 589 document_checker.CheckAccessible(GetRendererAccessible());
590 } 590 }
591 591
592 // FAILS crbug.com/54220 592 // This test verifies that the web content's accessibility tree is a
593 // This test verifies that browser-side cache of the renderer accessibility 593 // descendant of the main browser window's accessibility tree, so that
594 // tree is reachable from the browser's tree. Tools that analyze windows 594 // tools like AccExplorer32 or AccProbe can be used to examine Chrome's
595 // accessibility trees like AccExplorer32 should be able to drill into the 595 // accessibility support.
596 // cached renderer accessibility tree. 596 //
597 // If you made a change and this test now fails, check that the NativeViewHost
598 // that wraps the tab contents returns the IAccessible implementation
599 // provided by RenderWidgetHostViewWin in GetNativeViewAccessible().
597 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, 600 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
598 DISABLED_ContainsRendererAccessibilityTree) { 601 ContainsRendererAccessibilityTree) {
599 GURL tree_url("data:text/html,<body><input type='checkbox' /></body>"); 602 GURL tree_url("data:text/html,<html><head><title>MyDocument</title></head>"
603 "<body>Content</body></html>");
600 browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED); 604 browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
601 GetRendererAccessible(); 605 GetRendererAccessible();
602 ui_test_utils::WaitForNotification( 606 ui_test_utils::WaitForNotification(
603 NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED); 607 NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
604 608
605 // Get the accessibility object for the browser window. 609 // Get the accessibility object for the browser window.
606 HWND browser_hwnd = browser()->window()->GetNativeHandle(); 610 HWND browser_hwnd = browser()->window()->GetNativeHandle();
607 base::win::ScopedComPtr<IAccessible> browser_accessible; 611 base::win::ScopedComPtr<IAccessible> browser_accessible;
608 HRESULT hr = AccessibleObjectFromWindow( 612 HRESULT hr = AccessibleObjectFromWindow(
609 browser_hwnd, 613 browser_hwnd,
610 OBJID_WINDOW, 614 OBJID_WINDOW,
611 IID_IAccessible, 615 IID_IAccessible,
612 reinterpret_cast<void**>(browser_accessible.Receive())); 616 reinterpret_cast<void**>(browser_accessible.Receive()));
613 ASSERT_EQ(S_OK, hr); 617 ASSERT_EQ(S_OK, hr);
614 618
615 // Get the accessibility object for the renderer client document.
616 base::win::ScopedComPtr<IAccessible> document_accessible(
617 GetRendererAccessible());
618 ASSERT_NE(document_accessible.get(), reinterpret_cast<IAccessible*>(NULL));
619 base::win::ScopedComPtr<IAccessible2> document_accessible2;
620 hr = QueryIAccessible2(document_accessible, document_accessible2.Receive());
621 ASSERT_EQ(S_OK, hr);
622
623 // TODO(ctguil): Pointer comparison of retrieved IAccessible pointers dosen't
624 // seem to work for here. Perhaps make IAccessible2 available in views to make
625 // unique id comparison available.
626 bool found = false; 619 bool found = false;
627 base::win::ScopedComPtr<IAccessible> parent = document_accessible; 620 RecursiveFindNodeInAccessibilityTree(
628 while (parent.get()) { 621 browser_accessible.get(), ROLE_SYSTEM_DOCUMENT, L"MyDocument", 0, &found);
629 base::win::ScopedComPtr<IDispatch> parent_dispatch;
630 hr = parent->get_accParent(parent_dispatch.Receive());
631 ASSERT_TRUE(SUCCEEDED(hr));
632 if (!parent_dispatch.get()) {
633 ASSERT_EQ(hr, S_FALSE);
634 break;
635 }
636
637 parent.Release();
638 hr = parent_dispatch.QueryInterface(parent.Receive());
639 ASSERT_EQ(S_OK, hr);
640
641 if (parent.get() == browser_accessible.get()) {
642 found = true;
643 break;
644 }
645 }
646
647 // If pointer comparison fails resort to the exhuasive search that can use
648 // IAccessible2::get_unique_id for equality comparison.
649 if (!found) {
650 AccessibleContainsAccessible(
651 browser_accessible, document_accessible2, &found);
652 }
653
654 ASSERT_EQ(found, true); 622 ASSERT_EQ(found, true);
655 } 623 }
656 624
657 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, 625 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
658 SupportsISimpleDOM) { 626 SupportsISimpleDOM) {
659 GURL tree_url("data:text/html,<body><input type='checkbox' /></body>"); 627 GURL tree_url("data:text/html,<body><input type='checkbox' /></body>");
660 browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED); 628 browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
661 GetRendererAccessible(); 629 GetRendererAccessible();
662 ui_test_utils::WaitForNotification( 630 ui_test_utils::WaitForNotification(
663 NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED); 631 NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
711 ASSERT_EQ(S_OK, hr); 679 ASSERT_EQ(S_OK, hr);
712 hr = checkbox_isimpledomnode->get_nodeInfo( 680 hr = checkbox_isimpledomnode->get_nodeInfo(
713 &node_name, &name_space_id, &node_value, &num_children, &unique_id, 681 &node_name, &name_space_id, &node_value, &num_children, &unique_id,
714 &node_type); 682 &node_type);
715 ASSERT_EQ(S_OK, hr); 683 ASSERT_EQ(S_OK, hr);
716 EXPECT_STREQ(L"input", wstring(node_name, SysStringLen(node_name)).c_str()); 684 EXPECT_STREQ(L"input", wstring(node_name, SysStringLen(node_name)).c_str());
717 EXPECT_EQ(NODETYPE_ELEMENT, node_type); 685 EXPECT_EQ(NODETYPE_ELEMENT, node_type);
718 EXPECT_EQ(0, num_children); 686 EXPECT_EQ(0, num_children);
719 } 687 }
720 } // namespace. 688 } // namespace.
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/accessibility/browser_views_accessibility_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698