// Copyright (c) 2012 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 <objbase.h>
#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <vector>

#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/sys_string_conversions.h"
#include "base/win/scoped_bstr.h"
#include "base/win/scoped_comptr.h"
#include "base/win/scoped_variant.h"
#include "content/browser/accessibility/accessibility_tree_formatter.h"
#include "content/browser/accessibility/accessibility_tree_formatter_utils_win.h"
#include "content/browser/accessibility/browser_accessibility_manager_win.h"
#include "content/browser/accessibility/browser_accessibility_win.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/browser/web_contents/web_contents_view_aura.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/test/accessibility_browser_test_utils.h"
#include "net/base/escape.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "third_party/iaccessible2/ia2_api_all.h"
#include "third_party/isimpledom/ISimpleDOMNode.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"

namespace content {

namespace {


const char INPUT_CONTENTS[] = "Moz/5.0 (ST 6.x; WWW33) "
    "WebKit  \"KHTML, like\".";
const char TEXTAREA_CONTENTS[] = "Moz/5.0 (ST 6.x; WWW33)\n"
    "WebKit \n\"KHTML, like\".";
const LONG CONTENTS_LENGTH = static_cast<LONG>(
    (sizeof(INPUT_CONTENTS) - 1) / sizeof(char));


// AccessibilityWinBrowserTest ------------------------------------------------

class AccessibilityWinBrowserTest : public ContentBrowserTest {
 public:
  AccessibilityWinBrowserTest();
  ~AccessibilityWinBrowserTest() override;

 protected:
  class AccessibleChecker;
  void LoadInitialAccessibilityTreeFromHtml(
      const std::string& html,
      ui::AXMode accessibility_mode = ui::kAXModeComplete);
  IAccessible* GetRendererAccessible();
  void ExecuteScript(const std::wstring& script);
  void SetUpInputField(
      base::win::ScopedComPtr<IAccessibleText>* input_text);
  void SetUpTextareaField(
      base::win::ScopedComPtr<IAccessibleText>* textarea_text);
  void SetUpSampleParagraph(
      base::win::ScopedComPtr<IAccessibleText>* accessible_text,
      ui::AXMode accessibility_mode = ui::kAXModeComplete);

  static base::win::ScopedComPtr<IAccessible> GetAccessibleFromVariant(
      IAccessible* parent,
      VARIANT* var);
  static HRESULT QueryIAccessible2(IAccessible* accessible,
                                   IAccessible2** accessible2);
  static void FindNodeInAccessibilityTree(IAccessible* node,
                                          int32_t expected_role,
                                          const std::wstring& expected_name,
                                          int32_t depth,
                                          bool* found);
  static void CheckTextAtOffset(
      base::win::ScopedComPtr<IAccessibleText>& object,
      LONG offset,
      IA2TextBoundaryType boundary_type,
      LONG expected_start_offset,
      LONG expected_end_offset,
      const std::wstring& expected_text);
  static std::vector<base::win::ScopedVariant> GetAllAccessibleChildren(
      IAccessible* element);

 private:
  DISALLOW_COPY_AND_ASSIGN(AccessibilityWinBrowserTest);
};

AccessibilityWinBrowserTest::AccessibilityWinBrowserTest() {
}

AccessibilityWinBrowserTest::~AccessibilityWinBrowserTest() {
}

void AccessibilityWinBrowserTest::LoadInitialAccessibilityTreeFromHtml(
    const std::string& html,
    ui::AXMode accessibility_mode) {
  AccessibilityNotificationWaiter waiter(
      shell()->web_contents(), accessibility_mode, ui::AX_EVENT_LOAD_COMPLETE);
  GURL html_data_url("data:text/html," + html);
  NavigateToURL(shell(), html_data_url);
  waiter.WaitForNotification();
}

// Retrieve the MSAA client accessibility object for the Render Widget Host View
// of the selected tab.
IAccessible* AccessibilityWinBrowserTest::GetRendererAccessible() {
  content::WebContents* web_contents = shell()->web_contents();
  return web_contents->GetRenderWidgetHostView()->GetNativeViewAccessible();
}

void AccessibilityWinBrowserTest::ExecuteScript(const std::wstring& script) {
  shell()->web_contents()->GetMainFrame()->ExecuteJavaScriptForTests(script);
}

// Loads a page with  an input text field and places sample text in it. Also,
// places the caret on the last character.
void AccessibilityWinBrowserTest::SetUpInputField(
    base::win::ScopedComPtr<IAccessibleText>* input_text) {
  ASSERT_NE(nullptr, input_text);
  LoadInitialAccessibilityTreeFromHtml(std::string("<!DOCTYPE html><html><body>"
      "<form><label for='textField'>Browser name:</label>"
      "<input type='text' id='textField' name='name' value='") +
      net::EscapeQueryParamValue(INPUT_CONTENTS, false) + std::string(
      "'></form></body></html>"));

  // Retrieve the IAccessible interface for the web page.
  base::win::ScopedComPtr<IAccessible> document(GetRendererAccessible());
  std::vector<base::win::ScopedVariant> document_children =
      GetAllAccessibleChildren(document.Get());
  ASSERT_EQ(1u, document_children.size());

  base::win::ScopedComPtr<IAccessible2> form;
  ASSERT_HRESULT_SUCCEEDED(QueryIAccessible2(
      GetAccessibleFromVariant(document.Get(), document_children[0].AsInput())
          .Get(),
      form.GetAddressOf()));
  std::vector<base::win::ScopedVariant> form_children =
      GetAllAccessibleChildren(form.Get());
  ASSERT_EQ(2u, form_children.size());

  // Find the input text field.
  base::win::ScopedComPtr<IAccessible2> input;
  ASSERT_HRESULT_SUCCEEDED(QueryIAccessible2(
      GetAccessibleFromVariant(form.Get(), form_children[1].AsInput()).Get(),
      input.GetAddressOf()));
  LONG input_role = 0;
  ASSERT_HRESULT_SUCCEEDED(input->role(&input_role));
  ASSERT_EQ(ROLE_SYSTEM_TEXT, input_role);

  // Retrieve the IAccessibleText interface for the field.
  ASSERT_HRESULT_SUCCEEDED(input.CopyTo(input_text->GetAddressOf()));

  // Set the caret on the last character.
  AccessibilityNotificationWaiter waiter(shell()->web_contents(),
                                         ui::kAXModeComplete,
                                         ui::AX_EVENT_TEXT_SELECTION_CHANGED);
  std::wstring caret_offset = base::UTF16ToWide(base::IntToString16(
      static_cast<int>(CONTENTS_LENGTH - 1)));
  ExecuteScript(std::wstring(
      L"var textField = document.getElementById('textField');"
      L"textField.focus();"
      L"textField.setSelectionRange(") +
      caret_offset + L"," + caret_offset + L");");
  waiter.WaitForNotification();
}

// Loads a page with  a textarea text field and places sample text in it. Also,
// places the caret on the last character.
void AccessibilityWinBrowserTest::SetUpTextareaField(
    base::win::ScopedComPtr<IAccessibleText>* textarea_text) {
  ASSERT_NE(nullptr, textarea_text);
  LoadInitialAccessibilityTreeFromHtml(std::string("<!DOCTYPE html><html><body>"
      "<textarea id='textField' rows='3' cols='60'>") +
      net::EscapeQueryParamValue(TEXTAREA_CONTENTS, false) + std::string(
      "</textarea></body></html>"));

  // Retrieve the IAccessible interface for the web page.
  base::win::ScopedComPtr<IAccessible> document(GetRendererAccessible());
  std::vector<base::win::ScopedVariant> document_children =
      GetAllAccessibleChildren(document.Get());
  ASSERT_EQ(1u, document_children.size());

  base::win::ScopedComPtr<IAccessible2> section;
  ASSERT_HRESULT_SUCCEEDED(QueryIAccessible2(
      GetAccessibleFromVariant(document.Get(), document_children[0].AsInput())
          .Get(),
      section.GetAddressOf()));
  std::vector<base::win::ScopedVariant> section_children =
      GetAllAccessibleChildren(section.Get());
  ASSERT_EQ(1u, section_children.size());

  // Find the textarea text field.
  base::win::ScopedComPtr<IAccessible2> textarea;
  ASSERT_HRESULT_SUCCEEDED(QueryIAccessible2(
      GetAccessibleFromVariant(section.Get(), section_children[0].AsInput())
          .Get(),
      textarea.GetAddressOf()));
  LONG textarea_role = 0;
  ASSERT_HRESULT_SUCCEEDED(textarea->role(&textarea_role));
  ASSERT_EQ(ROLE_SYSTEM_TEXT, textarea_role);

  // Retrieve the IAccessibleText interface for the field.
  ASSERT_HRESULT_SUCCEEDED(textarea.CopyTo(textarea_text->GetAddressOf()));

  // Set the caret on the last character.
  AccessibilityNotificationWaiter waiter(shell()->web_contents(),
                                         ui::kAXModeComplete,
                                         ui::AX_EVENT_TEXT_SELECTION_CHANGED);
  std::wstring caret_offset = base::UTF16ToWide(base::IntToString16(
      static_cast<int>(CONTENTS_LENGTH - 1)));
  ExecuteScript(std::wstring(
      L"var textField = document.getElementById('textField');"
      L"textField.focus();"
      L"textField.setSelectionRange(") +
      caret_offset + L"," + caret_offset + L");");
  waiter.WaitForNotification();
}

// Loads a page with  a paragraph of sample text.
void AccessibilityWinBrowserTest::SetUpSampleParagraph(
    base::win::ScopedComPtr<IAccessibleText>* accessible_text,
    ui::AXMode accessibility_mode) {
  ASSERT_NE(nullptr, accessible_text);
  LoadInitialAccessibilityTreeFromHtml(
      "<!DOCTYPE html><html>"
      "<body style=\"overflow: scroll; margin-top: 100vh\">"
      "<p><b>Game theory</b> is \"the study of "
      "<a href=\"#\" title=\"Mathematical model\">mathematical models</a> "
      "of conflict and<br>cooperation between intelligent rational "
      "decision-makers.\"</p></body></html>",
      accessibility_mode);

  // Retrieve the IAccessible interface for the web page.
  base::win::ScopedComPtr<IAccessible> document(GetRendererAccessible());
  std::vector<base::win::ScopedVariant> document_children =
      GetAllAccessibleChildren(document.Get());
  ASSERT_EQ(1u, document_children.size());

  base::win::ScopedComPtr<IAccessible2> paragraph;
  ASSERT_HRESULT_SUCCEEDED(QueryIAccessible2(
      GetAccessibleFromVariant(document.Get(), document_children[0].AsInput())
          .Get(),
      paragraph.GetAddressOf()));
  LONG paragraph_role = 0;
  ASSERT_HRESULT_SUCCEEDED(paragraph->role(&paragraph_role));
  ASSERT_EQ(IA2_ROLE_PARAGRAPH, paragraph_role);
  ASSERT_HRESULT_SUCCEEDED(paragraph.CopyTo(accessible_text->GetAddressOf()));
}

// Static helpers ------------------------------------------------

base::win::ScopedComPtr<IAccessible>
AccessibilityWinBrowserTest::GetAccessibleFromVariant(
    IAccessible* parent,
    VARIANT* var) {
  base::win::ScopedComPtr<IAccessible> ptr;
  switch (V_VT(var)) {
    case VT_DISPATCH: {
      IDispatch* dispatch = V_DISPATCH(var);
      if (dispatch)
        dispatch->QueryInterface(ptr.GetAddressOf());
      break;
    }

    case VT_I4: {
      base::win::ScopedComPtr<IDispatch> dispatch;
      HRESULT hr = parent->get_accChild(*var, dispatch.GetAddressOf());
      EXPECT_TRUE(SUCCEEDED(hr));
      if (dispatch.Get())
        dispatch.CopyTo(ptr.GetAddressOf());
      break;
    }
  }
  return ptr;
}

HRESULT AccessibilityWinBrowserTest::QueryIAccessible2(
    IAccessible* accessible,
    IAccessible2** accessible2) {
  // IA2 Spec dictates that IServiceProvider should be used instead of
  // QueryInterface when retrieving IAccessible2.
  base::win::ScopedComPtr<IServiceProvider> service_provider;
  HRESULT hr = accessible->QueryInterface(service_provider.GetAddressOf());
  return SUCCEEDED(hr) ?
      service_provider->QueryService(IID_IAccessible2, accessible2) : hr;
}

// 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 AccessibilityWinBrowserTest::FindNodeInAccessibilityTree(
    IAccessible* node,
    int32_t expected_role,
    const std::wstring& expected_name,
    int32_t depth,
    bool* found) {
  base::win::ScopedBstr name_bstr;
  base::win::ScopedVariant childid_self(CHILDID_SELF);
  node->get_accName(childid_self, name_bstr.Receive());
  std::wstring name(name_bstr, name_bstr.Length());
  base::win::ScopedVariant role;
  node->get_accRole(childid_self, role.Receive());
  ASSERT_EQ(VT_I4, role.type());

  // 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=%s name=%s\n",
         base::WideToUTF8(IAccessibleRoleToString(V_I4(role.ptr()))).c_str(),
         base::WideToUTF8(name).c_str());

