| Index: chrome/browser/accessibility/accessibility_win_browsertest.cc
|
| ===================================================================
|
| --- chrome/browser/accessibility/accessibility_win_browsertest.cc (revision 88807)
|
| +++ chrome/browser/accessibility/accessibility_win_browsertest.cc (working copy)
|
| @@ -6,6 +6,7 @@
|
| #include <vector>
|
|
|
| #include "base/memory/scoped_ptr.h"
|
| +#include "base/utf_string_conversions.h"
|
| #include "base/win/scoped_comptr.h"
|
| #include "chrome/browser/automation/ui_controls.h"
|
| #include "chrome/browser/renderer_host/render_widget_host_view_win.h"
|
| @@ -136,54 +137,53 @@
|
| return hr;
|
| }
|
|
|
| -// Sets result to true if the child is located in the parent's tree. An
|
| -// exhustive search is perform here because we determine equality using
|
| -// IAccessible2::get_unique_id which is only supported by the child node.
|
| -void AccessibleContainsAccessible(
|
| - IAccessible* parent, IAccessible2* child, bool* result) {
|
| - vector<base::win::ScopedComPtr<IAccessible>> accessible_list;
|
| - accessible_list.push_back(base::win::ScopedComPtr<IAccessible>(parent));
|
| +// Recursively search through all of the descendants reachable from an
|
| +// IAccessible node and return true if we find one with the given role
|
| +// and name.
|
| +void RecursiveFindNodeInAccessibilityTree(
|
| + IAccessible* node,
|
| + int32 expected_role,
|
| + const wstring& expected_name,
|
| + int32 depth,
|
| + bool* found) {
|
| + CComBSTR name_bstr;
|
| + node->get_accName(CreateI4Variant(CHILDID_SELF), &name_bstr);
|
| + wstring name(name_bstr.m_str, SysStringLen(name_bstr));
|
| + VARIANT role = {0};
|
| + node->get_accRole(CreateI4Variant(CHILDID_SELF), &role);
|
|
|
| - LONG unique_id;
|
| - HRESULT hr = child->get_uniqueID(&unique_id);
|
| - ASSERT_EQ(S_OK, hr);
|
| - *result = false;
|
| + // Print the accessibility tree as we go, because if this test fails
|
| + // on the bots, this is really helpful in figuring out why.
|
| + for (int i = 0; i < depth; i++) {
|
| + printf(" ");
|
| + }
|
| + printf("role=%d name=%s\n", role.lVal, WideToUTF8(name).c_str());
|
|
|
| - while (accessible_list.size()) {
|
| - base::win::ScopedComPtr<IAccessible> accessible = accessible_list.back();
|
| - accessible_list.pop_back();
|
| + if (expected_role == role.lVal && expected_name == name) {
|
| + *found = true;
|
| + return;
|
| + }
|
|
|
| - base::win::ScopedComPtr<IAccessible2> accessible2;
|
| - hr = QueryIAccessible2(accessible, accessible2.Receive());
|
| - if (SUCCEEDED(hr)) {
|
| - LONG child_id;
|
| - accessible2->get_uniqueID(&child_id);
|
| - if (child_id == unique_id) {
|
| - *result = true;
|
| - break;
|
| - }
|
| - }
|
| + LONG child_count = 0;
|
| + HRESULT hr = node->get_accChildCount(&child_count);
|
| + ASSERT_EQ(S_OK, hr);
|
|
|
| - LONG child_count;
|
| - hr = accessible->get_accChildCount(&child_count);
|
| - ASSERT_EQ(S_OK, hr);
|
| - if (child_count == 0)
|
| - continue;
|
| + scoped_array<VARIANT> child_array(new VARIANT[child_count]);
|
| + LONG obtained_count = 0;
|
| + hr = AccessibleChildren(
|
| + node, 0, child_count, child_array.get(), &obtained_count);
|
| + ASSERT_EQ(S_OK, hr);
|
| + ASSERT_EQ(child_count, obtained_count);
|
|
|
| - scoped_array<VARIANT> child_array(new VARIANT[child_count]);
|
| - LONG obtained_count = 0;
|
| - hr = AccessibleChildren(
|
| - accessible, 0, child_count, child_array.get(), &obtained_count);
|
| - ASSERT_EQ(S_OK, hr);
|
| - ASSERT_EQ(child_count, obtained_count);
|
| -
|
| - for (int index = 0; index < obtained_count; index++) {
|
| - base::win::ScopedComPtr<IAccessible> child_accessible(
|
| - GetAccessibleFromResultVariant(accessible, &child_array.get()[index]));
|
| - if (child_accessible.get()) {
|
| - accessible_list.push_back(
|
| - base::win::ScopedComPtr<IAccessible>(child_accessible));
|
| - }
|
| + for (int index = 0; index < obtained_count; index++) {
|
| + base::win::ScopedComPtr<IAccessible> child_accessible(
|
| + GetAccessibleFromResultVariant(node, &child_array.get()[index]));
|
| + if (child_accessible.get()) {
|
| + RecursiveFindNodeInAccessibilityTree(
|
| + child_accessible.get(), expected_role, expected_name, depth + 1,
|
| + found);
|
| + if (*found)
|
| + return;
|
| }
|
| }
|
| }
|
| @@ -589,14 +589,18 @@
|
| document_checker.CheckAccessible(GetRendererAccessible());
|
| }
|
|
|
| -// FAILS crbug.com/54220
|
| -// This test verifies that browser-side cache of the renderer accessibility
|
| -// tree is reachable from the browser's tree. Tools that analyze windows
|
| -// accessibility trees like AccExplorer32 should be able to drill into the
|
| -// cached renderer accessibility tree.
|
| +// This test verifies that the web content's accessibility tree is a
|
| +// descendant of the main browser window's accessibility tree, so that
|
| +// tools like AccExplorer32 or AccProbe can be used to examine Chrome's
|
| +// accessibility support.
|
| +//
|
| +// If you made a change and this test now fails, check that the NativeViewHost
|
| +// that wraps the tab contents returns the IAccessible implementation
|
| +// provided by RenderWidgetHostViewWin in GetNativeViewAccessible().
|
| IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
|
| - DISABLED_ContainsRendererAccessibilityTree) {
|
| - GURL tree_url("data:text/html,<body><input type='checkbox' /></body>");
|
| + ContainsRendererAccessibilityTree) {
|
| + GURL tree_url("data:text/html,<html><head><title>MyDocument</title></head>"
|
| + "<body>Content</body></html>");
|
| browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
|
| GetRendererAccessible();
|
| ui_test_utils::WaitForNotification(
|
| @@ -612,45 +616,9 @@
|
| reinterpret_cast<void**>(browser_accessible.Receive()));
|
| ASSERT_EQ(S_OK, hr);
|
|
|
| - // Get the accessibility object for the renderer client document.
|
| - base::win::ScopedComPtr<IAccessible> document_accessible(
|
| - GetRendererAccessible());
|
| - ASSERT_NE(document_accessible.get(), reinterpret_cast<IAccessible*>(NULL));
|
| - base::win::ScopedComPtr<IAccessible2> document_accessible2;
|
| - hr = QueryIAccessible2(document_accessible, document_accessible2.Receive());
|
| - ASSERT_EQ(S_OK, hr);
|
| -
|
| - // TODO(ctguil): Pointer comparison of retrieved IAccessible pointers dosen't
|
| - // seem to work for here. Perhaps make IAccessible2 available in views to make
|
| - // unique id comparison available.
|
| bool found = false;
|
| - base::win::ScopedComPtr<IAccessible> parent = document_accessible;
|
| - while (parent.get()) {
|
| - base::win::ScopedComPtr<IDispatch> parent_dispatch;
|
| - hr = parent->get_accParent(parent_dispatch.Receive());
|
| - ASSERT_TRUE(SUCCEEDED(hr));
|
| - if (!parent_dispatch.get()) {
|
| - ASSERT_EQ(hr, S_FALSE);
|
| - break;
|
| - }
|
| -
|
| - parent.Release();
|
| - hr = parent_dispatch.QueryInterface(parent.Receive());
|
| - ASSERT_EQ(S_OK, hr);
|
| -
|
| - if (parent.get() == browser_accessible.get()) {
|
| - found = true;
|
| - break;
|
| - }
|
| - }
|
| -
|
| - // If pointer comparison fails resort to the exhuasive search that can use
|
| - // IAccessible2::get_unique_id for equality comparison.
|
| - if (!found) {
|
| - AccessibleContainsAccessible(
|
| - browser_accessible, document_accessible2, &found);
|
| - }
|
| -
|
| + RecursiveFindNodeInAccessibilityTree(
|
| + browser_accessible.get(), ROLE_SYSTEM_DOCUMENT, L"MyDocument", 0, &found);
|
| ASSERT_EQ(found, true);
|
| }
|
|
|
|
|