summaryrefslogtreecommitdiffstats
path: root/chrome/browser/accessibility_win_browsertest.cc
diff options
context:
space:
mode:
authorctguil@chromium.org <ctguil@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-03 17:33:14 +0000
committerctguil@chromium.org <ctguil@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-03 17:33:14 +0000
commitb953062aec66a8c20fbbc50396c23fac2696ef1d (patch)
treed207c629950ce4daaa3e174f4f31486dd9522c73 /chrome/browser/accessibility_win_browsertest.cc
parent9deebf20b712a0b1701a3d508a4a85528e05486e (diff)
downloadchromium_src-b953062aec66a8c20fbbc50396c23fac2696ef1d.zip
chromium_src-b953062aec66a8c20fbbc50396c23fac2696ef1d.tar.gz
chromium_src-b953062aec66a8c20fbbc50396c23fac2696ef1d.tar.bz2
Add browser test to verify that MSAA clients can correctly retrieve accessibility tree from renderer.
BUG=none TEST=none Review URL: http://codereview.chromium.org/1806001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@46238 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/accessibility_win_browsertest.cc')
-rw-r--r--chrome/browser/accessibility_win_browsertest.cc222
1 files changed, 222 insertions, 0 deletions
diff --git a/chrome/browser/accessibility_win_browsertest.cc b/chrome/browser/accessibility_win_browsertest.cc
new file mode 100644
index 0000000..1fc03a1
--- /dev/null
+++ b/chrome/browser/accessibility_win_browsertest.cc
@@ -0,0 +1,222 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <atlbase.h>
+#include <vector>
+
+#include "base/file_path.h"
+#include "base/scoped_comptr_win.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_window.h"
+#include "chrome/browser/renderer_host/render_widget_host_view_win.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/test/in_process_browser_test.h"
+#include "chrome/test/ui_test_utils.h"
+
+namespace {
+
+class AccessibilityWinBrowserTest : public InProcessBrowserTest {
+ public:
+ void SetUpCommandLine(CommandLine* command_line) {
+ // Turns on the accessibility in the renderer. Off by default until
+ // http://b/issue?id=1432077 is fixed.
+ command_line->AppendSwitch(switches::kEnableRendererAccessibility);
+ }
+
+ protected:
+ IAccessible* GetRenderWidgetHostViewClientAccessible();
+};
+
+class AccessibleChecker {
+ public:
+ AccessibleChecker(std::wstring expected_name, int32 expected_role);
+
+ // Append an AccessibleChecker that verifies accessibility information for
+ // a child IAccessible. Order is important.
+ void AppendExpectedChild(AccessibleChecker* expected_child);
+
+ // Check that the name and role of the given IAccessible instance and its
+ // descendants match the expected names and roles that this object was
+ // initialized with.
+ void CheckAccessible(IAccessible* accessible);
+
+ typedef std::vector<AccessibleChecker*> AccessibleCheckerVector;
+
+ private:
+ void CheckAccessibleName(IAccessible* accessible);
+ void CheckAccessibleRole(IAccessible* accessible);
+ void CheckAccessibleChildren(IAccessible* accessible);
+
+ private:
+ // Expected accessible name. Checked against IAccessible::get_accName.
+ std::wstring name_;
+
+ // Expected accessible role. Checked against IAccessible::get_accRole.
+ int32 role_;
+
+ // Expected accessible children. Checked using IAccessible::get_accChildCount
+ // and ::AccessibleChildren.
+ AccessibleCheckerVector children_;
+};
+
+VARIANT CreateI4Variant(LONG value) {
+ VARIANT variant = {0};
+
+ V_VT(&variant) = VT_I4;
+ V_I4(&variant) = value;
+
+ return variant;
+}
+
+IAccessible* GetAccessibleFromResultVariant(IAccessible* parent, VARIANT *var) {
+ switch (V_VT(var)) {
+ case VT_DISPATCH:
+ return CComQIPtr<IAccessible>(V_DISPATCH(var)).Detach();
+ break;
+
+ case VT_I4: {
+ CComPtr<IDispatch> dispatch;
+ HRESULT hr = parent->get_accChild(CreateI4Variant(V_I4(var)), &dispatch);
+ EXPECT_EQ(hr, S_OK);
+ return CComQIPtr<IAccessible>(dispatch).Detach();
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+// Retrieve the MSAA client accessibility object for the Render Widget Host View
+// of the selected tab.
+IAccessible*
+AccessibilityWinBrowserTest::GetRenderWidgetHostViewClientAccessible() {
+ HWND hwnd_render_widget_host_view =
+ browser()->GetSelectedTabContents()->GetRenderWidgetHostView()->
+ GetNativeView();
+
+ IAccessible* accessible;
+ HRESULT hr = AccessibleObjectFromWindow(
+ hwnd_render_widget_host_view, OBJID_CLIENT,
+ IID_IAccessible, reinterpret_cast<void**>(&accessible));
+ EXPECT_EQ(S_OK, hr);
+ EXPECT_NE(accessible, reinterpret_cast<IAccessible*>(NULL));
+
+ return accessible;
+}
+
+AccessibleChecker::AccessibleChecker(
+ std::wstring expected_name, int32 expected_role) :
+ name_(expected_name),
+ role_(expected_role) {
+}
+
+void AccessibleChecker::AppendExpectedChild(
+ AccessibleChecker* expected_child) {
+ children_.push_back(expected_child);
+}
+
+void AccessibleChecker::CheckAccessible(IAccessible* accessible) {
+ CheckAccessibleName(accessible);
+ CheckAccessibleRole(accessible);
+ CheckAccessibleChildren(accessible);
+}
+
+void AccessibleChecker::CheckAccessibleName(IAccessible* accessible) {
+ CComBSTR name;
+ HRESULT hr =
+ accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);
+
+ if (name_.empty()) {
+ // If the object doesn't have name S_FALSE should be returned.
+ EXPECT_EQ(hr, S_FALSE);
+ } else {
+ // Test that the correct string was returned.
+ EXPECT_EQ(hr, S_OK);
+ EXPECT_EQ(CompareString(LOCALE_NEUTRAL, 0, name, SysStringLen(name),
+ name_.c_str(), name_.length()),
+ CSTR_EQUAL);
+ }
+}
+
+void AccessibleChecker::CheckAccessibleRole(IAccessible* accessible) {
+ VARIANT var_role = {0};
+ HRESULT hr =
+ accessible->get_accRole(CreateI4Variant(CHILDID_SELF), &var_role);
+ EXPECT_EQ(hr, S_OK);
+ EXPECT_EQ(V_VT(&var_role), VT_I4);
+ EXPECT_EQ(V_I4(&var_role), role_);
+}
+
+void AccessibleChecker::CheckAccessibleChildren(IAccessible* parent) {
+ LONG child_count = 0;
+ HRESULT hr = parent->get_accChildCount(&child_count);
+ EXPECT_EQ(hr, S_OK);
+ ASSERT_EQ(child_count, children_.size());
+
+ std::auto_ptr<VARIANT> child_array(new VARIANT[child_count]);
+ LONG obtained_count = 0;
+ hr = AccessibleChildren(parent, 0, child_count,
+ child_array.get(), &obtained_count);
+ ASSERT_EQ(hr, S_OK);
+ ASSERT_EQ(child_count, obtained_count);
+
+ VARIANT* child = child_array.get();
+ for (AccessibleCheckerVector::iterator child_checker = children_.begin();
+ child_checker != children_.end();
+ ++child_checker, ++child) {
+ ScopedComPtr<IAccessible> child_accessible;
+ child_accessible.Attach(GetAccessibleFromResultVariant(parent, child));
+ (*child_checker)->CheckAccessible(child_accessible);
+ }
+}
+
+IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
+ TestRendererAccessibilityTree) {
+ GURL tree_url(
+ "data:text/html,<html><head><title>Accessibility Win Test</title></head>"
+ "<body><input type='button' value='push' /><input type='checkbox' />"
+ "</body></html>");
+ ui_test_utils::NavigateToURL(browser(), tree_url);
+
+ ScopedComPtr<IAccessible> document_accessible(
+ GetRenderWidgetHostViewClientAccessible());
+
+ AccessibleChecker button_checker(L"push", ROLE_SYSTEM_PUSHBUTTON);
+ AccessibleChecker checkbox_checker(L"", ROLE_SYSTEM_CHECKBUTTON);
+
+ AccessibleChecker grouping_checker(L"", ROLE_SYSTEM_GROUPING);
+ grouping_checker.AppendExpectedChild(&button_checker);
+ grouping_checker.AppendExpectedChild(&checkbox_checker);
+
+ AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT);
+ document_checker.AppendExpectedChild(&grouping_checker);
+
+ // Check the accessible tree of the renderer.
+ document_checker.CheckAccessible(document_accessible);
+
+ // Check that document accessible has a parent accessible.
+ ScopedComPtr<IDispatch> parent_dispatch;
+ HRESULT hr = document_accessible->get_accParent(parent_dispatch.Receive());
+ EXPECT_EQ(hr, S_OK);
+ EXPECT_NE(parent_dispatch, reinterpret_cast<IDispatch*>(NULL));
+
+ // Navigate to another page.
+ GURL about_url("about:");
+ ui_test_utils::NavigateToURL(browser(), about_url);
+
+ // Verify that the IAccessible reference still points to a valid object and
+ // that it calls to its methods fail since the tree is no longer valid after
+ // the page navagation.
+ // Todo(ctguil): Currently this is giving a false positive because E_FAIL is
+ // returned when BrowserAccessibilityManager::RequestAccessibilityInfo fails
+ // since the previous render view host connection is lost. Verify that
+ // instances are actually marked as invalid once the browse side cache is
+ // checked in.
+ CComBSTR name;
+ hr = document_accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);
+ ASSERT_EQ(E_FAIL, hr);
+}
+} // namespace.
+