  if (expected_role == V_I4(role.ptr()) && expected_name == name) {
    *found = true;
    return;
  }

  std::vector<base::win::ScopedVariant> children = GetAllAccessibleChildren(
      node);
  for (size_t i = 0; i < children.size(); ++i) {
    base::win::ScopedComPtr<IAccessible> child_accessible(
        GetAccessibleFromVariant(node, children[i].AsInput()));
    if (child_accessible) {
      FindNodeInAccessibilityTree(
          child_accessible.Get(), expected_role, expected_name, depth + 1,
          found);
      if (*found)
        return;
    }
  }
}

// Ensures that the text and the start and end offsets retrieved using
// get_textAtOffset match the expected values.
void AccessibilityWinBrowserTest::CheckTextAtOffset(
    base::win::ScopedComPtr<IAccessibleText>& object,
    LONG offset,
    IA2TextBoundaryType boundary_type,
    LONG expected_start_offset,
    LONG expected_end_offset,
    const std::wstring& expected_text) {
  testing::Message message;
  message << "While checking for \'" << expected_text << "\' at " <<
      expected_start_offset << '-' << expected_end_offset << '.';
  SCOPED_TRACE(message);

  LONG start_offset = 0;
  LONG end_offset = 0;
  base::win::ScopedBstr text;
  HRESULT hr = object->get_textAtOffset(offset, boundary_type, &start_offset,
                                        &end_offset, text.Receive());
  EXPECT_EQ(S_OK, hr);
  EXPECT_EQ(expected_start_offset, start_offset);
  EXPECT_EQ(expected_end_offset, end_offset);
  EXPECT_EQ(expected_text, std::wstring(text, text.Length()));
}

std::vector<base::win::ScopedVariant>
AccessibilityWinBrowserTest::GetAllAccessibleChildren(
    IAccessible* element) {
  LONG child_count = 0;
  HRESULT hr = element->get_accChildCount(&child_count);
  EXPECT_EQ(S_OK, hr);
  if (child_count <= 0)
      return std::vector<base::win::ScopedVariant>();

  std::unique_ptr<VARIANT[]> children_array(new VARIANT[child_count]);
  LONG obtained_count = 0;
  hr = AccessibleChildren(
      element, 0, child_count, children_array.get(), &obtained_count);
  EXPECT_EQ(S_OK, hr);
  EXPECT_EQ(child_count, obtained_count);

  std::vector<base::win::ScopedVariant> children(
      static_cast<size_t>(child_count));
  for (size_t i = 0; i < children.size(); i++) {
    children[i].Reset(children_array[i]);
  }
  return children;
}


// AccessibleChecker ----------------------------------------------------------

class AccessibilityWinBrowserTest::AccessibleChecker {
 public:
  // This constructor can be used if the IA2 role will be the same as the MSAA
  // role.
  AccessibleChecker(const std::wstring& expected_name,
                    int32_t expected_role,
                    const std::wstring& expected_value);
  AccessibleChecker(const std::wstring& expected_name,
                    int32_t expected_role,
                    int32_t expected_ia2_role,
                    const std::wstring& expected_value);
  AccessibleChecker(const std::wstring& expected_name,
                    const std::wstring& expected_role,
                    int32_t expected_ia2_role,
                    const std::wstring& expected_value);

  // 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);

  // Set the expected value for this AccessibleChecker.
  void SetExpectedValue(const std::wstring& expected_value);

  // Set the expected state for this AccessibleChecker.
  void SetExpectedState(LONG expected_state);

 private:
  typedef std::vector<AccessibleChecker*> AccessibleCheckerVector;

  void CheckAccessibleName(IAccessible* accessible);
  void CheckAccessibleRole(IAccessible* accessible);
  void CheckIA2Role(IAccessible* accessible);
  void CheckAccessibleValue(IAccessible* accessible);
  void CheckAccessibleState(IAccessible* accessible);
  void CheckAccessibleChildren(IAccessible* accessible);
  base::string16 RoleVariantToString(const base::win::ScopedVariant& role);

  // Expected accessible name. Checked against IAccessible::get_accName.
  std::wstring name_;

  // Expected accessible role. Checked against IAccessible::get_accRole.
  base::win::ScopedVariant role_;

  // Expected IAccessible2 role. Checked against IAccessible2::role.
  int32_t ia2_role_;

  // Expected accessible value. Checked against IAccessible::get_accValue.
  std::wstring value_;

  // Expected accessible state. Checked against IAccessible::get_accState.
  LONG state_;

  // Expected accessible children. Checked using IAccessible::get_accChildCount
  // and ::AccessibleChildren.
  AccessibleCheckerVector children_;
};

AccessibilityWinBrowserTest::AccessibleChecker::AccessibleChecker(
    const std::wstring& expected_name,
    int32_t expected_role,
    const std::wstring& expected_value)
    : name_(expected_name),
      role_(expected_role),
      ia2_role_(expected_role),
      value_(expected_value),
      state_(-1) {}

AccessibilityWinBrowserTest::AccessibleChecker::AccessibleChecker(
    const std::wstring& expected_name,
    int32_t expected_role,
    int32_t expected_ia2_role,
    const std::wstring& expected_value)
    : name_(expected_name),
      role_(expected_role),
      ia2_role_(expected_ia2_role),
      value_(expected_value),
      state_(-1) {}

AccessibilityWinBrowserTest::AccessibleChecker::AccessibleChecker(
    const std::wstring& expected_name,
    const std::wstring& expected_role,
    int32_t expected_ia2_role,
    const std::wstring& expected_value)
    : name_(expected_name),
      role_(expected_role.c_str()),
      ia2_role_(expected_ia2_role),
      value_(expected_value),
      state_(-1) {}

void AccessibilityWinBrowserTest::AccessibleChecker::AppendExpectedChild(
    AccessibleChecker* expected_child) {
  children_.push_back(expected_child);
}

void AccessibilityWinBrowserTest::AccessibleChecker::CheckAccessible(
    IAccessible* accessible) {
  SCOPED_TRACE("While checking "
                   + base::UTF16ToUTF8(RoleVariantToString(role_)));
  CheckAccessibleName(accessible);
  CheckAccessibleRole(accessible);
  CheckIA2Role(accessible);
  CheckAccessibleValue(accessible);
  CheckAccessibleState(accessible);
  CheckAccessibleChildren(accessible);
}

void AccessibilityWinBrowserTest::AccessibleChecker::SetExpectedValue(
    const std::wstring& expected_value) {
  value_ = expected_value;
}

void AccessibilityWinBrowserTest::AccessibleChecker::SetExpectedState(
    LONG expected_state) {
  state_ = expected_state;
}

void AccessibilityWinBrowserTest::AccessibleChecker::CheckAccessibleName(
    IAccessible* accessible) {
  base::win::ScopedBstr name;
  base::win::ScopedVariant childid_self(CHILDID_SELF);
  HRESULT hr = accessible->get_accName(childid_self, name.Receive());

  if (name_.empty()) {
    // If the object doesn't have name S_FALSE should be returned.
    EXPECT_EQ(S_FALSE, hr);
  } else {
    // Test that the correct string was returned.
    EXPECT_EQ(S_OK, hr);
    EXPECT_EQ(name_, std::wstring(name, name.Length()));
  }
}

void AccessibilityWinBrowserTest::AccessibleChecker::CheckAccessibleRole(
    IAccessible* accessible) {
  base::win::ScopedVariant role;
  base::win::ScopedVariant childid_self(CHILDID_SELF);
  HRESULT hr = accessible->get_accRole(childid_self, role.Receive());
  ASSERT_EQ(S_OK, hr);
  EXPECT_EQ(0, role_.Compare(role))
      << "Expected role: " << RoleVariantToString(role_)
      << "\nGot role: " << RoleVariantToString(role);
}

void AccessibilityWinBrowserTest::AccessibleChecker::CheckIA2Role(
    IAccessible* accessible) {
  base::win::ScopedComPtr<IAccessible2> accessible2;
  HRESULT hr = QueryIAccessible2(accessible, accessible2.GetAddressOf());
  ASSERT_EQ(S_OK, hr);
  long ia2_role = 0;
  hr = accessible2->role(&ia2_role);
  ASSERT_EQ(S_OK, hr);
  EXPECT_EQ(ia2_role_, ia2_role)
    << "Expected ia2 role: " << IAccessible2RoleToString(ia2_role_)
    << "\nGot ia2 role: " << IAccessible2RoleToString(ia2_role);
}

void AccessibilityWinBrowserTest::AccessibleChecker::CheckAccessibleValue(
    IAccessible* accessible) {
  // Don't check the value if if's a DOCUMENT role, because the value
  // is supposed to be the url (and we don't keep track of that in the
  // test expectations).
  base::win::ScopedVariant role;
  base::win::ScopedVariant childid_self(CHILDID_SELF);
  HRESULT hr = accessible->get_accRole(childid_self, role.Receive());
  ASSERT_EQ(S_OK, hr);
  if (role.type() == VT_I4 && V_I4(role.ptr()) == ROLE_SYSTEM_DOCUMENT)
    return;

  // Get the value.
  base::win::ScopedBstr value;
  hr = accessible->get_accValue(childid_self, value.Receive());
  EXPECT_EQ(S_OK, hr);

  // Test that the correct string was returned.
  EXPECT_EQ(value_, std::wstring(value, value.Length()));
}

