1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <atlbase.h>
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector>
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/win/scoped_comptr.h"
93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/automation/ui_controls.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/renderer_host/render_widget_host_view_win.h"
114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/ui/browser.h"
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_window.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/test/in_process_browser_test.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/test/ui_test_utils.h"
15dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_view_host.h"
16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h"
17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_type.h"
1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ia2_api_all.h"  // Generated    NOLINT
1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ISimpleDOMNode.h"  // Generated   NOLINT
203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickusing std::auto_ptr;
223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickusing std::vector;
233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickusing std::wstring;
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass AccessibilityWinBrowserTest : public InProcessBrowserTest {
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  AccessibilityWinBrowserTest() {}
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // InProcessBrowserTest
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void SetUpInProcessBrowserTestFixture();
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  IAccessible* GetRendererAccessible();
363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void ExecuteScript(wstring script);
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AccessibilityWinBrowserTest::SetUpInProcessBrowserTestFixture() {
403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // If the mouse happens to be on the document then it will have the unexpected
413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // STATE_SYSTEM_HOTTRACKED state. Move it to a non-document location.
423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ui_controls::SendMouseMove(0, 0);
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass AccessibleChecker {
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  AccessibleChecker(
483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      wstring expected_name,
493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      int32 expected_role,
503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      wstring expected_value);
513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  AccessibleChecker(
523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      wstring expected_name,
533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      wstring expected_role,
543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      wstring expected_value);
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Append an AccessibleChecker that verifies accessibility information for
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // a child IAccessible. Order is important.
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void AppendExpectedChild(AccessibleChecker* expected_child);
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check that the name and role of the given IAccessible instance and its
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // descendants match the expected names and roles that this object was
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // initialized with.
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void CheckAccessible(IAccessible* accessible);
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Set the expected value for this AccessibleChecker.
663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void SetExpectedValue(wstring expected_value);
673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Set the expected state for this AccessibleChecker.
693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void SetExpectedState(LONG expected_state);
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void CheckAccessibleName(IAccessible* accessible);
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void CheckAccessibleRole(IAccessible* accessible);
743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void CheckAccessibleValue(IAccessible* accessible);
753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void CheckAccessibleState(IAccessible* accessible);
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void CheckAccessibleChildren(IAccessible* accessible);
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  typedef vector<AccessibleChecker*> AccessibleCheckerVector;
803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Expected accessible name. Checked against IAccessible::get_accName.
823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  wstring name_;
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Expected accessible role. Checked against IAccessible::get_accRole.
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CComVariant role_;
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Expected accessible value. Checked against IAccessible::get_accValue.
883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  wstring value_;
893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Expected accessible state. Checked against IAccessible::get_accState.
913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  LONG state_;
923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Expected accessible children. Checked using IAccessible::get_accChildCount
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // and ::AccessibleChildren.
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AccessibleCheckerVector children_;
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochVARIANT CreateI4Variant(LONG value) {
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  VARIANT variant = {0};
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  V_VT(&variant) = VT_I4;
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  V_I4(&variant) = value;
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return variant;
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochIAccessible* GetAccessibleFromResultVariant(IAccessible* parent, VARIANT *var) {
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (V_VT(var)) {
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case VT_DISPATCH:
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return CComQIPtr<IAccessible>(V_DISPATCH(var)).Detach();
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case VT_I4: {
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      CComPtr<IDispatch> dispatch;
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      HRESULT hr = parent->get_accChild(CreateI4Variant(V_I4(var)), &dispatch);
1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      EXPECT_TRUE(SUCCEEDED(hr));
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return CComQIPtr<IAccessible>(dispatch).Detach();
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return NULL;
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1253345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickHRESULT QueryIAccessible2(IAccessible* accessible, IAccessible2** accessible2) {
1263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // TODO(ctguil): For some reason querying the IAccessible2 interface from
1273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // IAccessible fails.
128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::win::ScopedComPtr<IServiceProvider> service_provider;
1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HRESULT hr = accessible->QueryInterface(service_provider.Receive());
1303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (FAILED(hr))
1313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return hr;
1323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  hr = service_provider->QueryService(IID_IAccessible2, accessible2);
1343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return hr;
1353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
1363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Sets result to true if the child is located in the parent's tree. An
1383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// exhustive search is perform here because we determine equality using
13972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// IAccessible2::get_unique_id which is only supported by the child node.
1403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid AccessibleContainsAccessible(
1413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    IAccessible* parent, IAccessible2* child, bool* result) {
142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  vector<base::win::ScopedComPtr<IAccessible>> accessible_list;
143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  accessible_list.push_back(base::win::ScopedComPtr<IAccessible>(parent));
1443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  LONG unique_id;
1463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HRESULT hr = child->get_uniqueID(&unique_id);
14772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_EQ(S_OK, hr);
1483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  *result = false;
1493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  while (accessible_list.size()) {
151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::win::ScopedComPtr<IAccessible> accessible = accessible_list.back();
1523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    accessible_list.pop_back();
1533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::win::ScopedComPtr<IAccessible2> accessible2;
1553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    hr = QueryIAccessible2(accessible, accessible2.Receive());
1563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (SUCCEEDED(hr)) {
1573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      LONG child_id;
1583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      accessible2->get_uniqueID(&child_id);
1593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      if (child_id == unique_id) {
1603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        *result = true;
1613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        break;
1623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      }
1633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
1643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    LONG child_count;
1663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    hr = accessible->get_accChildCount(&child_count);
16772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    ASSERT_EQ(S_OK, hr);
1683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (child_count == 0)
1693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      continue;
1703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    auto_ptr<VARIANT> child_array(new VARIANT[child_count]);
1723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    LONG obtained_count = 0;
1733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    hr = AccessibleChildren(
1743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        accessible, 0, child_count, child_array.get(), &obtained_count);
17572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    ASSERT_EQ(S_OK, hr);
1763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ASSERT_EQ(child_count, obtained_count);
1773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    for (int index = 0; index < obtained_count; index++) {
179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      base::win::ScopedComPtr<IAccessible> child_accessible(
1803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        GetAccessibleFromResultVariant(accessible, &child_array.get()[index]));
181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (child_accessible.get()) {
182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        accessible_list.push_back(
183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            base::win::ScopedComPtr<IAccessible>(child_accessible));
184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
1853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
1863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
1873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
1883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Retrieve the MSAA client accessibility object for the Render Widget Host View
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// of the selected tab.
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochIAccessible*
1923345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickAccessibilityWinBrowserTest::GetRendererAccessible() {
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HWND hwnd_render_widget_host_view =
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      browser()->GetSelectedTabContents()->GetRenderWidgetHostView()->
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          GetNativeView();
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
197731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Invoke windows screen reader detection by sending the WM_GETOBJECT message
198731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // with kIdCustom as the LPARAM.
199731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  const int32 kIdCustom = 1;
200731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  SendMessage(
201731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      hwnd_render_widget_host_view, WM_GETOBJECT, OBJID_CLIENT, kIdCustom);
202731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  IAccessible* accessible;
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HRESULT hr = AccessibleObjectFromWindow(
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      hwnd_render_widget_host_view, OBJID_CLIENT,
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      IID_IAccessible, reinterpret_cast<void**>(&accessible));
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(S_OK, hr);
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_NE(accessible, reinterpret_cast<IAccessible*>(NULL));
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return accessible;
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid AccessibilityWinBrowserTest::ExecuteScript(wstring script) {
2143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  browser()->GetSelectedTabContents()->render_view_host()->
2153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      ExecuteJavascriptInWebFrame(L"", script);
2163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochAccessibleChecker::AccessibleChecker(
2193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    wstring expected_name, int32 expected_role, wstring expected_value) :
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    name_(expected_name),
2213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    role_(expected_role),
2223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    value_(expected_value),
2233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    state_(-1) {
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochAccessibleChecker::AccessibleChecker(
2273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    wstring expected_name, wstring expected_role, wstring expected_value) :
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    name_(expected_name),
2293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    role_(expected_role.c_str()),
2303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    value_(expected_value),
2313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    state_(-1) {
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AccessibleChecker::AppendExpectedChild(
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AccessibleChecker* expected_child) {
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  children_.push_back(expected_child);
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AccessibleChecker::CheckAccessible(IAccessible* accessible) {
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CheckAccessibleName(accessible);
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CheckAccessibleRole(accessible);
2423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CheckAccessibleValue(accessible);
2433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CheckAccessibleState(accessible);
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CheckAccessibleChildren(accessible);
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid AccessibleChecker::SetExpectedValue(wstring expected_value) {
2483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  value_ = expected_value;
2493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid AccessibleChecker::SetExpectedState(LONG expected_state) {
2523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  state_ = expected_state;
2533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AccessibleChecker::CheckAccessibleName(IAccessible* accessible) {
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CComBSTR name;
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HRESULT hr =
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (name_.empty()) {
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // If the object doesn't have name S_FALSE should be returned.
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(hr, S_FALSE);
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Test that the correct string was returned.
26572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    EXPECT_EQ(S_OK, hr);
2663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_STREQ(name_.c_str(),
2673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                 wstring(name.m_str, SysStringLen(name)).c_str());
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AccessibleChecker::CheckAccessibleRole(IAccessible* accessible) {
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  VARIANT var_role = {0};
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HRESULT hr =
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      accessible->get_accRole(CreateI4Variant(CHILDID_SELF), &var_role);
27572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_EQ(S_OK, hr);
2763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(role_ == var_role);
2773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid AccessibleChecker::CheckAccessibleValue(IAccessible* accessible) {
2803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CComBSTR value;
2813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HRESULT hr =
2823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      accessible->get_accValue(CreateI4Variant(CHILDID_SELF), &value);
2833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(S_OK, hr);
2843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Test that the correct string was returned.
2863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_STREQ(value_.c_str(),
2873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick               wstring(value.m_str, SysStringLen(value)).c_str());
2883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid AccessibleChecker::CheckAccessibleState(IAccessible* accessible) {
2913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (state_ < 0)
2923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return;
2933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  VARIANT var_state = {0};
2953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HRESULT hr =
2963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      accessible->get_accState(CreateI4Variant(CHILDID_SELF), &var_state);
29772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(S_OK, hr);
2983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_EQ(VT_I4, V_VT(&var_state));
2993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(state_, V_I4(&var_state));
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AccessibleChecker::CheckAccessibleChildren(IAccessible* parent) {
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LONG child_count = 0;
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HRESULT hr = parent->get_accChildCount(&child_count);
30572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(S_OK, hr);
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(child_count, children_.size());
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  auto_ptr<VARIANT> child_array(new VARIANT[child_count]);
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LONG obtained_count = 0;
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  hr = AccessibleChildren(parent, 0, child_count,
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          child_array.get(), &obtained_count);
31272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_EQ(S_OK, hr);
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(child_count, obtained_count);
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  VARIANT* child = child_array.get();
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (AccessibleCheckerVector::iterator child_checker = children_.begin();
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       child_checker != children_.end();
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       ++child_checker, ++child) {
319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::win::ScopedComPtr<IAccessible> child_accessible;
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    child_accessible.Attach(GetAccessibleFromResultVariant(parent, child));
3213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ASSERT_TRUE(child_accessible.get());
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    (*child_checker)->CheckAccessible(child_accessible);
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochIN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       TestRendererAccessibilityTree) {
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The initial accessible returned should have state STATE_SYSTEM_BUSY while
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the accessibility tree is being requested from the renderer.
3303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  AccessibleChecker document1_checker(L"", ROLE_SYSTEM_DOCUMENT, L"");
3313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  document1_checker.SetExpectedState(
3323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      STATE_SYSTEM_READONLY | STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_FOCUSED |
3333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      STATE_SYSTEM_BUSY);
3343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  document1_checker.CheckAccessible(GetRendererAccessible());
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Wait for the initial accessibility tree to load. Busy state should clear.
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::WaitForNotification(
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
3393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  document1_checker.SetExpectedState(
3403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      STATE_SYSTEM_READONLY | STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_FOCUSED);
3413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  document1_checker.CheckAccessible(GetRendererAccessible());
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL tree_url(
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "data:text/html,<html><head><title>Accessibility Win Test</title></head>"
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "<body><input type='button' value='push' /><input type='checkbox' />"
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "</body></html>");
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::WaitForNotification(
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Check the browser's copy of the renderer accessibility tree.
3523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  AccessibleChecker button_checker(L"push", ROLE_SYSTEM_PUSHBUTTON, L"push");
3533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  AccessibleChecker checkbox_checker(L"", ROLE_SYSTEM_CHECKBUTTON, L"");
3543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  AccessibleChecker body_checker(L"", L"body", L"");
3553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  AccessibleChecker document2_checker(
3563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    L"Accessibility Win Test", ROLE_SYSTEM_DOCUMENT, L"");
3573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  body_checker.AppendExpectedChild(&button_checker);
3583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  body_checker.AppendExpectedChild(&checkbox_checker);
3593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  document2_checker.AppendExpectedChild(&body_checker);
3603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  document2_checker.CheckAccessible(GetRendererAccessible());
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check that document accessible has a parent accessible.
363ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::win::ScopedComPtr<IAccessible> document_accessible(
364ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      GetRendererAccessible());
3653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_NE(document_accessible.get(), reinterpret_cast<IAccessible*>(NULL));
366ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::win::ScopedComPtr<IDispatch> parent_dispatch;
3673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HRESULT hr = document_accessible->get_accParent(parent_dispatch.Receive());
36872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(S_OK, hr);
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_NE(parent_dispatch, reinterpret_cast<IDispatch*>(NULL));
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to another page.
372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL about_url("about:");
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::NavigateToURL(browser(), about_url);
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Verify that the IAccessible reference still points to a valid object and
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // that calls to its methods fail since the tree is no longer valid after
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the page navagation.
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CComBSTR name;
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  hr = document_accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(E_FAIL, hr);
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3833345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickIN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
3843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       TestNotificationActiveDescendantChanged) {
3853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GURL tree_url("data:text/html,<ul tabindex='-1' role='radiogroup'><li id='li'"
3863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      ">li</li></ul>");
3873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
3883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GetRendererAccessible();
3893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ui_test_utils::WaitForNotification(
3903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
3913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Check the browser's copy of the renderer accessibility tree.
3933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  AccessibleChecker list_marker_checker(L"", ROLE_SYSTEM_LISTITEM, L"\x2022");
39472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  AccessibleChecker static_text_checker(L"li", ROLE_SYSTEM_TEXT, L"");
3953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  AccessibleChecker list_item_checker(L"", ROLE_SYSTEM_LISTITEM, L"");
3963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  list_item_checker.SetExpectedState(
3973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      STATE_SYSTEM_READONLY);
3983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  AccessibleChecker radio_group_checker(L"", ROLE_SYSTEM_GROUPING, L"");
3993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  radio_group_checker.SetExpectedState(
4003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_READONLY);
4013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT, L"");
4023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  list_item_checker.AppendExpectedChild(&list_marker_checker);
4033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  list_item_checker.AppendExpectedChild(&static_text_checker);
4043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  radio_group_checker.AppendExpectedChild(&list_item_checker);
4053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  document_checker.AppendExpectedChild(&radio_group_checker);
4063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  document_checker.CheckAccessible(GetRendererAccessible());
4073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Set focus to the radio group.
4093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ExecuteScript(L"document.body.children[0].focus()");
4103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ui_test_utils::WaitForNotification(
4113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
4123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Check that the accessibility tree of the browser has been updated.
4143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  radio_group_checker.SetExpectedState(
4153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_READONLY | STATE_SYSTEM_FOCUSED);
4163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  document_checker.CheckAccessible(GetRendererAccessible());
4173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Set the active descendant of the radio group
4193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ExecuteScript(
4203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      L"document.body.children[0].setAttribute('aria-activedescendant', 'li')");
4213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ui_test_utils::WaitForNotification(
4223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
4233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Check that the accessibility tree of the browser has been updated.
4253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  list_item_checker.SetExpectedState(
4263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      STATE_SYSTEM_READONLY | STATE_SYSTEM_FOCUSED);
4273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  radio_group_checker.SetExpectedState(
4283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_READONLY);
4293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  document_checker.CheckAccessible(GetRendererAccessible());
4303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
4313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4323345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickIN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
4333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       TestNotificationCheckedStateChanged) {
4343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GURL tree_url("data:text/html,<body><input type='checkbox' /></body>");
4353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
4363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GetRendererAccessible();
4373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ui_test_utils::WaitForNotification(
4383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
4393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Check the browser's copy of the renderer accessibility tree.
4413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  AccessibleChecker checkbox_checker(L"", ROLE_SYSTEM_CHECKBUTTON, L"");
4423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  checkbox_checker.SetExpectedState(
4433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_READONLY);
4443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  AccessibleChecker body_checker(L"", L"body", L"");
4453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT, L"");
4463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  body_checker.AppendExpectedChild(&checkbox_checker);
4473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  document_checker.AppendExpectedChild(&body_checker);
4483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  document_checker.CheckAccessible(GetRendererAccessible());
4493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Check the checkbox.
4513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ExecuteScript(L"document.body.children[0].checked=true");
4523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ui_test_utils::WaitForNotification(
4533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
4543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Check that the accessibility tree of the browser has been updated.
4563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  checkbox_checker.SetExpectedState(
4573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      STATE_SYSTEM_CHECKED | STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_READONLY);
4583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  document_checker.CheckAccessible(GetRendererAccessible());
4593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
4603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4613345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickIN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
4623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       TestNotificationChildrenChanged) {
4633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // The role attribute causes the node to be in the accessibility tree.
4643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GURL tree_url(
4653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "data:text/html,<body role=group></body>");
4663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
4673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GetRendererAccessible();
4683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ui_test_utils::WaitForNotification(
4693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
4703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Check the browser's copy of the renderer accessibility tree.
4723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  AccessibleChecker body_checker(L"", L"body", L"");
4733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT, L"");
4743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  document_checker.AppendExpectedChild(&body_checker);
4753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  document_checker.CheckAccessible(GetRendererAccessible());
4763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Change the children of the document body.
4783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ExecuteScript(L"document.body.innerHTML='<b>new text</b>'");
4793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ui_test_utils::WaitForNotification(
4803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
4813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Check that the accessibility tree of the browser has been updated.
48372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  AccessibleChecker text_checker(L"new text", ROLE_SYSTEM_TEXT, L"");
4843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  body_checker.AppendExpectedChild(&text_checker);
4853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  document_checker.CheckAccessible(GetRendererAccessible());
4863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
4873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4883345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickIN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
489731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                       TestNotificationChildrenChanged2) {
490731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // The role attribute causes the node to be in the accessibility tree.
491731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  GURL tree_url(
492731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      "data:text/html,<div role=group style='visibility: hidden'>text"
493731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      "</div>");
494731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
495731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  GetRendererAccessible();
496731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ui_test_utils::WaitForNotification(
497731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
498731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
499731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Check the accessible tree of the browser.
500731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT, L"");
501731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  document_checker.CheckAccessible(GetRendererAccessible());
502731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
503731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Change the children of the document body.
504731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ExecuteScript(L"document.body.children[0].style.visibility='visible'");
505731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ui_test_utils::WaitForNotification(
506731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
507731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
508731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Check that the accessibility tree of the browser has been updated.
50972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  AccessibleChecker static_text_checker(L"text", ROLE_SYSTEM_TEXT, L"");
510731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AccessibleChecker div_checker(L"", L"div", L"");
511731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  document_checker.AppendExpectedChild(&div_checker);
512731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  div_checker.AppendExpectedChild(&static_text_checker);
513731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  document_checker.CheckAccessible(GetRendererAccessible());
514731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
515731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
516731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickIN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
5173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       TestNotificationFocusChanged) {
5183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // The role attribute causes the node to be in the accessibility tree.
5193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GURL tree_url(
5203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "data:text/html,<div role=group tabindex='-1'></div>");
5213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
5223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GetRendererAccessible();
5233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ui_test_utils::WaitForNotification(
5243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
5253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Check the browser's copy of the renderer accessibility tree.
5273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  AccessibleChecker div_checker(L"", L"div", L"");
5283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  div_checker.SetExpectedState(
5293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_OFFSCREEN | STATE_SYSTEM_READONLY);
5303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT, L"");
5313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  document_checker.AppendExpectedChild(&div_checker);
5323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  document_checker.CheckAccessible(GetRendererAccessible());
5333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Focus the div in the document
5353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ExecuteScript(L"document.body.children[0].focus()");
5363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ui_test_utils::WaitForNotification(
5373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
5383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Check that the accessibility tree of the browser has been updated.
5403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  div_checker.SetExpectedState(
5413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_READONLY | STATE_SYSTEM_FOCUSED);
5423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  document_checker.CheckAccessible(GetRendererAccessible());
5433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Focus the document accessible. This will un-focus the current node.
545ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::win::ScopedComPtr<IAccessible> document_accessible(
546ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      GetRendererAccessible());
5473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_NE(document_accessible.get(), reinterpret_cast<IAccessible*>(NULL));
5483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HRESULT hr = document_accessible->accSelect(
5493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    SELFLAG_TAKEFOCUS, CreateI4Variant(CHILDID_SELF));
55072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_EQ(S_OK, hr);
5513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ui_test_utils::WaitForNotification(
5523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
5533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Check that the accessibility tree of the browser has been updated.
555731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  div_checker.SetExpectedState(
556731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_READONLY);
5573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  document_checker.CheckAccessible(GetRendererAccessible());
5583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
5593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5603345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickIN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
5613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       TestNotificationValueChanged) {
5623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GURL tree_url("data:text/html,<body><input type='text' value='old value'/>"
5633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "</body>");
5643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
5653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GetRendererAccessible();
5663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ui_test_utils::WaitForNotification(
5673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
5683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Check the browser's copy of the renderer accessibility tree.
570ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
571ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AccessibleChecker text_field_div_checker(L"", L"div", L"");
5723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  AccessibleChecker text_field_checker(L"", ROLE_SYSTEM_TEXT, L"old value");
5733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  text_field_checker.SetExpectedState(STATE_SYSTEM_FOCUSABLE);
5743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  AccessibleChecker body_checker(L"", L"body", L"");
5753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT, L"");
576ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  text_field_checker.AppendExpectedChild(&text_field_div_checker);
5773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  body_checker.AppendExpectedChild(&text_field_checker);
5783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  document_checker.AppendExpectedChild(&body_checker);
5793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  document_checker.CheckAccessible(GetRendererAccessible());
5803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Set the value of the text control
5823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ExecuteScript(L"document.body.children[0].value='new value'");
5833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ui_test_utils::WaitForNotification(
5843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
5853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Check that the accessibility tree of the browser has been updated.
5873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  text_field_checker.SetExpectedValue(L"new value");
5883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  document_checker.CheckAccessible(GetRendererAccessible());
5893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
5903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// FAILS crbug.com/54220
5923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// This test verifies that browser-side cache of the renderer accessibility
5933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// tree is reachable from the browser's tree. Tools that analyze windows
5943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// accessibility trees like AccExplorer32 should be able to drill into the
5953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// cached renderer accessibility tree.
5963345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickIN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
5973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       DISABLED_ContainsRendererAccessibilityTree) {
5983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GURL tree_url("data:text/html,<body><input type='checkbox' /></body>");
5993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
6003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GetRendererAccessible();
6013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ui_test_utils::WaitForNotification(
6023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
6033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
6043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Get the accessibility object for the browser window.
6053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HWND browser_hwnd = browser()->window()->GetNativeHandle();
606ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::win::ScopedComPtr<IAccessible> browser_accessible;
6073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HRESULT hr = AccessibleObjectFromWindow(
6083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      browser_hwnd,
6093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      OBJID_WINDOW,
6103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      IID_IAccessible,
6113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      reinterpret_cast<void**>(browser_accessible.Receive()));
6123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_EQ(S_OK, hr);
6133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
6143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Get the accessibility object for the renderer client document.
615ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::win::ScopedComPtr<IAccessible> document_accessible(
616ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      GetRendererAccessible());
6173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_NE(document_accessible.get(), reinterpret_cast<IAccessible*>(NULL));
618ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::win::ScopedComPtr<IAccessible2> document_accessible2;
6193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  hr = QueryIAccessible2(document_accessible, document_accessible2.Receive());
6203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_EQ(S_OK, hr);
6213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
6223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // TODO(ctguil): Pointer comparison of retrieved IAccessible pointers dosen't
6233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // seem to work for here. Perhaps make IAccessible2 available in views to make
6243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // unique id comparison available.
6253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool found = false;
626ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::win::ScopedComPtr<IAccessible> parent = document_accessible;
6273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  while (parent.get()) {
628ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::win::ScopedComPtr<IDispatch> parent_dispatch;
6293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    hr = parent->get_accParent(parent_dispatch.Receive());
6303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ASSERT_TRUE(SUCCEEDED(hr));
6313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (!parent_dispatch.get()) {
6323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      ASSERT_EQ(hr, S_FALSE);
6333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      break;
6343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
6353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
6363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    parent.Release();
6373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    hr = parent_dispatch.QueryInterface(parent.Receive());
6383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ASSERT_EQ(S_OK, hr);
6393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
6403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (parent.get() == browser_accessible.get()) {
6413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      found = true;
6423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      break;
6433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
6443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
6453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
6463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // If pointer comparison fails resort to the exhuasive search that can use
64772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // IAccessible2::get_unique_id for equality comparison.
6483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!found) {
6493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    AccessibleContainsAccessible(
6503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        browser_accessible, document_accessible2, &found);
6513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
6523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
6533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_EQ(found, true);
6543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
65572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
65672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenIN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
65772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                       SupportsISimpleDOM) {
65872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  GURL tree_url("data:text/html,<body><input type='checkbox' /></body>");
65972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
66072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  GetRendererAccessible();
66172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ui_test_utils::WaitForNotification(
66272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);
66372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
66472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Get the IAccessible object for the document.
665ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::win::ScopedComPtr<IAccessible> document_accessible(
666ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      GetRendererAccessible());
66772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_NE(document_accessible.get(), reinterpret_cast<IAccessible*>(NULL));
66872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
66972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Get the ISimpleDOM object for the document.
670ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::win::ScopedComPtr<IServiceProvider> service_provider;
67172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  HRESULT hr = static_cast<IAccessible*>(document_accessible)->QueryInterface(
67272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      service_provider.Receive());
67372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_EQ(S_OK, hr);
67472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  const GUID refguid = {0x0c539790, 0x12e4, 0x11cf,
67572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                        0xb6, 0x61, 0x00, 0xaa, 0x00, 0x4c, 0xd6, 0xd8};
676ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::win::ScopedComPtr<ISimpleDOMNode> document_isimpledomnode;
67772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  hr = static_cast<IServiceProvider *>(service_provider)->QueryService(
67872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      refguid, IID_ISimpleDOMNode,
67972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      reinterpret_cast<void**>(document_isimpledomnode.Receive()));
68072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_EQ(S_OK, hr);
68172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
68272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  BSTR node_name;
68372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  short name_space_id;  // NOLINT
68472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  BSTR node_value;
68572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  unsigned int num_children;
68672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  unsigned int unique_id;
68772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  unsigned short node_type;  // NOLINT
68872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  hr = document_isimpledomnode->get_nodeInfo(
68972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      &node_name, &name_space_id, &node_value, &num_children, &unique_id,
69072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      &node_type);
69172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_EQ(S_OK, hr);
69272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(NODETYPE_DOCUMENT, node_type);
69372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(1, num_children);
69472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
695ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::win::ScopedComPtr<ISimpleDOMNode> body_isimpledomnode;
69672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  hr = document_isimpledomnode->get_firstChild(
69772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      body_isimpledomnode.Receive());
69872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_EQ(S_OK, hr);
69972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  hr = body_isimpledomnode->get_nodeInfo(
70072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      &node_name, &name_space_id, &node_value, &num_children, &unique_id,
70172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      &node_type);
70272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_EQ(S_OK, hr);
70372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_STREQ(L"body", wstring(node_name, SysStringLen(node_name)).c_str());
70472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(NODETYPE_ELEMENT, node_type);
70572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(1, num_children);
70672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
707ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::win::ScopedComPtr<ISimpleDOMNode> checkbox_isimpledomnode;
70872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  hr = body_isimpledomnode->get_firstChild(
70972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      checkbox_isimpledomnode.Receive());
71072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_EQ(S_OK, hr);
71172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  hr = checkbox_isimpledomnode->get_nodeInfo(
71272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      &node_name, &name_space_id, &node_value, &num_children, &unique_id,
71372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      &node_type);
71472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_EQ(S_OK, hr);
71572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_STREQ(L"input", wstring(node_name, SysStringLen(node_name)).c_str());
71672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(NODETYPE_ELEMENT, node_type);
71772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(0, num_children);
71872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace.
720