void AccessibilityWinBrowserTest::AccessibleChecker::CheckAccessibleState(
    IAccessible* accessible) {
  if (state_ < 0)
    return;

  base::win::ScopedVariant state;
  base::win::ScopedVariant childid_self(CHILDID_SELF);
  HRESULT hr = accessible->get_accState(childid_self, state.Receive());
  EXPECT_EQ(S_OK, hr);
  ASSERT_EQ(VT_I4, state.type());
  LONG obj_state = V_I4(state.ptr());
  // Avoid flakiness. The "offscreen" state depends on whether the browser
  // window is frontmost or not, and "hottracked" depends on whether the
  // mouse cursor happens to be over the element.
  obj_state &= ~(STATE_SYSTEM_OFFSCREEN | STATE_SYSTEM_HOTTRACKED);
  EXPECT_EQ(state_, obj_state)
    << "Expected state: " << IAccessibleStateToString(state_)
    << "\nGot state: " << IAccessibleStateToString(obj_state);
}

void AccessibilityWinBrowserTest::AccessibleChecker::CheckAccessibleChildren(
    IAccessible* parent) {
  std::vector<base::win::ScopedVariant> obtained_children =
      GetAllAccessibleChildren(parent);
  size_t child_count = obtained_children.size();
  ASSERT_EQ(child_count, children_.size());

  AccessibleCheckerVector::iterator child_checker;
  std::vector<base::win::ScopedVariant>::iterator child;
  for (child_checker = children_.begin(),
       child = obtained_children.begin();
       child_checker != children_.end()
       && child != obtained_children.end();
       ++child_checker, ++child) {
    base::win::ScopedComPtr<IAccessible> child_accessible(
        GetAccessibleFromVariant(parent, child->AsInput()));
    ASSERT_TRUE(child_accessible.Get());
    (*child_checker)->CheckAccessible(child_accessible.Get());
  }
}

base::string16
AccessibilityWinBrowserTest::AccessibleChecker::RoleVariantToString(
    const base::win::ScopedVariant& role) {
  if (role.type() == VT_I4)
    return IAccessibleRoleToString(V_I4(role.ptr()));
  if (role.type() == VT_BSTR)
    return base::string16(V_BSTR(role.ptr()), SysStringLen(V_BSTR(role.ptr())));
  return base::string16();
}

}  // namespace


// Tests ----------------------------------------------------------------------

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       TestBusyAccessibilityTree) {
  NavigateToURL(shell(), GURL(url::kAboutBlankURL));

  // The initial accessible returned should have state STATE_SYSTEM_BUSY while
  // the accessibility tree is being requested from the renderer.
  AccessibleChecker document1_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT,
                                      std::wstring());
  document1_checker.SetExpectedState(
      STATE_SYSTEM_READONLY | STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_FOCUSED |
      STATE_SYSTEM_BUSY);
  document1_checker.CheckAccessible(GetRendererAccessible());
}

// Periodically failing.  See crbug.com/145537
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       DISABLED_TestNotificationActiveDescendantChanged) {
  LoadInitialAccessibilityTreeFromHtml(
      "<ul tabindex='-1' role='radiogroup' aria-label='ul'>"
      "<li id='li'>li</li></ul>");

  // Check the browser's copy of the renderer accessibility tree.
  AccessibleChecker list_marker_checker(L"\x2022", ROLE_SYSTEM_TEXT,
                                        std::wstring());
  AccessibleChecker static_text_checker(L"li", ROLE_SYSTEM_TEXT,
                                        std::wstring());
  AccessibleChecker list_item_checker(std::wstring(), ROLE_SYSTEM_LISTITEM,
                                      std::wstring());
  list_item_checker.SetExpectedState(STATE_SYSTEM_READONLY);
  AccessibleChecker radio_group_checker(L"ul", ROLE_SYSTEM_GROUPING,
                                        IA2_ROLE_SECTION, std::wstring());
  radio_group_checker.SetExpectedState(STATE_SYSTEM_FOCUSABLE);
  AccessibleChecker document_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT,
                                     std::wstring());
  list_item_checker.AppendExpectedChild(&list_marker_checker);
  list_item_checker.AppendExpectedChild(&static_text_checker);
  radio_group_checker.AppendExpectedChild(&list_item_checker);
  document_checker.AppendExpectedChild(&radio_group_checker);
  document_checker.CheckAccessible(GetRendererAccessible());

  // Set focus to the radio group.
  std::unique_ptr<AccessibilityNotificationWaiter> waiter(
      new AccessibilityNotificationWaiter(
          shell()->web_contents(), ui::kAXModeComplete, ui::AX_EVENT_FOCUS));
  ExecuteScript(L"document.body.children[0].focus()");
  waiter->WaitForNotification();

  // Check that the accessibility tree of the browser has been updated.
  radio_group_checker.SetExpectedState(
      STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_FOCUSED);
  document_checker.CheckAccessible(GetRendererAccessible());

  // Set the active descendant of the radio group
  waiter.reset(new AccessibilityNotificationWaiter(
      shell()->web_contents(), ui::kAXModeComplete, ui::AX_EVENT_FOCUS));
  ExecuteScript(
      L"document.body.children[0].setAttribute('aria-activedescendant', 'li')");
  waiter->WaitForNotification();

  // Check that the accessibility tree of the browser has been updated.
  list_item_checker.SetExpectedState(
      STATE_SYSTEM_READONLY | STATE_SYSTEM_FOCUSED);
  radio_group_checker.SetExpectedState(STATE_SYSTEM_FOCUSABLE);
  document_checker.CheckAccessible(GetRendererAccessible());
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       TestNotificationCheckedStateChanged) {
  LoadInitialAccessibilityTreeFromHtml(
      "<body><input type='checkbox' /></body>");

  // Check the browser's copy of the renderer accessibility tree.
  AccessibleChecker checkbox_checker(std::wstring(), ROLE_SYSTEM_CHECKBUTTON,
                                     std::wstring());
  checkbox_checker.SetExpectedState(STATE_SYSTEM_FOCUSABLE);
  AccessibleChecker body_checker(std::wstring(), L"BODY", IA2_ROLE_SECTION,
                                 std::wstring());
  AccessibleChecker document_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT,
                                     std::wstring());
  body_checker.AppendExpectedChild(&checkbox_checker);
  document_checker.AppendExpectedChild(&body_checker);
  document_checker.CheckAccessible(GetRendererAccessible());

  // Check the checkbox.
  std::unique_ptr<AccessibilityNotificationWaiter> waiter(
      new AccessibilityNotificationWaiter(shell()->web_contents(),
                                          ui::kAXModeComplete,
                                          ui::AX_EVENT_CHECKED_STATE_CHANGED));
  ExecuteScript(L"document.body.children[0].checked=true");
  waiter->WaitForNotification();

  // Check that the accessibility tree of the browser has been updated.
  checkbox_checker.SetExpectedState(
      STATE_SYSTEM_CHECKED | STATE_SYSTEM_FOCUSABLE);
  document_checker.CheckAccessible(GetRendererAccessible());
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       TestNotificationChildrenChanged) {
  // The role attribute causes the node to be in the accessibility tree.
  LoadInitialAccessibilityTreeFromHtml("<body role=group></body>");

  // Check the browser's copy of the renderer accessibility tree.
  AccessibleChecker group_checker(std::wstring(), ROLE_SYSTEM_GROUPING,
                                  std::wstring());
  AccessibleChecker document_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT,
                                     std::wstring());
  document_checker.AppendExpectedChild(&group_checker);
  document_checker.CheckAccessible(GetRendererAccessible());

  // Change the children of the document body.
  std::unique_ptr<AccessibilityNotificationWaiter> waiter(
      new AccessibilityNotificationWaiter(shell()->web_contents(),
                                          ui::kAXModeComplete,
                                          ui::AX_EVENT_CHILDREN_CHANGED));
  ExecuteScript(L"document.body.innerHTML='<b>new text</b>'");
  waiter->WaitForNotification();

  // Check that the accessibility tree of the browser has been updated.
  AccessibleChecker text_checker(
      L"new text", ROLE_SYSTEM_STATICTEXT, std::wstring());
  group_checker.AppendExpectedChild(&text_checker);
  document_checker.CheckAccessible(GetRendererAccessible());
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       TestNotificationChildrenChanged2) {
  // The role attribute causes the node to be in the accessibility tree.
  LoadInitialAccessibilityTreeFromHtml(
      "<div role=group style='visibility: hidden'>text</div>");

  // Check the accessible tree of the browser.
  AccessibleChecker document_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT,
                                     std::wstring());
  document_checker.CheckAccessible(GetRendererAccessible());

  // Change the children of the document body.
  std::unique_ptr<AccessibilityNotificationWaiter> waiter(
      new AccessibilityNotificationWaiter(shell()->web_contents(),
                                          ui::kAXModeComplete,
                                          ui::AX_EVENT_CHILDREN_CHANGED));
  ExecuteScript(L"document.body.children[0].style.visibility='visible'");
  waiter->WaitForNotification();

  // Check that the accessibility tree of the browser has been updated.
  AccessibleChecker static_text_checker(L"text", ROLE_SYSTEM_STATICTEXT,
                                        std::wstring());
  AccessibleChecker group_checker(std::wstring(), ROLE_SYSTEM_GROUPING,
                                  std::wstring());
  document_checker.AppendExpectedChild(&group_checker);
  group_checker.AppendExpectedChild(&static_text_checker);
  document_checker.CheckAccessible(GetRendererAccessible());
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       TestNotificationFocusChanged) {
  // The role attribute causes the node to be in the accessibility tree.
  LoadInitialAccessibilityTreeFromHtml("<div role=group tabindex='-1'></div>");

  // Check the browser's copy of the renderer accessibility tree.
  SCOPED_TRACE("Check initial tree");
  AccessibleChecker group_checker(std::wstring(), ROLE_SYSTEM_GROUPING,
                                  std::wstring());
  group_checker.SetExpectedState(STATE_SYSTEM_FOCUSABLE);
  AccessibleChecker document_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT,
                                     std::wstring());
  document_checker.AppendExpectedChild(&group_checker);
  document_checker.CheckAccessible(GetRendererAccessible());

  // Focus the div in the document
  std::unique_ptr<AccessibilityNotificationWaiter> waiter(
      new AccessibilityNotificationWaiter(
          shell()->web_contents(), ui::kAXModeComplete, ui::AX_EVENT_FOCUS));
  ExecuteScript(L"document.body.children[0].focus()");
  waiter->WaitForNotification();

  // Check that the accessibility tree of the browser has been updated.
  SCOPED_TRACE("Check updated tree after focusing div");
  group_checker.SetExpectedState(
      STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_FOCUSED);
  document_checker.CheckAccessible(GetRendererAccessible());

  // Focus the document accessible. This will un-focus the current node.
  waiter.reset(new AccessibilityNotificationWaiter(
      shell()->web_contents(), ui::kAXModeComplete, ui::AX_EVENT_BLUR));
  base::win::ScopedComPtr<IAccessible> document_accessible(
      GetRendererAccessible());
  ASSERT_NE(document_accessible.Get(), reinterpret_cast<IAccessible*>(NULL));
  base::win::ScopedVariant childid_self(CHILDID_SELF);
  HRESULT hr = document_accessible->accSelect(SELFLAG_TAKEFOCUS, childid_self);
  ASSERT_EQ(S_OK, hr);
  waiter->WaitForNotification();

  // Check that the accessibility tree of the browser has been updated.
  SCOPED_TRACE("Check updated tree after focusing document again");
  group_checker.SetExpectedState(STATE_SYSTEM_FOCUSABLE);
  document_checker.CheckAccessible(GetRendererAccessible());
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       TestNotificationValueChanged) {
  LoadInitialAccessibilityTreeFromHtml(
      "<body><input type='text' value='old value'/></body>");

  // Check the browser's copy of the renderer accessibility tree.
  AccessibleChecker text_field_checker(std::wstring(), ROLE_SYSTEM_TEXT,
                                       L"old value");
  text_field_checker.SetExpectedState(STATE_SYSTEM_FOCUSABLE);
  AccessibleChecker body_checker(std::wstring(), L"BODY", IA2_ROLE_SECTION,
                                 std::wstring());
  AccessibleChecker document_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT,
                                     std::wstring());
  body_checker.AppendExpectedChild(&text_field_checker);
  document_checker.AppendExpectedChild(&body_checker);
  document_checker.CheckAccessible(GetRendererAccessible());

  // Set the value of the text control
  std::unique_ptr<AccessibilityNotificationWaiter> waiter(
      new AccessibilityNotificationWaiter(shell()->web_contents(),
                                          ui::kAXModeComplete,
                                          ui::AX_EVENT_VALUE_CHANGED));
  ExecuteScript(L"document.body.children[0].value='new value'");
  waiter->WaitForNotification();

  // Check that the accessibility tree of the browser has been updated.
  text_field_checker.SetExpectedValue(L"new value");
  document_checker.CheckAccessible(GetRendererAccessible());
}

// 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().
// flaky: http://crbug.com/402190
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       DISABLED_ContainsRendererAccessibilityTree) {
  LoadInitialAccessibilityTreeFromHtml(
      "<html><head><title>MyDocument</title></head>"
      "<body>Content</body></html>");

  // Get the accessibility object for the window tree host.
  aura::Window* window = shell()->window();
  CHECK(window);
  aura::WindowTreeHost* window_tree_host = window->GetHost();
  CHECK(window_tree_host);
  HWND hwnd = window_tree_host->GetAcceleratedWidget();
  CHECK(hwnd);
  base::win::ScopedComPtr<IAccessible> browser_accessible;
  HRESULT hr = AccessibleObjectFromWindow(
      hwnd, OBJID_WINDOW, IID_IAccessible,
      reinterpret_cast<void**>(browser_accessible.GetAddressOf()));
  ASSERT_EQ(S_OK, hr);

  bool found = false;
  FindNodeInAccessibilityTree(
      browser_accessible.Get(), ROLE_SYSTEM_DOCUMENT, L"MyDocument", 0, &found);
  ASSERT_EQ(found, true);
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       SupportsISimpleDOM) {
  LoadInitialAccessibilityTreeFromHtml(
      "<body><input type='checkbox'></body>");

  // Get the IAccessible object for the document.
  base::win::ScopedComPtr<IAccessible> document_accessible(
      GetRendererAccessible());
  ASSERT_NE(document_accessible.Get(), reinterpret_cast<IAccessible*>(NULL));

  // Get the ISimpleDOM object for the document.
  base::win::ScopedComPtr<IServiceProvider> service_provider;
  HRESULT hr = static_cast<IAccessible*>(document_accessible.Get())
                   ->QueryInterface(service_provider.GetAddressOf());
  ASSERT_EQ(S_OK, hr);
  const GUID refguid = {0x0c539790,
                        0x12e4,
                        0x11cf,
                        {0xb6, 0x61, 0x00, 0xaa, 0x00, 0x4c, 0xd6, 0xd8}};
  base::win::ScopedComPtr<ISimpleDOMNode> document_isimpledomnode;
  hr = service_provider->QueryService(refguid,
                                      IID_PPV_ARGS(&document_isimpledomnode));
  ASSERT_EQ(S_OK, hr);

  base::win::ScopedBstr node_name;
  short name_space_id;  // NOLINT
  base::win::ScopedBstr node_value;
  unsigned int num_children;
  unsigned int unique_id;
  unsigned short node_type;  // NOLINT
  hr = document_isimpledomnode->get_nodeInfo(
      node_name.Receive(), &name_space_id, node_value.Receive(), &num_children,
      &unique_id, &node_type);
  ASSERT_EQ(S_OK, hr);
  EXPECT_EQ(NODETYPE_DOCUMENT, node_type);
  EXPECT_EQ(1u, num_children);
  node_name.Reset();
  node_value.Reset();

  base::win::ScopedComPtr<ISimpleDOMNode> body_isimpledomnode;
  hr = document_isimpledomnode->get_firstChild(
      body_isimpledomnode.GetAddressOf());
  ASSERT_EQ(S_OK, hr);
  hr = body_isimpledomnode->get_nodeInfo(
      node_name.Receive(), &name_space_id, node_value.Receive(), &num_children,
      &unique_id, &node_type);
  ASSERT_EQ(S_OK, hr);
  EXPECT_EQ(L"body", std::wstring(node_name, node_name.Length()));
  EXPECT_EQ(NODETYPE_ELEMENT, node_type);
  EXPECT_EQ(1u, num_children);
  node_name.Reset();
  node_value.Reset();

  base::win::ScopedComPtr<ISimpleDOMNode> checkbox_isimpledomnode;
  hr = body_isimpledomnode->get_firstChild(
      checkbox_isimpledomnode.GetAddressOf());
  ASSERT_EQ(S_OK, hr);
  hr = checkbox_isimpledomnode->get_nodeInfo(
      node_name.Receive(), &name_space_id, node_value.Receive(), &num_children,
      &unique_id, &node_type);
  ASSERT_EQ(S_OK, hr);
  EXPECT_EQ(L"input", std::wstring(node_name, node_name.Length()));
  EXPECT_EQ(NODETYPE_ELEMENT, node_type);
  EXPECT_EQ(0u, num_children);
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestRoleGroup) {
  LoadInitialAccessibilityTreeFromHtml(
      "<fieldset></fieldset><div role=group></div>");

  // Check the browser's copy of the renderer accessibility tree.
  AccessibleChecker grouping1_checker(std::wstring(), ROLE_SYSTEM_GROUPING,
                                      std::wstring());
  AccessibleChecker grouping2_checker(std::wstring(), ROLE_SYSTEM_GROUPING,
                                      std::wstring());
  AccessibleChecker document_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT,
                                     std::wstring());
  document_checker.AppendExpectedChild(&grouping1_checker);
  document_checker.AppendExpectedChild(&grouping2_checker);
  document_checker.CheckAccessible(GetRendererAccessible());
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       TestCharacterExtentsWithInvalidArguments) {
  base::win::ScopedComPtr<IAccessibleText> paragraph_text;
  SetUpSampleParagraph(&paragraph_text);

  LONG invalid_offset = -3;
  LONG x = -1, y = -1;
  LONG width = -1, height = -1;

  HRESULT hr = paragraph_text->get_characterExtents(
      invalid_offset, IA2_COORDTYPE_SCREEN_RELATIVE, &x, &y, &width, &height);
  EXPECT_EQ(E_INVALIDARG, hr);
  EXPECT_EQ(-1, x);
  EXPECT_EQ(-1, y);
  EXPECT_EQ(-1, width);
  EXPECT_EQ(-1, height);
  hr = paragraph_text->get_characterExtents(
      invalid_offset, IA2_COORDTYPE_PARENT_RELATIVE, &x, &y, &width, &height);
  EXPECT_EQ(E_INVALIDARG, hr);
  EXPECT_EQ(-1, x);
  EXPECT_EQ(-1, y);
  EXPECT_EQ(-1, width);
  EXPECT_EQ(-1, height);

  LONG n_characters;
  ASSERT_HRESULT_SUCCEEDED(paragraph_text->get_nCharacters(&n_characters));
  ASSERT_LT(0, n_characters);

  invalid_offset = n_characters + 1;
  hr = paragraph_text->get_characterExtents(
      invalid_offset, IA2_COORDTYPE_SCREEN_RELATIVE, &x, &y, &width, &height);
  EXPECT_EQ(E_INVALIDARG, hr);
  EXPECT_EQ(-1, x);
  EXPECT_EQ(-1, y);
  EXPECT_EQ(-1, width);
  EXPECT_EQ(-1, height);
  hr = paragraph_text->get_characterExtents(
      invalid_offset, IA2_COORDTYPE_PARENT_RELATIVE, &x, &y, &width, &height);
  EXPECT_EQ(E_INVALIDARG, hr);
  EXPECT_EQ(-1, x);
  EXPECT_EQ(-1, y);
  EXPECT_EQ(-1, width);
  EXPECT_EQ(-1, height);
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestCharacterExtents) {
  base::win::ScopedComPtr<IAccessibleText> paragraph_text;
  SetUpSampleParagraph(&paragraph_text);

  const LONG newline_offset = 46;
  LONG n_characters;
  ASSERT_HRESULT_SUCCEEDED(paragraph_text->get_nCharacters(&n_characters));
  ASSERT_LT(0, n_characters);

  LONG x, y, width, height;
  LONG previous_x, previous_y;
  for (int coordinate = IA2_COORDTYPE_SCREEN_RELATIVE;
       coordinate <= IA2_COORDTYPE_PARENT_RELATIVE; ++coordinate) {
    auto coordinate_type = static_cast<IA2CoordinateType>(coordinate);
    EXPECT_HRESULT_SUCCEEDED(paragraph_text->get_characterExtents(
        0, coordinate_type, &x, &y, &width, &height));
    EXPECT_LT(0, x) << "at offset 0";
    EXPECT_LT(0, y) << "at offset 0";
    EXPECT_LT(0, width) << "at offset 0";
    EXPECT_LT(0, height) << "at offset 0";

    for (LONG offset = 1; offset < newline_offset; ++offset) {
      previous_x = x;
      previous_y = y;

      EXPECT_HRESULT_SUCCEEDED(paragraph_text->get_characterExtents(
          offset, coordinate_type, &x, &y, &width, &height));
      EXPECT_LT(previous_x, x) << "at offset " << offset;
      EXPECT_EQ(previous_y, y) << "at offset " << offset;
      EXPECT_LT(0, width) << "at offset " << offset;
      EXPECT_LT(0, height) << "at offset " << offset;
    }

    EXPECT_HRESULT_SUCCEEDED(paragraph_text->get_characterExtents(
        newline_offset + 1, coordinate_type, &x, &y, &width, &height));
    EXPECT_LE(0, x) << "at offset " << newline_offset + 1;
    EXPECT_GT(previous_x, x) << "at offset " << newline_offset + 1;
    EXPECT_LT(previous_y, y) << "at offset " << newline_offset + 1;
    EXPECT_LT(0, width) << "at offset " << newline_offset + 1;
    EXPECT_LT(0, height) << "at offset " << newline_offset + 1;

    for (LONG offset = newline_offset + 2; offset < n_characters; ++offset) {
      previous_x = x;
      previous_y = y;

      EXPECT_HRESULT_SUCCEEDED(paragraph_text->get_characterExtents(
          offset, coordinate_type, &x, &y, &width, &height));
      EXPECT_LT(previous_x, x) << "at offset " << offset;
      EXPECT_EQ(previous_y, y) << "at offset " << offset;
      EXPECT_LT(0, width) << "at offset " << offset;
      EXPECT_LT(0, height) << "at offset " << offset;
    }
  }
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       TestCharacterExtentsWithAccessibilityModeChange) {
  base::win::ScopedComPtr<IAccessibleText> paragraph_text;
  SetUpSampleParagraph(&paragraph_text, ui::AXMode::kNativeAPIs |
                                            ui::AXMode::kWebContents |
                                            ui::AXMode::kScreenReader);

  LONG x, y, width, height;
  AccessibilityNotificationWaiter waiter(shell()->web_contents(),
                                         ui::AXMode::kNativeAPIs |
                                             ui::AXMode::kWebContents |
                                             ui::AXMode::kScreenReader,
                                         ui::AX_EVENT_LOAD_COMPLETE);
  EXPECT_HRESULT_SUCCEEDED(paragraph_text->get_characterExtents(
      0, IA2_COORDTYPE_SCREEN_RELATIVE, &x, &y, &width, &height));
  // X and y coordinates should be available without
  // |ui::AXMode::kInlineTextBoxes|.
  EXPECT_LT(0, x);
  EXPECT_LT(0, y);
  // Width and height should be unavailable at this point.
  EXPECT_EQ(0, width);
  EXPECT_EQ(0, height);
  waiter.WaitForNotification();
  // Inline text boxes should have been enabled by this point.
  EXPECT_HRESULT_SUCCEEDED(paragraph_text->get_characterExtents(
      0, IA2_COORDTYPE_SCREEN_RELATIVE, &x, &y, &width, &height));
  EXPECT_LT(0, x);
  EXPECT_LT(0, y);
  EXPECT_LT(0, width);
  EXPECT_LT(0, height);
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestScrollToPoint) {
  base::win::ScopedComPtr<IAccessibleText> accessible_text;
  SetUpSampleParagraph(&accessible_text);
  base::win::ScopedComPtr<IAccessible2> paragraph;
  ASSERT_HRESULT_SUCCEEDED(
      accessible_text.CopyTo(IID_PPV_ARGS(&paragraph)));

  LONG prev_x, prev_y, x, y, width, height;
  base::win::ScopedVariant childid_self(CHILDID_SELF);
  ASSERT_HRESULT_SUCCEEDED(
      paragraph->accLocation(&prev_x, &prev_y, &width, &height, childid_self));
  AccessibilityNotificationWaiter location_changed_waiter(
      shell()->web_contents(), ui::kAXModeComplete,
      ui::AX_EVENT_LOCATION_CHANGED);
  EXPECT_HRESULT_SUCCEEDED(
      paragraph->scrollToPoint(IA2_COORDTYPE_PARENT_RELATIVE, 0, 0));
  location_changed_waiter.WaitForNotification();

  ASSERT_HRESULT_SUCCEEDED(
      paragraph->accLocation(&x, &y, &width, &height, childid_self));
  EXPECT_EQ(prev_x, x);
  EXPECT_GT(prev_y, y);

  prev_x = x;
  prev_y = y;
  EXPECT_HRESULT_SUCCEEDED(
      paragraph->scrollToPoint(IA2_COORDTYPE_SCREEN_RELATIVE, 0, 0));
  location_changed_waiter.WaitForNotification();
  ASSERT_HRESULT_SUCCEEDED(
      paragraph->accLocation(&x, &y, &width, &height, childid_self));
  EXPECT_EQ(prev_x, x);
  EXPECT_EQ(prev_y, y);
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestSetCaretOffset) {
  base::win::ScopedComPtr<IAccessibleText> input_text;
  SetUpInputField(&input_text);

  LONG caret_offset = 0;
  HRESULT hr = input_text->get_caretOffset(&caret_offset);
  EXPECT_EQ(S_OK, hr);
  EXPECT_EQ(CONTENTS_LENGTH - 1, caret_offset);

  AccessibilityNotificationWaiter waiter(shell()->web_contents(),
                                         ui::kAXModeComplete,
                                         ui::AX_EVENT_TEXT_SELECTION_CHANGED);
  caret_offset = 0;
  hr = input_text->setCaretOffset(caret_offset);
  EXPECT_EQ(S_OK, hr);
  waiter.WaitForNotification();

  hr = input_text->get_caretOffset(&caret_offset);
  EXPECT_EQ(S_OK, hr);
  EXPECT_EQ(0, caret_offset);
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       TestMultiLineSetCaretOffset) {
  base::win::ScopedComPtr<IAccessibleText> textarea_text;
  SetUpTextareaField(&textarea_text);

    LONG caret_offset = 0;
  HRESULT hr = textarea_text->get_caretOffset(&caret_offset);
  EXPECT_EQ(S_OK, hr);
  EXPECT_EQ(CONTENTS_LENGTH - 1, caret_offset);

  AccessibilityNotificationWaiter waiter(shell()->web_contents(),
                                         ui::kAXModeComplete,
                                         ui::AX_EVENT_TEXT_SELECTION_CHANGED);
  caret_offset = 0;
  hr = textarea_text->setCaretOffset(caret_offset);
  EXPECT_EQ(S_OK, hr);
  waiter.WaitForNotification();

  hr = textarea_text->get_caretOffset(&caret_offset);
  EXPECT_EQ(S_OK, hr);
  EXPECT_EQ(0, caret_offset);
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestSetSelection) {
  base::win::ScopedComPtr<IAccessibleText> input_text;
  SetUpInputField(&input_text);

  LONG start_offset, end_offset;
  EXPECT_HRESULT_FAILED(
      input_text->get_selection(1, &start_offset, &end_offset));
  HRESULT hr = input_text->get_selection(0, &start_offset, &end_offset);
  // There is no selection, just a caret.
  EXPECT_EQ(E_INVALIDARG, hr);

  AccessibilityNotificationWaiter waiter(shell()->web_contents(),
                                         ui::kAXModeComplete,
                                         ui::AX_EVENT_TEXT_SELECTION_CHANGED);
  start_offset = 0;
  end_offset = CONTENTS_LENGTH;
  EXPECT_HRESULT_FAILED(input_text->setSelection(1, start_offset, end_offset));
  EXPECT_HRESULT_SUCCEEDED(
      input_text->setSelection(0, start_offset, end_offset));
  waiter.WaitForNotification();

  hr = input_text->get_selection(0, &start_offset, &end_offset);
  EXPECT_EQ(S_OK, hr);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(CONTENTS_LENGTH, end_offset);

  start_offset = CONTENTS_LENGTH;
  end_offset = 1;
  EXPECT_HRESULT_SUCCEEDED(
      input_text->setSelection(0, start_offset, end_offset));
  waiter.WaitForNotification();

  hr = input_text->get_selection(0, &start_offset, &end_offset);
  EXPECT_EQ(S_OK, hr);
  // Start and end offsets are always swapped to be in ascending order.
  EXPECT_EQ(1, start_offset);
  EXPECT_EQ(CONTENTS_LENGTH, end_offset);
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestMultiLineSetSelection) {
  base::win::ScopedComPtr<IAccessibleText> textarea_text;
  SetUpTextareaField(&textarea_text);

  LONG start_offset, end_offset;
  EXPECT_HRESULT_FAILED(
      textarea_text->get_selection(1, &start_offset, &end_offset));
  HRESULT hr = textarea_text->get_selection(0, &start_offset, &end_offset);
  // There is no selection, just a caret.
  EXPECT_EQ(E_INVALIDARG, hr);

  AccessibilityNotificationWaiter waiter(shell()->web_contents(),
                                         ui::kAXModeComplete,
                                         ui::AX_EVENT_TEXT_SELECTION_CHANGED);
  start_offset = 0;
  end_offset = CONTENTS_LENGTH;
  EXPECT_HRESULT_FAILED(
      textarea_text->setSelection(1, start_offset, end_offset));
  EXPECT_HRESULT_SUCCEEDED(
      textarea_text->setSelection(0, start_offset, end_offset));
  waiter.WaitForNotification();

  hr = textarea_text->get_selection(0, &start_offset, &end_offset);
  EXPECT_EQ(S_OK, hr);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(CONTENTS_LENGTH, end_offset);

  start_offset = CONTENTS_LENGTH - 1;
  end_offset = 0;
  EXPECT_HRESULT_SUCCEEDED(
      textarea_text->setSelection(0, start_offset, end_offset));
  waiter.WaitForNotification();

  hr = textarea_text->get_selection(0, &start_offset, &end_offset);
  EXPECT_EQ(S_OK, hr);
  // Start and end offsets are always swapped to be in ascending order.
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(CONTENTS_LENGTH - 1, end_offset);
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       TestStaticTextSetSelection) {
  base::win::ScopedComPtr<IAccessibleText> paragraph_text;
  SetUpSampleParagraph(&paragraph_text);

  LONG n_characters;
  ASSERT_HRESULT_SUCCEEDED(paragraph_text->get_nCharacters(&n_characters));
  ASSERT_LT(0, n_characters);

  AccessibilityNotificationWaiter waiter(
      shell()->web_contents(), ui::kAXModeComplete,
      ui::AX_EVENT_DOCUMENT_SELECTION_CHANGED);
  LONG start_offset = 0;
  LONG end_offset = n_characters;
  EXPECT_HRESULT_FAILED(
      paragraph_text->setSelection(1, start_offset, end_offset));
  EXPECT_HRESULT_SUCCEEDED(
      paragraph_text->setSelection(0, start_offset, end_offset));
  waiter.WaitForNotification();

  HRESULT hr = paragraph_text->get_selection(0, &start_offset, &end_offset);
  EXPECT_EQ(S_OK, hr);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(n_characters, end_offset);

  start_offset = n_characters - 1;
  end_offset = 0;
  EXPECT_HRESULT_SUCCEEDED(
      paragraph_text->setSelection(0, start_offset, end_offset));
  waiter.WaitForNotification();

  hr = paragraph_text->get_selection(0, &start_offset, &end_offset);
  EXPECT_EQ(S_OK, hr);
  // Start and end offsets are always swapped to be in ascending order.
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(n_characters - 1, end_offset);
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       TestTextAtOffsetWithInvalidArguments) {
  base::win::ScopedComPtr<IAccessibleText> input_text;
  SetUpInputField(&input_text);
  HRESULT hr = input_text->get_textAtOffset(
      0, IA2_TEXT_BOUNDARY_CHAR, NULL, NULL, NULL);
  EXPECT_EQ(E_INVALIDARG, hr);

  // Test invalid offset.
  LONG start_offset = 0;
  LONG end_offset = 0;
  base::win::ScopedBstr text;
  LONG invalid_offset = -5;
  hr = input_text->get_textAtOffset(
      invalid_offset, IA2_TEXT_BOUNDARY_CHAR,
      &start_offset, &end_offset, text.Receive());
  EXPECT_EQ(E_INVALIDARG, hr);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(0, end_offset);
  EXPECT_EQ(nullptr, static_cast<BSTR>(text));
  invalid_offset = CONTENTS_LENGTH + 1;
  hr = input_text->get_textAtOffset(
      invalid_offset, IA2_TEXT_BOUNDARY_WORD,
      &start_offset, &end_offset, text.Receive());
  EXPECT_EQ(E_INVALIDARG, hr);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(0, end_offset);
  EXPECT_EQ(nullptr, static_cast<BSTR>(text));

  // According to the IA2 Spec, only line boundaries should succeed when
  // the offset is one past the end of the text.
  invalid_offset = CONTENTS_LENGTH;
  hr = input_text->get_textAtOffset(
      invalid_offset, IA2_TEXT_BOUNDARY_CHAR,
      &start_offset, &end_offset, text.Receive());
  EXPECT_EQ(S_FALSE, hr);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(0, end_offset);
  EXPECT_EQ(nullptr, static_cast<BSTR>(text));
  hr = input_text->get_textAtOffset(
      invalid_offset, IA2_TEXT_BOUNDARY_WORD,
      &start_offset, &end_offset, text.Receive());
  EXPECT_EQ(S_FALSE, hr);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(0, end_offset);
  EXPECT_EQ(nullptr, static_cast<BSTR>(text));
  hr = input_text->get_textAtOffset(
      invalid_offset, IA2_TEXT_BOUNDARY_SENTENCE,
      &start_offset, &end_offset, text.Receive());
  EXPECT_EQ(S_FALSE, hr);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(0, end_offset);
  EXPECT_EQ(nullptr, static_cast<BSTR>(text));
  hr = input_text->get_textAtOffset(
      invalid_offset, IA2_TEXT_BOUNDARY_ALL,
      &start_offset, &end_offset, text.Receive());
  EXPECT_EQ(S_FALSE, hr);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(0, end_offset);
  EXPECT_EQ(nullptr, static_cast<BSTR>(text));

  // The same behavior should be observed when the special offset
  // IA2_TEXT_OFFSET_LENGTH is used.
  hr = input_text->get_textAtOffset(
      IA2_TEXT_OFFSET_LENGTH, IA2_TEXT_BOUNDARY_CHAR,
      &start_offset, &end_offset, text.Receive());
  EXPECT_EQ(S_FALSE, hr);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(0, end_offset);
  EXPECT_EQ(nullptr, static_cast<BSTR>(text));
  hr = input_text->get_textAtOffset(
      IA2_TEXT_OFFSET_LENGTH, IA2_TEXT_BOUNDARY_WORD,
      &start_offset, &end_offset, text.Receive());
  EXPECT_EQ(S_FALSE, hr);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(0, end_offset);
  EXPECT_EQ(nullptr, static_cast<BSTR>(text));
  hr = input_text->get_textAtOffset(
      IA2_TEXT_OFFSET_LENGTH, IA2_TEXT_BOUNDARY_SENTENCE,
      &start_offset, &end_offset, text.Receive());
  EXPECT_EQ(S_FALSE, hr);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(0, end_offset);
  EXPECT_EQ(nullptr, static_cast<BSTR>(text));
  hr = input_text->get_textAtOffset(
      IA2_TEXT_OFFSET_LENGTH, IA2_TEXT_BOUNDARY_ALL,
      &start_offset, &end_offset, text.Receive());
  EXPECT_EQ(S_FALSE, hr);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(0, end_offset);
  EXPECT_EQ(nullptr, static_cast<BSTR>(text));
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       TestMultiLineTextAtOffsetWithInvalidArguments) {
  base::win::ScopedComPtr<IAccessibleText> textarea_text;
  SetUpTextareaField(&textarea_text);
  HRESULT hr = textarea_text->get_textAtOffset(
      0, IA2_TEXT_BOUNDARY_CHAR, NULL, NULL, NULL);
  EXPECT_EQ(E_INVALIDARG, hr);

  // Test invalid offset.
  LONG start_offset = 0;
  LONG end_offset = 0;
  base::win::ScopedBstr text;
  LONG invalid_offset = -5;
  hr = textarea_text->get_textAtOffset(
      invalid_offset, IA2_TEXT_BOUNDARY_CHAR,
      &start_offset, &end_offset, text.Receive());
  EXPECT_EQ(E_INVALIDARG, hr);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(0, end_offset);
  EXPECT_EQ(nullptr, static_cast<BSTR>(text));
  invalid_offset = CONTENTS_LENGTH + 1;
  hr = textarea_text->get_textAtOffset(
      invalid_offset, IA2_TEXT_BOUNDARY_WORD,
      &start_offset, &end_offset, text.Receive());
  EXPECT_EQ(E_INVALIDARG, hr);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(0, end_offset);
  EXPECT_EQ(nullptr, static_cast<BSTR>(text));

  // According to the IA2 Spec, only line boundaries should succeed when
  // the offset is one past the end of the text.
  invalid_offset = CONTENTS_LENGTH;
  hr = textarea_text->get_textAtOffset(
      invalid_offset, IA2_TEXT_BOUNDARY_CHAR,
      &start_offset, &end_offset, text.Receive());
  EXPECT_EQ(S_FALSE, hr);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(0, end_offset);
  EXPECT_EQ(nullptr, static_cast<BSTR>(text));
  hr = textarea_text->get_textAtOffset(
      invalid_offset, IA2_TEXT_BOUNDARY_WORD,
      &start_offset, &end_offset, text.Receive());
  EXPECT_EQ(S_FALSE, hr);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(0, end_offset);
  EXPECT_EQ(nullptr, static_cast<BSTR>(text));
  hr = textarea_text->get_textAtOffset(
      invalid_offset, IA2_TEXT_BOUNDARY_SENTENCE,
      &start_offset, &end_offset, text.Receive());
  EXPECT_EQ(S_FALSE, hr);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(0, end_offset);
  EXPECT_EQ(nullptr, static_cast<BSTR>(text));
  hr = textarea_text->get_textAtOffset(
      invalid_offset, IA2_TEXT_BOUNDARY_ALL,
      &start_offset, &end_offset, text.Receive());
  EXPECT_EQ(S_FALSE, hr);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(0, end_offset);
  EXPECT_EQ(nullptr, static_cast<BSTR>(text));

  // The same behavior should be observed when the special offset
  // IA2_TEXT_OFFSET_LENGTH is used.
  hr = textarea_text->get_textAtOffset(
      IA2_TEXT_OFFSET_LENGTH, IA2_TEXT_BOUNDARY_CHAR,
      &start_offset, &end_offset, text.Receive());
  EXPECT_EQ(S_FALSE, hr);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(0, end_offset);
  EXPECT_EQ(nullptr, static_cast<BSTR>(text));
  hr = textarea_text->get_textAtOffset(
      IA2_TEXT_OFFSET_LENGTH, IA2_TEXT_BOUNDARY_WORD,
      &start_offset, &end_offset, text.Receive());
  EXPECT_EQ(S_FALSE, hr);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(0, end_offset);
  EXPECT_EQ(nullptr, static_cast<BSTR>(text));
  hr = textarea_text->get_textAtOffset(
      IA2_TEXT_OFFSET_LENGTH, IA2_TEXT_BOUNDARY_SENTENCE,
      &start_offset, &end_offset, text.Receive());
  EXPECT_EQ(S_FALSE, hr);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(0, end_offset);
  EXPECT_EQ(nullptr, static_cast<BSTR>(text));
  hr = textarea_text->get_textAtOffset(
      IA2_TEXT_OFFSET_LENGTH, IA2_TEXT_BOUNDARY_ALL,
      &start_offset, &end_offset, text.Receive());
  EXPECT_EQ(S_FALSE, hr);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(0, end_offset);
  EXPECT_EQ(nullptr, static_cast<BSTR>(text));
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       TestTextAtOffsetWithBoundaryCharacter) {
  base::win::ScopedComPtr<IAccessibleText> input_text;
  SetUpInputField(&input_text);
  for (LONG offset = 0; offset < CONTENTS_LENGTH; ++offset) {
    std::wstring expected_text(1, INPUT_CONTENTS[offset]);
    LONG expected_start_offset = offset;
    LONG expected_end_offset = offset + 1;
    CheckTextAtOffset(input_text, offset, IA2_TEXT_BOUNDARY_CHAR,
        expected_start_offset, expected_end_offset, expected_text);
  }

  for (LONG offset = CONTENTS_LENGTH - 1; offset >= 0; --offset) {
    std::wstring expected_text(1, INPUT_CONTENTS[offset]);
    LONG expected_start_offset = offset;
    LONG expected_end_offset = offset + 1;
    CheckTextAtOffset(input_text, offset, IA2_TEXT_BOUNDARY_CHAR,
        expected_start_offset, expected_end_offset, expected_text);
  }

  CheckTextAtOffset(input_text, IA2_TEXT_OFFSET_CARET,
      IA2_TEXT_BOUNDARY_CHAR, CONTENTS_LENGTH - 1, CONTENTS_LENGTH, L".");
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
    TestMultiLineTextAtOffsetWithBoundaryCharacter) {
  base::win::ScopedComPtr<IAccessibleText> textarea_text;
  SetUpTextareaField(&textarea_text);
  for (LONG offset = 0; offset < CONTENTS_LENGTH; ++offset) {
    std::wstring expected_text(1, TEXTAREA_CONTENTS[offset]);
    LONG expected_start_offset = offset;
    LONG expected_end_offset = offset + 1;
    CheckTextAtOffset(textarea_text, offset, IA2_TEXT_BOUNDARY_CHAR,
        expected_start_offset, expected_end_offset, expected_text);
  }

  for (LONG offset = CONTENTS_LENGTH - 1; offset >= 0; --offset) {
    std::wstring expected_text(1, TEXTAREA_CONTENTS[offset]);
    LONG expected_start_offset = offset;
    LONG expected_end_offset = offset + 1;
    CheckTextAtOffset(textarea_text, offset, IA2_TEXT_BOUNDARY_CHAR,
        expected_start_offset, expected_end_offset, expected_text);
  }

  CheckTextAtOffset(textarea_text, IA2_TEXT_OFFSET_CARET,
      IA2_TEXT_BOUNDARY_CHAR, CONTENTS_LENGTH - 1, CONTENTS_LENGTH, L".");
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       TestTextAtOffsetWithBoundaryWord) {
  base::win::ScopedComPtr<IAccessibleText> input_text;
  SetUpInputField(&input_text);

  // Trailing punctuation should be included as part of the previous word.
  CheckTextAtOffset(input_text, 0, IA2_TEXT_BOUNDARY_WORD,
      0, 4, L"Moz/");
  CheckTextAtOffset(input_text, 2, IA2_TEXT_BOUNDARY_WORD,
      0, 4, L"Moz/");

  // If the offset is at the punctuation, it should return
  // the previous word.
  CheckTextAtOffset(input_text, 3, IA2_TEXT_BOUNDARY_WORD,
      0, 4, L"Moz/");

  // Numbers with a decimal point ("." for U.S), should be treated as one word.
  // Also, trailing punctuation that occurs after empty space should be part of
  // the word. ("5.0 (" and not "5.0 ".)
  CheckTextAtOffset(input_text, 4, IA2_TEXT_BOUNDARY_WORD,
      4, 9, L"5.0 (");
  CheckTextAtOffset(input_text, 5, IA2_TEXT_BOUNDARY_WORD,
      4, 9, L"5.0 (");
  CheckTextAtOffset(input_text, 6, IA2_TEXT_BOUNDARY_WORD,
      4, 9, L"5.0 (");
  CheckTextAtOffset(input_text, 7, IA2_TEXT_BOUNDARY_WORD,
      4, 9, L"5.0 (");

  // Leading punctuation should not be included with the word after it.
  CheckTextAtOffset(input_text, 8, IA2_TEXT_BOUNDARY_WORD,
      4, 9, L"5.0 (");
  CheckTextAtOffset(input_text, 11, IA2_TEXT_BOUNDARY_WORD,
      9, 12, L"ST ");

  // Numbers separated from letters with trailing punctuation should
  // be split into two words. Same for abreviations like "i.e.".
  CheckTextAtOffset(input_text, 12, IA2_TEXT_BOUNDARY_WORD,
      12, 14, L"6.");
  CheckTextAtOffset(input_text, 15, IA2_TEXT_BOUNDARY_WORD,
      14, 17, L"x; ");

  // Words with numbers should be treated like ordinary words.
  CheckTextAtOffset(input_text, 17, IA2_TEXT_BOUNDARY_WORD,
      17, 24, L"WWW33) ");
  CheckTextAtOffset(input_text, 23, IA2_TEXT_BOUNDARY_WORD,
      17, 24, L"WWW33) ");

  // Multiple trailing empty spaces should be part of the word preceding it.
  CheckTextAtOffset(input_text, 28, IA2_TEXT_BOUNDARY_WORD,
      24, 33, L"WebKit  \"");
  CheckTextAtOffset(input_text, 31, IA2_TEXT_BOUNDARY_WORD,
      24, 33, L"WebKit  \"");
  CheckTextAtOffset(input_text, 32, IA2_TEXT_BOUNDARY_WORD,
      24, 33, L"WebKit  \"");

  // Leading punctuation such as quotation marks should not be part of the word.
  CheckTextAtOffset(input_text, 33, IA2_TEXT_BOUNDARY_WORD,
      33, 40, L"KHTML, ");
  CheckTextAtOffset(input_text, 38, IA2_TEXT_BOUNDARY_WORD,
      33, 40, L"KHTML, ");

  // Trailing final punctuation should be part of the last word.
  CheckTextAtOffset(input_text, 41, IA2_TEXT_BOUNDARY_WORD,
      40, CONTENTS_LENGTH, L"like\".");
  CheckTextAtOffset(input_text, 45, IA2_TEXT_BOUNDARY_WORD,
      40, CONTENTS_LENGTH, L"like\".");

  // Test special offsets.
  CheckTextAtOffset(input_text, IA2_TEXT_OFFSET_CARET,
      IA2_TEXT_BOUNDARY_WORD, 40, CONTENTS_LENGTH, L"like\".");
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
    TestMultiLineTextAtOffsetWithBoundaryWord) {
  base::win::ScopedComPtr<IAccessibleText> textarea_text;
  SetUpTextareaField(&textarea_text);

  // Trailing punctuation should be included as part of the previous word.
  CheckTextAtOffset(textarea_text, 0, IA2_TEXT_BOUNDARY_WORD,
      0, 4, L"Moz/");
  CheckTextAtOffset(textarea_text, 2, IA2_TEXT_BOUNDARY_WORD,
      0, 4, L"Moz/");

  // If the offset is at the punctuation, it should return
  // the previous word.
  CheckTextAtOffset(textarea_text, 3, IA2_TEXT_BOUNDARY_WORD,
      0, 4, L"Moz/");

  // Numbers with a decimal point ("." for U.S), should be treated as one word.
  // Also, trailing punctuation that occurs after empty space should be part of
  // the word. ("5.0 (" and not "5.0 ".)
  CheckTextAtOffset(textarea_text, 4, IA2_TEXT_BOUNDARY_WORD,
      4, 9, L"5.0 (");
  CheckTextAtOffset(textarea_text, 5, IA2_TEXT_BOUNDARY_WORD,
      4, 9, L"5.0 (");
  CheckTextAtOffset(textarea_text, 6, IA2_TEXT_BOUNDARY_WORD,
      4, 9, L"5.0 (");
  CheckTextAtOffset(textarea_text, 7, IA2_TEXT_BOUNDARY_WORD,
      4, 9, L"5.0 (");

  // Leading punctuation should not be included with the word after it.
  CheckTextAtOffset(textarea_text, 8, IA2_TEXT_BOUNDARY_WORD,
      4, 9, L"5.0 (");
  CheckTextAtOffset(textarea_text, 11, IA2_TEXT_BOUNDARY_WORD,
      9, 12, L"ST ");

  // Numbers separated from letters with trailing punctuation should
  // be split into two words. Same for abreviations like "i.e.".
  CheckTextAtOffset(textarea_text, 12, IA2_TEXT_BOUNDARY_WORD,
      12, 14, L"6.");
  CheckTextAtOffset(textarea_text, 15, IA2_TEXT_BOUNDARY_WORD,
      14, 17, L"x; ");

  // Words with numbers should be treated like ordinary words.
  CheckTextAtOffset(textarea_text, 17, IA2_TEXT_BOUNDARY_WORD,
      17, 24, L"WWW33)\n");
  CheckTextAtOffset(textarea_text, 23, IA2_TEXT_BOUNDARY_WORD,
      17, 24, L"WWW33)\n");

  // Multiple trailing empty spaces should be part of the word preceding it.
  CheckTextAtOffset(textarea_text, 28, IA2_TEXT_BOUNDARY_WORD,
      24, 33, L"WebKit \n\"");
  CheckTextAtOffset(textarea_text, 31, IA2_TEXT_BOUNDARY_WORD,
      24, 33, L"WebKit \n\"");
  CheckTextAtOffset(textarea_text, 32, IA2_TEXT_BOUNDARY_WORD,
      24, 33, L"WebKit \n\"");

  // Leading punctuation such as quotation marks should not be part of the word.
  CheckTextAtOffset(textarea_text, 33, IA2_TEXT_BOUNDARY_WORD,
      33, 40, L"KHTML, ");
  CheckTextAtOffset(textarea_text, 38, IA2_TEXT_BOUNDARY_WORD,
      33, 40, L"KHTML, ");

  // Trailing final punctuation should be part of the last word.
  CheckTextAtOffset(textarea_text, 41, IA2_TEXT_BOUNDARY_WORD,
      40, CONTENTS_LENGTH, L"like\".");
  CheckTextAtOffset(textarea_text, 45, IA2_TEXT_BOUNDARY_WORD,
      40, CONTENTS_LENGTH, L"like\".");

  // Test special offsets.
  CheckTextAtOffset(textarea_text, IA2_TEXT_OFFSET_CARET,
      IA2_TEXT_BOUNDARY_WORD, 40, CONTENTS_LENGTH, L"like\".");
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       TestStaticTextAtOffsetWithBoundaryWord) {
  base::win::ScopedComPtr<IAccessibleText> paragraph_text;
  SetUpSampleParagraph(&paragraph_text);
  base::string16 embedded_character(
      1, BrowserAccessibilityComWin::kEmbeddedCharacter);
  std::vector<std::wstring> words;
  words.push_back(L"Game ");
  words.push_back(L"theory ");
  words.push_back(L"is \"");
  words.push_back(L"the ");
  words.push_back(L"study ");
  words.push_back(L"of ");
  words.push_back(embedded_character);
  words.push_back(L"of ");
  words.push_back(L"conflict ");
  words.push_back(L"and\n");
  words.push_back(L"cooperation ");
  words.push_back(L"between ");
  words.push_back(L"intelligent ");
  words.push_back(L"rational ");
  words.push_back(L"decision-");
  words.push_back(L"makers.\"");

  // Try to retrieve one word after another.
  LONG word_start_offset = 0;
  for (auto& word : words) {
    LONG word_end_offset = word_start_offset + word.size();
    CheckTextAtOffset(paragraph_text, word_start_offset, IA2_TEXT_BOUNDARY_WORD,
                      word_start_offset, word_end_offset, word);
    word_start_offset = word_end_offset;
    // If the word boundary is inside an embedded object, |word_end_offset|
    // should be one past the embedded object character. To get to the start of
    // the next word, we have to skip the space between the embedded object
    // character and the next word.
    if (word == embedded_character)
      ++word_start_offset;
  }
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       TestTextAtOffsetWithBoundarySentence) {
  base::win::ScopedComPtr<IAccessibleText> input_text;
  SetUpInputField(&input_text);

  // Sentence navigation is not currently implemented.
  LONG start_offset = 0;
  LONG end_offset = 0;
  base::win::ScopedBstr text;
  HRESULT hr = input_text->get_textAtOffset(
      5, IA2_TEXT_BOUNDARY_SENTENCE,
      &start_offset, &end_offset, text.Receive());
  EXPECT_EQ(S_FALSE, hr);
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       TestMultiLineTextAtOffsetWithBoundarySentence) {
  base::win::ScopedComPtr<IAccessibleText> textarea_text;
  SetUpTextareaField(&textarea_text);

  // Sentence navigation is not currently implemented.
  LONG start_offset = 0;
  LONG end_offset = 0;
  base::win::ScopedBstr text;
  HRESULT hr = textarea_text->get_textAtOffset(
      25, IA2_TEXT_BOUNDARY_SENTENCE,
      &start_offset, &end_offset, text.Receive());
  EXPECT_EQ(S_FALSE, hr);
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       TestTextAtOffsetWithBoundaryLine) {
  base::win::ScopedComPtr<IAccessibleText> input_text;
  SetUpInputField(&input_text);

  // Single line text fields should return the whole text.
  CheckTextAtOffset(input_text, 0, IA2_TEXT_BOUNDARY_LINE,
      0, CONTENTS_LENGTH, base::SysUTF8ToWide(INPUT_CONTENTS));

  // Test special offsets.
  CheckTextAtOffset(input_text, IA2_TEXT_OFFSET_LENGTH, IA2_TEXT_BOUNDARY_LINE,
      0, CONTENTS_LENGTH, base::SysUTF8ToWide(INPUT_CONTENTS));
  CheckTextAtOffset(input_text, IA2_TEXT_OFFSET_CARET, IA2_TEXT_BOUNDARY_LINE,
      0, CONTENTS_LENGTH, base::SysUTF8ToWide(INPUT_CONTENTS));
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
    TestMultiLineTextAtOffsetWithBoundaryLine) {
  base::win::ScopedComPtr<IAccessibleText> textarea_text;
  SetUpTextareaField(&textarea_text);

  CheckTextAtOffset(textarea_text, 0, IA2_TEXT_BOUNDARY_LINE,
      0, 24, L"Moz/5.0 (ST 6.x; WWW33)\n");

  // If the offset is at the newline, return the line preceding it.
  CheckTextAtOffset(textarea_text, 31, IA2_TEXT_BOUNDARY_LINE,
      24, 32, L"WebKit \n");

  // Last line does not have a trailing newline.
  CheckTextAtOffset(textarea_text, 32, IA2_TEXT_BOUNDARY_LINE,
      32, CONTENTS_LENGTH, L"\"KHTML, like\".");

  // An offset one past the last character should return the last line.
  CheckTextAtOffset(textarea_text, CONTENTS_LENGTH, IA2_TEXT_BOUNDARY_LINE,
      32, CONTENTS_LENGTH, L"\"KHTML, like\".");

  // Test special offsets.
  CheckTextAtOffset(textarea_text, IA2_TEXT_OFFSET_LENGTH,
      IA2_TEXT_BOUNDARY_LINE, 32, CONTENTS_LENGTH, L"\"KHTML, like\".");
  CheckTextAtOffset(textarea_text, IA2_TEXT_OFFSET_CARET,
      IA2_TEXT_BOUNDARY_LINE, 32, CONTENTS_LENGTH, L"\"KHTML, like\".");
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       TestParagraphTextAtOffsetWithBoundaryLine) {
  base::win::ScopedComPtr<IAccessibleText> paragraph_text;
  SetUpSampleParagraph(&paragraph_text);

  // There should be two lines in this paragraph.
  const LONG newline_offset = 46;
  LONG n_characters;
  ASSERT_HRESULT_SUCCEEDED(paragraph_text->get_nCharacters(&n_characters));
  ASSERT_LT(0, n_characters);
  ASSERT_LT(newline_offset, n_characters);

  for (LONG i = 0; i <= newline_offset; ++i) {
    CheckTextAtOffset(
        paragraph_text, i, IA2_TEXT_BOUNDARY_LINE, 0, newline_offset + 1,
        L"Game theory is \"the study of \xFFFC of conflict and\n");
  }

  // For line boundaries, IA2 Spec allows for the offset to be equal to the
  // text's length.
  for (LONG i = newline_offset + 1; i <= n_characters; ++i) {
    CheckTextAtOffset(
        paragraph_text, i, IA2_TEXT_BOUNDARY_LINE, newline_offset + 1,
        n_characters,
        L"cooperation between intelligent rational decision-makers.\"");
  }
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       TestTextAtOffsetWithBoundaryAll) {
  base::win::ScopedComPtr<IAccessibleText> input_text;
  SetUpInputField(&input_text);

  CheckTextAtOffset(input_text, 0, IA2_TEXT_BOUNDARY_ALL,
      0, CONTENTS_LENGTH, base::SysUTF8ToWide(INPUT_CONTENTS));
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       TestMultiLineTextAtOffsetWithBoundaryAll) {
  base::win::ScopedComPtr<IAccessibleText> textarea_text;
  SetUpTextareaField(&textarea_text);

  CheckTextAtOffset(textarea_text, CONTENTS_LENGTH - 1, IA2_TEXT_BOUNDARY_ALL,
      0, CONTENTS_LENGTH, base::SysUTF8ToWide(TEXTAREA_CONTENTS));
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestIAccessibleAction) {
  LoadInitialAccessibilityTreeFromHtml(
      "<!DOCTYPE html><html><body>"
      "<img src=\"\" alt=\"image\" "
      "onclick=\"document.querySelector('img').alt = 'image2';\">"
      "</body></html>");

  // Retrieve the IAccessible interface for the web page.
  base::win::ScopedComPtr<IAccessible> document(GetRendererAccessible());
  std::vector<base::win::ScopedVariant> document_children =
      GetAllAccessibleChildren(document.Get());
  ASSERT_EQ(1u, document_children.size());

  base::win::ScopedComPtr<IAccessible2> div;
  ASSERT_HRESULT_SUCCEEDED(QueryIAccessible2(
      GetAccessibleFromVariant(document.Get(), document_children[0].AsInput())
          .Get(),
      div.GetAddressOf()));
  std::vector<base::win::ScopedVariant> div_children =
      GetAllAccessibleChildren(div.Get());
  ASSERT_EQ(1u, div_children.size());

  base::win::ScopedComPtr<IAccessible2> image;
  ASSERT_HRESULT_SUCCEEDED(QueryIAccessible2(
      GetAccessibleFromVariant(div.Get(), div_children[0].AsInput()).Get(),
      image.GetAddressOf()));
  LONG image_role = 0;
  ASSERT_HRESULT_SUCCEEDED(image->role(&image_role));
  ASSERT_EQ(ROLE_SYSTEM_GRAPHIC, image_role);

  base::win::ScopedComPtr<IAccessibleAction> image_action;
  ASSERT_HRESULT_SUCCEEDED(image.CopyTo(image_action.GetAddressOf()));

  LONG n_actions = 0;
  EXPECT_HRESULT_SUCCEEDED(image_action->nActions(&n_actions));
  EXPECT_EQ(1, n_actions);

  base::win::ScopedBstr action_name;
  EXPECT_HRESULT_SUCCEEDED(image_action->get_name(0, action_name.Receive()));
  EXPECT_EQ(L"click", std::wstring(action_name, action_name.Length()));
  action_name.Release();
  EXPECT_HRESULT_FAILED(image_action->get_name(1, action_name.Receive()));
  EXPECT_EQ(nullptr, static_cast<BSTR>(action_name));

  base::win::ScopedVariant childid_self(CHILDID_SELF);
  base::win::ScopedBstr image_name;
  EXPECT_HRESULT_SUCCEEDED(
      image->get_accName(childid_self, image_name.Receive()));
  EXPECT_EQ(L"image", std::wstring(image_name, image_name.Length()));
  image_name.Release();
  // Cllicking the image will change its name.
  EXPECT_HRESULT_SUCCEEDED(image_action->doAction(0));
  AccessibilityNotificationWaiter waiter(
      shell()->web_contents(), ui::kAXModeComplete, ui::AX_EVENT_TEXT_CHANGED);
  waiter.WaitForNotification();
  EXPECT_HRESULT_SUCCEEDED(
      image->get_accName(childid_self, image_name.Receive()));
  EXPECT_EQ(L"image2", std::wstring(image_name, image_name.Length()));
  EXPECT_HRESULT_FAILED(image_action->doAction(1));
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, HasHWNDAfterNavigation) {
  // This test simulates a scenario where RenderWidgetHostViewAura::SetSize
  // is not called again after its window is added to the root window.
  // Ensure that we still get a legacy HWND for accessibility.

  ASSERT_TRUE(embedded_test_server()->Start());
  WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
      shell()->web_contents());
  WebContentsView* web_contents_view = web_contents->GetView();
  WebContentsViewAura* web_contents_view_aura =
      static_cast<WebContentsViewAura*>(web_contents_view);

  // Set a flag that will cause WebContentsViewAura to initialize a
  // RenderWidgetHostViewAura with a null parent view.
  web_contents_view_aura->set_init_rwhv_with_null_parent_for_testing(true);

  // Navigate to a new page and wait for the accessibility tree to load.
  AccessibilityNotificationWaiter waiter(
      shell()->web_contents(), ui::kAXModeComplete, ui::AX_EVENT_LOAD_COMPLETE);
  NavigateToURL(shell(), embedded_test_server()->GetURL(
      "/accessibility/html/article.html"));
  waiter.WaitForNotification();

  // At this point the root of the accessibility tree shouldn't have an HWND
  // because we never gave a parent window to the RWHVA.
  BrowserAccessibilityManagerWin* manager =
      static_cast<BrowserAccessibilityManagerWin*>(
          web_contents->GetRootBrowserAccessibilityManager());
  ASSERT_EQ(nullptr, manager->GetParentHWND());

  // Now add the RWHVA's window to the root window and ensure that we have
  // an HWND for accessibility now.
  web_contents_view->GetNativeView()->AddChild(
      web_contents->GetRenderWidgetHostView()->GetNativeView());
  ASSERT_NE(nullptr, manager->GetParentHWND());
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestAccNavigateInTables) {
  ASSERT_TRUE(embedded_test_server()->Start());
  AccessibilityNotificationWaiter waiter(
      shell()->web_contents(), ui::kAXModeComplete, ui::AX_EVENT_LOAD_COMPLETE);
  NavigateToURL(shell(), embedded_test_server()->GetURL(
                             "/accessibility/html/table-spans.html"));
  waiter.WaitForNotification();

  base::win::ScopedComPtr<IAccessible> document(GetRendererAccessible());
  std::vector<base::win::ScopedVariant> document_children =
      GetAllAccessibleChildren(document.Get());
  // There are two tables in this test file. Use only the first one.
  ASSERT_EQ(2u, document_children.size());

  base::win::ScopedComPtr<IAccessible2> table;
  ASSERT_HRESULT_SUCCEEDED(QueryIAccessible2(
      GetAccessibleFromVariant(document.Get(), document_children[0].AsInput())
          .Get(),
      table.GetAddressOf()));
  LONG role = 0;
  ASSERT_HRESULT_SUCCEEDED(table->role(&role));
  ASSERT_EQ(ROLE_SYSTEM_TABLE, role);

  // Retrieve the first cell.
  base::win::ScopedComPtr<IAccessibleTable2> table2;
  base::win::ScopedComPtr<IUnknown> cell;
  base::win::ScopedComPtr<IAccessible2> cell1;
  EXPECT_HRESULT_SUCCEEDED(table.CopyTo(table2.GetAddressOf()));
  EXPECT_HRESULT_SUCCEEDED(table2->get_cellAt(0, 0, cell.GetAddressOf()));
  EXPECT_HRESULT_SUCCEEDED(cell.CopyTo(cell1.GetAddressOf()));

  base::win::ScopedBstr name;
  base::win::ScopedVariant childid_self(CHILDID_SELF);
  base::win::ScopedComPtr<IAccessibleTableCell> accessible_cell;
  LONG row_index = -1;
  LONG column_index = -1;
  EXPECT_HRESULT_SUCCEEDED(cell1->role(&role));
  EXPECT_EQ(ROLE_SYSTEM_CELL, role);
  EXPECT_HRESULT_SUCCEEDED(cell1->get_accName(childid_self, name.Receive()));
  // EXPECT_STREQ(L"AD", name);
  EXPECT_HRESULT_SUCCEEDED(cell1.CopyTo(accessible_cell.GetAddressOf()));
  EXPECT_HRESULT_SUCCEEDED(accessible_cell->get_rowIndex(&row_index));
  EXPECT_HRESULT_SUCCEEDED(accessible_cell->get_columnIndex(&column_index));
  EXPECT_EQ(0, row_index);
  EXPECT_EQ(0, column_index);
  name.Reset();
  accessible_cell.Reset();

  // The first cell has a rowspan of 2, try navigating down and expect to get
  // at the end of the table.
  base::win::ScopedVariant variant;
  EXPECT_HRESULT_SUCCEEDED(
      cell1->accNavigate(NAVDIR_DOWN, childid_self, variant.Receive()));
  ASSERT_EQ(VT_EMPTY, variant.type());

  // Try navigating to the cell in the first row, 2nd column.
  base::win::ScopedComPtr<IAccessible2> cell2;
  EXPECT_HRESULT_SUCCEEDED(
      cell1->accNavigate(NAVDIR_RIGHT, childid_self, variant.Receive()));
  ASSERT_NE(nullptr, V_DISPATCH(variant.AsInput()));
  ASSERT_EQ(VT_DISPATCH, variant.type());
  V_DISPATCH(variant.AsInput())->QueryInterface(cell2.GetAddressOf());
  EXPECT_HRESULT_SUCCEEDED(cell2->role(&role));
  EXPECT_EQ(ROLE_SYSTEM_CELL, role);
  EXPECT_HRESULT_SUCCEEDED(cell2->get_accName(childid_self, name.Receive()));
  // EXPECT_STREQ(L"BC", name);
  EXPECT_HRESULT_SUCCEEDED(cell2.CopyTo(accessible_cell.GetAddressOf()));
  EXPECT_HRESULT_SUCCEEDED(accessible_cell->get_rowIndex(&row_index));
  EXPECT_HRESULT_SUCCEEDED(accessible_cell->get_columnIndex(&column_index));
  EXPECT_EQ(0, row_index);
  EXPECT_EQ(1, column_index);
  variant.Reset();
  name.Reset();
  accessible_cell.Reset();

  // Try navigating to the cell in the second row, 2nd column.
  base::win::ScopedComPtr<IAccessible2> cell3;
  EXPECT_HRESULT_SUCCEEDED(
      cell2->accNavigate(NAVDIR_DOWN, childid_self, variant.Receive()));
  ASSERT_NE(nullptr, V_DISPATCH(variant.AsInput()));
  ASSERT_EQ(VT_DISPATCH, variant.type());
  V_DISPATCH(variant.AsInput())->QueryInterface(cell3.GetAddressOf());
  EXPECT_HRESULT_SUCCEEDED(cell3->role(&role));
  EXPECT_EQ(ROLE_SYSTEM_CELL, role);
  EXPECT_HRESULT_SUCCEEDED(cell3->get_accName(childid_self, name.Receive()));
  // EXPECT_STREQ(L"EF", name);
  EXPECT_HRESULT_SUCCEEDED(cell3.CopyTo(accessible_cell.GetAddressOf()));
  EXPECT_HRESULT_SUCCEEDED(accessible_cell->get_rowIndex(&row_index));
  EXPECT_HRESULT_SUCCEEDED(accessible_cell->get_columnIndex(&column_index));
  EXPECT_EQ(1, row_index);
  EXPECT_EQ(1, column_index);
  variant.Reset();
  name.Reset();
  accessible_cell.Reset();
}

}  // namespace content
