// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <atk/atk.h>

#include <string>
#include <vector>

#include "base/functional/callback_helpers.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/version.h"
#include "build/build_config.h"
#include "content/browser/accessibility/accessibility_browsertest.h"
#include "content/browser/renderer_host/render_widget_host_view_aura.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/test/accessibility_notification_waiter.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/test/content_browser_test_utils_internal.h"
#include "ui/accessibility/platform/ax_platform_node_auralinux.h"
#include "ui/accessibility/platform/browser_accessibility.h"
#include "ui/base/glib/scoped_gsignal.h"

// TODO(crbug.com/40248581): Remove this again.
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

namespace content {

namespace {

const char16_t kBullet[2] = {u'\x2022', ' '};
const std::u16string kString16Bullet = std::u16string(kBullet, 2);

AtkObject* FindAtkObjectParentFrame(AtkObject* atk_object) {
  while (atk_object) {
    if (atk_object_get_role(atk_object) == ATK_ROLE_FRAME) {
      return atk_object;
    }
    atk_object = atk_object_get_parent(atk_object);
  }
  return nullptr;
}

static bool IsAtkObjectFocused(AtkObject* object) {
  AtkStateSet* state_set = atk_object_ref_state_set(object);
  bool result = atk_state_set_contains_state(state_set, ATK_STATE_FOCUSED);
  g_object_unref(state_set);
  return result;
}

static bool IsAtkObjectEditable(AtkObject* object) {
  AtkStateSet* state_set = atk_object_ref_state_set(object);
  bool result = atk_state_set_contains_state(state_set, ATK_STATE_EDITABLE);
  g_object_unref(state_set);
  return result;
}

}  // namespace

class AccessibilityAuraLinuxBrowserTest : public AccessibilityBrowserTest {
 public:
  AccessibilityAuraLinuxBrowserTest() = default;

  AccessibilityAuraLinuxBrowserTest(const AccessibilityAuraLinuxBrowserTest&) =
      delete;
  AccessibilityAuraLinuxBrowserTest& operator=(
      const AccessibilityAuraLinuxBrowserTest&) = delete;

  ~AccessibilityAuraLinuxBrowserTest() override = default;

 protected:
  static bool HasObjectWithAtkRoleFrameInAncestry(AtkObject* object) {
    while (object) {
      if (atk_object_get_role(object) == ATK_ROLE_FRAME) {
        return true;
      }
      object = atk_object_get_parent(object);
    }
    return false;
  }

  // Ensures that the text and the start and end offsets retrieved using
  // get_textAtOffset match the expected values.
  static void CheckTextAtOffset(AtkText* text_object,
                                int offset,
                                AtkTextBoundary boundary_type,
                                int expected_start_offset,
                                int expected_end_offset,
                                const char* expected_text);

  // Loads a page with  an input text field and places sample text in it.
  // Returns a pointer to the field's AtkText interface.
  AtkText* SetUpInputField();

  // Loads a page with  a textarea text field, places sample text in it, and
  // places the caret after the last character.
  //  Returns a pointer to the field's AtkText interface.
  AtkText* SetUpTextareaField();

  // Does a few checks on the scrollable input field and returns
  // a pointer to the field's AtkText interface.
  AtkText* GetScrollableInputField();

  // Loads a page with a paragraph of sample text and returns its AtkText
  // interface.
  AtkText* SetUpSampleParagraph();

  // Retrieves a pointer to the already loaded paragraph's AtkText interface.
  AtkText* GetSampleParagraph();

  // Searches the accessibility tree in pre-order debth-first traversal for a
  // node with the given role and returns its AtkText interface if found,
  // otherwise returns nullptr.
  AtkText* FindNode(const AtkRole role);

  void TestCharacterExtentsInScrollableInput();

 private:
  // Searches the accessibility tree in pre-order debth-first traversal starting
  // at a given node and for a node with the given role and returns its AtkText
  // interface if found, otherwise returns nullptr.
  AtkText* FindNode(AtkObject* root, const AtkRole role) const;
};

void AccessibilityAuraLinuxBrowserTest::CheckTextAtOffset(
    AtkText* text_object,
    int offset,
    AtkTextBoundary boundary_type,
    int expected_start_offset,
    int expected_end_offset,
    const char* expected_text) {
  ::testing::Message message;
  message << "While checking at index \'" << offset << "\' for \'"
          << expected_text << "\' at " << expected_start_offset << '-'
          << expected_end_offset << '.';
  SCOPED_TRACE(message);

  int start_offset = 0;
  int end_offset = 0;
  char* text = atk_text_get_text_at_offset(text_object, offset, boundary_type,
                                           &start_offset, &end_offset);
  EXPECT_EQ(expected_start_offset, start_offset);
  EXPECT_EQ(expected_end_offset, end_offset);
  EXPECT_STREQ(expected_text, text);
  g_free(text);
}

AtkText* AccessibilityAuraLinuxBrowserTest::SetUpInputField() {
  LoadInputField();
  return FindNode(ATK_ROLE_ENTRY);
}

AtkText* AccessibilityAuraLinuxBrowserTest::SetUpTextareaField() {
  LoadTextareaField();
  return FindNode(ATK_ROLE_ENTRY);
}

AtkText* AccessibilityAuraLinuxBrowserTest::SetUpSampleParagraph() {
  LoadSampleParagraph();

  AtkObject* document = GetRendererAccessible();
  EXPECT_EQ(1, atk_object_get_n_accessible_children(document));

  int number_of_children = atk_object_get_n_accessible_children(document);
  EXPECT_LT(0, number_of_children);

  // The input field is always the last child.
  AtkObject* input = atk_object_ref_accessible_child(document, 0);
  EXPECT_EQ(ATK_ROLE_PARAGRAPH, atk_object_get_role(input));

  EXPECT_TRUE(ATK_IS_TEXT(input));
  return ATK_TEXT(input);
}

AtkText* AccessibilityAuraLinuxBrowserTest::GetSampleParagraph() {
  AtkObject* document = GetRendererAccessible();
  EXPECT_EQ(1, atk_object_get_n_accessible_children(document));

  int number_of_children = atk_object_get_n_accessible_children(document);
  EXPECT_LT(0, number_of_children);

  // The paragraph is the last child.
  AtkObject* paragraph = atk_object_ref_accessible_child(document, 0);
  EXPECT_EQ(ATK_ROLE_PARAGRAPH, atk_object_get_role(paragraph));

  EXPECT_TRUE(ATK_IS_TEXT(paragraph));
  return ATK_TEXT(paragraph);
}

AtkText* AccessibilityAuraLinuxBrowserTest::GetScrollableInputField() {
  AtkObject* document = GetRendererAccessible();
  EXPECT_EQ(1, atk_object_get_n_accessible_children(document));

  AtkObject* div = atk_object_ref_accessible_child(document, 0);
  EXPECT_NE(div, nullptr);
  int n_div_children = atk_object_get_n_accessible_children(div);
  EXPECT_GT(n_div_children, 0);

  // The input field is always the last child.
  AtkObject* input = atk_object_ref_accessible_child(div, n_div_children - 1);
  EXPECT_EQ(ATK_ROLE_ENTRY, atk_object_get_role(input));

  // Retrieve the IAccessibleText interface for the field.
  AtkText* atk_text_field = ATK_TEXT(input);

  // Set the caret before the last character.
  AccessibilityNotificationWaiter waiter(
      shell()->web_contents(),
      ui::AXEventGenerator::Event::TEXT_SELECTION_CHANGED);
  long caret_offset = InputContentsString().size() - 1;
  ExecuteScript(base::ASCIIToUTF16(
      base::StrCat({"let textField = document.querySelector('input,textarea');"
                    "textField.focus();"
                    "textField.setSelectionRange(",
                    base::NumberToString(caret_offset), ",",
                    base::NumberToString(caret_offset),
                    ");"
                    "textField.scrollLeft = 1000;"})));
  EXPECT_TRUE(waiter.WaitForNotification());

  g_object_unref(div);
  return atk_text_field;
}

AtkText* AccessibilityAuraLinuxBrowserTest::FindNode(const AtkRole role) {
  AtkObject* document = GetRendererAccessible();
  EXPECT_NE(nullptr, document);
  return FindNode(document, role);
}

AtkText* AccessibilityAuraLinuxBrowserTest::FindNode(AtkObject* root,
                                                     const AtkRole role) const {
  EXPECT_NE(nullptr, root);
  if (atk_object_get_role(root) == role) {
    EXPECT_TRUE(ATK_IS_TEXT(root));
    g_object_ref(root);
    AtkText* root_text = ATK_TEXT(root);
    return root_text;
  }

  for (int i = 0; i < atk_object_get_n_accessible_children(root); ++i) {
    AtkObject* child = atk_object_ref_accessible_child(root, i);
    EXPECT_NE(nullptr, child);
    if (atk_object_get_role(child) == role) {
      EXPECT_TRUE(ATK_IS_TEXT(child));
      AtkText* child_text = ATK_TEXT(child);
      return child_text;
    }

    if (AtkText* descendant_text = FindNode(child, role)) {
      g_object_unref(child);
      return descendant_text;
    }

    g_object_unref(child);
  }

  return nullptr;
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       AuraLinuxBrowserAccessibleParent) {
  LoadInitialAccessibilityTreeFromHtml({});

  // Get the BrowserAccessibilityManager.
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());
  ui::BrowserAccessibilityManager* manager =
      web_contents->GetRootBrowserAccessibilityManager();
  ASSERT_NE(nullptr, manager);

  auto* host_view = static_cast<RenderWidgetHostViewAura*>(
      web_contents->GetRenderWidgetHostView());
  ASSERT_NE(nullptr, host_view->GetNativeViewAccessible());

  AtkObject* host_view_parent =
      host_view->AccessibilityGetNativeViewAccessible();
  ASSERT_NE(nullptr, host_view_parent);
  ASSERT_TRUE(
      AccessibilityAuraLinuxBrowserTest::HasObjectWithAtkRoleFrameInAncestry(
          host_view_parent));
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       TestTextAtOffsetWithBoundaryCharacterAndEmbeddedObject) {
  LoadInitialAccessibilityTreeFromHtml(R"HTML(<!DOCTYPE html>
      <div contenteditable>
        Before<img alt="image">after.
      </div>
      )HTML");

  AtkObject* document = GetRendererAccessible();
  ASSERT_EQ(1, atk_object_get_n_accessible_children(document));

  AtkObject* contenteditable = atk_object_ref_accessible_child(document, 0);
  ASSERT_NE(nullptr, contenteditable);
  ASSERT_EQ(ATK_ROLE_SECTION, atk_object_get_role(contenteditable));
  ASSERT_TRUE(ATK_IS_TEXT(contenteditable));

  AtkText* contenteditable_text = ATK_TEXT(contenteditable);
  int character_count = atk_text_get_character_count(contenteditable_text);
  ASSERT_EQ(13, character_count);

  const std::u16string embedded_character(
      1, ui::AXPlatformNodeAuraLinux::kEmbeddedCharacter);
  const std::vector<std::string> expected_hypertext = {
      "B", "e", "f", "o", "r", "e", base::UTF16ToUTF8(embedded_character),
      "a", "f", "t", "e", "r", "."};

  // "Before".
  //
  // The embedded object character representing the image is at offset 6.
  for (int i = 0; i < 6; ++i) {
    CheckTextAtOffset(contenteditable_text, i, ATK_TEXT_BOUNDARY_CHAR, i,
                      (i + 1), expected_hypertext[i].c_str());
  }

  // "after.".
  //
  // Note that according to the ATK Spec, an offset that is equal to
  // "character_count" is not permitted.
  for (int i = 7; i < character_count; ++i) {
    CheckTextAtOffset(contenteditable_text, i, ATK_TEXT_BOUNDARY_CHAR, i,
                      (i + 1), expected_hypertext[i].c_str());
  }

  ASSERT_EQ(3, atk_object_get_n_accessible_children(contenteditable));
  // The image is the second child.
  AtkObject* image = atk_object_ref_accessible_child(contenteditable, 1);
  ASSERT_NE(nullptr, image);
  ASSERT_EQ(ATK_ROLE_IMAGE, atk_object_get_role(image));

  // The alt text of the image is not navigable as text.
  ASSERT_FALSE(ATK_IS_TEXT(image));

  g_object_unref(image);
  g_object_unref(contenteditable_text);
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       TestMultilingualTextAtOffsetWithBoundaryCharacter) {
  AtkText* atk_text = SetUpInputField();
  ASSERT_NE(nullptr, atk_text);
  AccessibilityNotificationWaiter waiter(shell()->web_contents(),
                                         ax::mojom::Event::kValueChanged);
  // Place an e acute, and two emoticons in the text field.
  ExecuteScript(
      uR"SCRIPT(
      const input = document.querySelector('input');
      input.value =
          'é👩\u200D❤\uFE0F\u200D👩🐶';
      )SCRIPT");
  ASSERT_TRUE(waiter.WaitForNotification());

  int character_count = atk_text_get_character_count(atk_text);
  // "character_count" is the number of actual characters, not the number of
  // UTF16 code units.
  //
  // Currently, this doesn't properly count grapheme clusters, but it does
  // handle surrogate pairs.
  // TODO(nektar): Implement support for base::OffsetAdjuster in AXPosition.
  ASSERT_EQ(9, character_count);

  // The expected text consists of an e acute, and two emoticons, but
  // not every multi-byte character is a surrogate pair.
  CheckTextAtOffset(atk_text, 0, ATK_TEXT_BOUNDARY_CHAR, 0, 2,
                    base::WideToUTF8(L"e\x0301").c_str());
  CheckTextAtOffset(atk_text, 1, ATK_TEXT_BOUNDARY_CHAR, 0, 2,
                    base::WideToUTF8(L"e\x0301").c_str());
  CheckTextAtOffset(atk_text, 2, ATK_TEXT_BOUNDARY_CHAR, 2, 8,
                    "\xF0\x9F\x91\xA9\xE2\x80\x8D\xE2\x9D\xA4\xEF\xB8\x8F\xE2"
                    "\x80\x8D\xF0\x9F\x91\xA9");
  CheckTextAtOffset(atk_text, 3, ATK_TEXT_BOUNDARY_CHAR, 2, 8,
                    "\xF0\x9F\x91\xA9\xE2\x80\x8D\xE2\x9D\xA4\xEF\xB8\x8F\xE2"
                    "\x80\x8D\xF0\x9F\x91\xA9");
  CheckTextAtOffset(atk_text, 4, ATK_TEXT_BOUNDARY_CHAR, 2, 8,
                    "\xF0\x9F\x91\xA9\xE2\x80\x8D\xE2\x9D\xA4\xEF\xB8\x8F\xE2"
                    "\x80\x8D\xF0\x9F\x91\xA9");
  CheckTextAtOffset(atk_text, 5, ATK_TEXT_BOUNDARY_CHAR, 2, 8,
                    "\xF0\x9F\x91\xA9\xE2\x80\x8D\xE2\x9D\xA4\xEF\xB8\x8F\xE2"
                    "\x80\x8D\xF0\x9F\x91\xA9");
  CheckTextAtOffset(atk_text, 6, ATK_TEXT_BOUNDARY_CHAR, 2, 8,
                    "\xF0\x9F\x91\xA9\xE2\x80\x8D\xE2\x9D\xA4\xEF\xB8\x8F\xE2"
                    "\x80\x8D\xF0\x9F\x91\xA9");
  CheckTextAtOffset(atk_text, 7, ATK_TEXT_BOUNDARY_CHAR, 2, 8,
                    "\xF0\x9F\x91\xA9\xE2\x80\x8D\xE2\x9D\xA4\xEF\xB8\x8F\xE2"
                    "\x80\x8D\xF0\x9F\x91\xA9");
  CheckTextAtOffset(atk_text, 8, ATK_TEXT_BOUNDARY_CHAR, 8, 9,
                    "\xF0\x9F\x90\xB6");
  CheckTextAtOffset(atk_text, 9, ATK_TEXT_BOUNDARY_CHAR, 0, 0, nullptr);

  g_object_unref(atk_text);
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       TestTextAtOffsetWithBoundaryLine) {
  AtkText* atk_text = SetUpInputField();

  // Single line text fields should return the whole text.
  CheckTextAtOffset(atk_text, 0, ATK_TEXT_BOUNDARY_LINE_START, 0,
                    static_cast<int>(InputContentsString().size()),
                    InputContentsString().c_str());

  g_object_unref(atk_text);
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       TestMultiLineTextAtOffsetWithBoundaryLine) {
  AtkText* atk_text = SetUpTextareaField();

  CheckTextAtOffset(atk_text, 0, ATK_TEXT_BOUNDARY_LINE_START, 0, 24,
                    "Moz/5.0 (ST 6.x; WWW33)\n");

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

  // Last line does not have a trailing newline.
  CheckTextAtOffset(atk_text, 32, ATK_TEXT_BOUNDARY_LINE_START, 32,
                    static_cast<int>(InputContentsString().size()),
                    "\"KHTML, like\".");

  g_object_unref(atk_text);
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       TestBlankLineTextAtOffsetWithBoundaryLine) {
  AtkText* atk_text = SetUpTextareaField();

  AccessibilityNotificationWaiter waiter(shell()->web_contents(),
                                         ax::mojom::Event::kValueChanged);
  // Add a blank line at the end of the textarea.
  ExecuteScript(
      uR"SCRIPT(
      const textarea = document.querySelector('textarea');
      textarea.value += '\n';
      )SCRIPT");
  ASSERT_TRUE(waiter.WaitForNotification());

  // The second last line should have an additional trailing newline. Also,
  // Blink represents the blank line with a newline character, so in total there
  // should be two more newlines. The second newline is not part of the HTML
  // value attribute however.
  int contents_string_length =
      static_cast<int>(InputContentsString().size()) + 1;
  CheckTextAtOffset(atk_text, 32, ATK_TEXT_BOUNDARY_LINE_START, 32,
                    contents_string_length, "\"KHTML, like\".\n");
  CheckTextAtOffset(atk_text, 46, ATK_TEXT_BOUNDARY_LINE_START, 32,
                    contents_string_length, "\"KHTML, like\".\n");

  // An offset one past the last character should return the last line which is
  // blank. This is represented by Blink with yet another line break.
  CheckTextAtOffset(atk_text, contents_string_length,
                    ATK_TEXT_BOUNDARY_LINE_START, contents_string_length,
                    (contents_string_length + 1), "\n");

  {
    // There should be no text after the blank line.
    int start_offset = 0;
    int end_offset = 0;
    char* text = atk_text_get_text_at_offset(
        atk_text, (contents_string_length + 1), ATK_TEXT_BOUNDARY_LINE_START,
        &start_offset, &end_offset);
    EXPECT_EQ(0, start_offset);
    EXPECT_EQ(0, end_offset);
    EXPECT_EQ(nullptr, text);
  }

  g_object_unref(atk_text);
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       TestParagraphTextAtOffsetWithBoundaryLine) {
  AtkText* atk_text = SetUpSampleParagraph();

  // There should be two lines in this paragraph.
  const int newline_offset = 46;
  int n_characters = atk_text_get_character_count(atk_text);
  ASSERT_LT(newline_offset, n_characters);

  const std::u16string embedded_character(
      1, ui::AXPlatformNodeAuraLinux::kEmbeddedCharacter);
  std::string expected_string = "Game theory is \"the study of " +
                                base::UTF16ToUTF8(embedded_character) +
                                " of conflict and\n";
  for (int i = 0; i <= newline_offset; ++i) {
    CheckTextAtOffset(atk_text, i, ATK_TEXT_BOUNDARY_LINE_START, 0,
                      newline_offset + 1, expected_string.c_str());
  }

  for (int i = newline_offset + 1; i < n_characters; ++i) {
    CheckTextAtOffset(
        atk_text, i, ATK_TEXT_BOUNDARY_LINE_START, newline_offset + 1,
        n_characters,
        "cooperation between intelligent rational decision-makers.\"");
  }

  g_object_unref(atk_text);
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       DISABLED_TestParagraphTextAtOffsetWithBoundarySentence) {
  LoadInitialAccessibilityTreeFromHtml(std::string(
      R"HTML(<!DOCTYPE html>
          <html>
          <body>
            <div>One sentence. Two sentences. Three sentences!</div>
          </body>
          </html>)HTML"));

  AtkObject* document = GetRendererAccessible();
  EXPECT_EQ(1, atk_object_get_n_accessible_children(document));

  AtkText* div_element = ATK_TEXT(atk_object_ref_accessible_child(document, 0));
  EXPECT_EQ(1, atk_object_get_n_accessible_children(ATK_OBJECT(div_element)));
  AtkText* atk_text =
      ATK_TEXT(atk_object_ref_accessible_child(ATK_OBJECT(div_element), 0));

  int first_sentence_offset = 14;
  int second_sentence_offset = first_sentence_offset + 15;
  int third_sentence_offset = second_sentence_offset + 16;

  for (int i = 0; i < first_sentence_offset; ++i) {
    CheckTextAtOffset(atk_text, i, ATK_TEXT_BOUNDARY_SENTENCE_START, 0,
                      first_sentence_offset, "One sentence. ");
  }

  for (int i = first_sentence_offset + 1; i < second_sentence_offset; ++i) {
    CheckTextAtOffset(atk_text, i, ATK_TEXT_BOUNDARY_SENTENCE_START,
                      first_sentence_offset, second_sentence_offset,
                      "Two sentences. ");
  }

  for (int i = second_sentence_offset + 1; i < third_sentence_offset; ++i) {
    CheckTextAtOffset(atk_text, i, ATK_TEXT_BOUNDARY_SENTENCE_START,
                      second_sentence_offset, third_sentence_offset,
                      "Three sentences!");
  }

  g_object_unref(atk_text);
  g_object_unref(div_element);
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       TestCharacterExtentsWithInvalidArguments) {
  AtkText* atk_text = SetUpSampleParagraph();

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

  // When given invalid arguments, atk_text_get_character_extents returns 0
  // before 2.35.1 and -1 after:
  // https://gitlab.gnome.org/GNOME/atk/-/merge_requests/44#9f621eb5fd3bcb2fa5c7bd228c9b1ad42edc46c8_32_33
  // https://gnome.pages.gitlab.gnome.org/at-spi2-core/atk/AtkText.html#atk-text-get-character-extents
  base::Version atk_version(atk_get_version());
  int expect = atk_version.CompareTo(base::Version("2.35.1")) >= 0 ? -1 : 0;

  atk_text_get_character_extents(atk_text, invalid_offset, &x, &y, &width,
                                 &height, ATK_XY_SCREEN);
  EXPECT_EQ(expect, x);
  EXPECT_EQ(expect, y);
  EXPECT_EQ(expect, width);
  EXPECT_EQ(expect, height);

  atk_text_get_character_extents(atk_text, invalid_offset, &x, &y, &width,
                                 &height, ATK_XY_PARENT);
  EXPECT_EQ(expect, x);
  EXPECT_EQ(expect, y);
  EXPECT_EQ(expect, width);
  EXPECT_EQ(expect, height);

  atk_text_get_character_extents(atk_text, invalid_offset, &x, &y, &width,
                                 &height, ATK_XY_WINDOW);
  EXPECT_EQ(expect, x);
  EXPECT_EQ(expect, y);
  EXPECT_EQ(expect, width);
  EXPECT_EQ(expect, height);

  int n_characters = atk_text_get_character_count(atk_text);
  ASSERT_LT(0, n_characters);

  atk_text_get_character_extents(atk_text, invalid_offset, &x, &y, &width,
                                 &height, ATK_XY_SCREEN);
  EXPECT_EQ(expect, x);
  EXPECT_EQ(expect, y);
  EXPECT_EQ(expect, width);
  EXPECT_EQ(expect, height);

  atk_text_get_character_extents(atk_text, invalid_offset, &x, &y, &width,
                                 &height, ATK_XY_PARENT);
  EXPECT_EQ(expect, x);
  EXPECT_EQ(expect, y);
  EXPECT_EQ(expect, width);
  EXPECT_EQ(expect, height);

  atk_text_get_character_extents(atk_text, invalid_offset, &x, &y, &width,
                                 &height, ATK_XY_WINDOW);
  EXPECT_EQ(expect, x);
  EXPECT_EQ(expect, y);
  EXPECT_EQ(expect, width);
  EXPECT_EQ(expect, height);

  g_object_unref(atk_text);
}

AtkCoordType kCoordinateTypes[] = {
    ATK_XY_SCREEN,
    ATK_XY_WINDOW,
    ATK_XY_PARENT,
};

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       TestCharacterExtentsInEditable) {
  AtkText* atk_text = SetUpSampleParagraph();

  constexpr int newline_offset = 46;
  int n_characters = atk_text_get_character_count(atk_text);
  ASSERT_EQ(105, n_characters);

  int x, y, width, height;
  int previous_x, previous_y, previous_height;
  for (AtkCoordType coordinate_type : kCoordinateTypes) {
    atk_text_get_character_extents(atk_text, 0, &x, &y, &width, &height,
                                   coordinate_type);
    EXPECT_LT(0, x) << "at offset 0";
    EXPECT_LT(0, y) << "at offset 0";
    EXPECT_LT(1, width) << "at offset 0";
    EXPECT_LT(1, height) << "at offset 0";

    gfx::Rect combined_extents(x, y, width, height);
    for (int offset = 1; offset < newline_offset; ++offset) {
      ::testing::Message message;
      message << "While checking at offset " << offset;
      SCOPED_TRACE(message);

      previous_x = x;
      previous_y = y;
      previous_height = height;

      atk_text_get_character_extents(atk_text, offset, &x, &y, &width, &height,
                                     coordinate_type);
      EXPECT_LT(previous_x, x);
      EXPECT_EQ(previous_y, y);
      EXPECT_LT(1, width);
      EXPECT_EQ(previous_height, height);

      combined_extents.Union(gfx::Rect(x, y, width, height));
      atk_text_get_character_extents(atk_text, offset, &x, &y, &width, &height,
                                     coordinate_type);

      AtkTextRectangle atk_rect;
      atk_text_get_range_extents(atk_text, 0, offset + 1, coordinate_type,
                                 &atk_rect);
      EXPECT_EQ(combined_extents.x(), atk_rect.x);
      EXPECT_EQ(combined_extents.y(), atk_rect.y);
      EXPECT_EQ(combined_extents.width(), atk_rect.width);
      EXPECT_EQ(combined_extents.height(), atk_rect.height);
    }

    {
      ::testing::Message message;
      message << "While checking at offset " << newline_offset + 1;
      SCOPED_TRACE(message);

      atk_text_get_character_extents(atk_text, newline_offset + 1, &x, &y,
                                     &width, &height, coordinate_type);
      EXPECT_LE(0, x);
      EXPECT_GT(previous_x, x);
      EXPECT_LT(previous_y, y);
      EXPECT_LT(1, width);
      EXPECT_EQ(previous_height, height);
    }

    combined_extents = gfx::Rect(x, y, width, height);
    for (int offset = newline_offset + 2; offset < n_characters; ++offset) {
      ::testing::Message message;
      message << "While checking at offset " << offset;
      SCOPED_TRACE(message);

      previous_x = x;
      previous_y = y;
      previous_height = height;

      atk_text_get_character_extents(atk_text, offset, &x, &y, &width, &height,
                                     coordinate_type);
      EXPECT_LT(previous_x, x);
      EXPECT_EQ(previous_y, y);
      EXPECT_LT(1, width);
      EXPECT_EQ(previous_height, height);

      combined_extents.Union(gfx::Rect(x, y, width, height));
      atk_text_get_character_extents(atk_text, offset, &x, &y, &width, &height,
                                     coordinate_type);

      AtkTextRectangle atk_rect;
      atk_text_get_range_extents(atk_text, newline_offset + 1, offset + 1,
                                 coordinate_type, &atk_rect);
      EXPECT_EQ(combined_extents.x(), atk_rect.x);
      EXPECT_EQ(combined_extents.y(), atk_rect.y);
      EXPECT_EQ(combined_extents.width(), atk_rect.width);
      EXPECT_EQ(combined_extents.height(), atk_rect.height);
    }
  }

  g_object_unref(atk_text);
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       TestCharacterExtentsInScrollableEditable) {
  LoadSampleParagraphInScrollableEditable();

  // By construction, only the first line of the content editable is visible.
  AtkText* atk_text = GetSampleParagraph();

  constexpr int first_line_end = 5;
  constexpr int last_line_start = 8;

  int n_characters = atk_text_get_character_count(atk_text);
  ASSERT_EQ(13, n_characters);

  int x, y, width, height;
  int previous_x, previous_y, previous_height;
  for (AtkCoordType coordinate_type : kCoordinateTypes) {
    // Test that non offscreen characters have increasing x coordinates and a
    // height that is greater than 1px.
    {
      ::testing::Message message;
      message << "While checking at offset 0";
      SCOPED_TRACE(message);

      atk_text_get_character_extents(atk_text, 0, &x, &y, &width, &height,
                                     coordinate_type);
      EXPECT_LT(0, x);
      EXPECT_LT(0, y);
      EXPECT_LT(1, width);
      EXPECT_LT(1, height);
    }

    for (int offset = 1; offset < first_line_end; ++offset) {
      ::testing::Message message;
      message << "While checking at offset " << offset;
      SCOPED_TRACE(message);

      previous_x = x;
      previous_y = y;
      previous_height = height;

      atk_text_get_character_extents(atk_text, offset, &x, &y, &width, &height,
                                     coordinate_type);
      EXPECT_LT(previous_x, x);
      EXPECT_EQ(previous_y, y);
      EXPECT_LT(1, width);
      EXPECT_EQ(previous_height, height);
    }

    {
      ::testing::Message message;
      message << "While checking at offset " << last_line_start;
      SCOPED_TRACE(message);

      atk_text_get_character_extents(atk_text, last_line_start, &x, &y, &width,
                                     &height, coordinate_type);
      EXPECT_LT(0, x);
      EXPECT_LT(previous_y, y);
      EXPECT_LT(1, width);
      EXPECT_EQ(previous_height, height);
    }

    for (int offset = last_line_start + 1; offset < n_characters; ++offset) {
      ::testing::Message message;
      message << "While checking at offset " << offset;
      SCOPED_TRACE(message);

      previous_x = x;
      previous_y = y;

      atk_text_get_character_extents(atk_text, offset, &x, &y, &width, &height,
                                     coordinate_type);
      EXPECT_LT(previous_x, x);
      EXPECT_EQ(previous_y, y);
      EXPECT_LT(1, width);
      EXPECT_EQ(previous_height, height);
    }
  }

  g_object_unref(atk_text);
}

void AccessibilityAuraLinuxBrowserTest::
    TestCharacterExtentsInScrollableInput() {
  AtkText* input_text = GetScrollableInputField();
  int contents_string_length = InputContentsString().length();
  int visible_characters_start = 21;
  int n_characters = atk_text_get_character_count(input_text);
  EXPECT_EQ(contents_string_length, n_characters);

  int caret_offset = atk_text_get_caret_offset(input_text);
  EXPECT_EQ(contents_string_length - 1, caret_offset);

  int x, y, width, height;
  int previous_x, previous_y, previous_height;
  for (int coordinate = ATK_XY_SCREEN; coordinate <= ATK_XY_WINDOW;
       ++coordinate) {
    auto coordinate_type = static_cast<AtkCoordType>(coordinate);

    atk_text_get_character_extents(input_text, 0, &x, &y, &width, &height,
                                   coordinate_type);
    EXPECT_GT(0, x + width) << "at offset 0";
    EXPECT_LT(0, y) << "at offset 0";
    EXPECT_LT(1, width) << "at offset 0";
    EXPECT_LT(1, height) << "at offset 0";

    for (int offset = 1; offset < (visible_characters_start - 1); ++offset) {
      previous_x = x;
      previous_y = y;
      previous_height = height;

      atk_text_get_character_extents(input_text, offset, &x, &y, &width,
                                     &height, coordinate_type);
      EXPECT_LT(previous_x, x) << "at offset " << offset;
      EXPECT_EQ(previous_y, y) << "at offset " << offset;
      EXPECT_LT(1, width) << "at offset " << offset;
      EXPECT_EQ(previous_height, height) << "at offset " << offset;
    }

    // Test that non offscreen characters have increasing x coordinates and a
    // width that is greater than 1px.
    atk_text_get_character_extents(input_text, visible_characters_start, &x, &y,
                                   &width, &height, coordinate_type);
    EXPECT_LT(previous_x, x) << "at offset " << visible_characters_start;
    EXPECT_EQ(previous_y, y) << "at offset " << visible_characters_start;
    EXPECT_LT(1, width) << "at offset " << visible_characters_start;
    EXPECT_EQ(previous_height, height)
        << "at offset " << visible_characters_start;

    // Exclude the dot at the end of the text field, because it has a width of
    // one anyway.
    for (int offset = visible_characters_start + 1; offset < (n_characters - 1);
         ++offset) {
      previous_x = x;
      previous_y = y;
      previous_height = height;

      atk_text_get_character_extents(input_text, offset, &x, &y, &width,
                                     &height, coordinate_type);
      EXPECT_LT(previous_x, x) << "at offset " << offset;
      EXPECT_EQ(previous_y, y) << "at offset " << offset;
      EXPECT_LT(1, width) << "at offset " << offset;
      EXPECT_EQ(previous_height, height) << "at offset " << offset;
    }
  }

  g_object_unref(input_text);
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       TestCharacterExtentsInScrollableInputField) {
  LoadScrollableInputField("text");
  TestCharacterExtentsInScrollableInput();
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       TestCharacterExtentsInScrollableInputTypeSearchField) {
  LoadScrollableInputField("search");
  TestCharacterExtentsInScrollableInput();
}

typedef bool (*ScrollToPointFunc)(AtkComponent* component,
                                  AtkCoordType coords,
                                  gint x,
                                  gint y);
typedef bool (*ScrollToFunc)(AtkComponent* component, AtkScrollType type);

// TODO(crbug.com/40866728): Enable this test.
IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       DISABLED_TestScrollToPoint) {
  LoadSampleParagraphInScrollableDocument();
  AtkText* atk_text = GetSampleParagraph();
  ASSERT_TRUE(ATK_IS_COMPONENT(atk_text));
  AtkComponent* atk_component = ATK_COMPONENT(atk_text);

  int prev_x, prev_y, x, y;
  atk_component_get_extents(atk_component, &prev_x, &prev_y, nullptr, nullptr,
                            ATK_XY_SCREEN);

  AccessibilityNotificationWaiter location_changed_waiter(
      shell()->web_contents(), ax::mojom::Event::kLocationChanged);
  atk_component_scroll_to_point(atk_component, ATK_XY_PARENT, 0, 0);
  ASSERT_TRUE(location_changed_waiter.WaitForNotification());

  atk_component_get_extents(atk_component, &x, &y, nullptr, nullptr,
                            ATK_XY_SCREEN);
  EXPECT_EQ(prev_x, x);
  EXPECT_GT(prev_y, y);

  constexpr int kScrollToY = 0;
  atk_component_scroll_to_point(atk_component, ATK_XY_SCREEN, 0, kScrollToY);
  ASSERT_TRUE(location_changed_waiter.WaitForNotification());
  atk_component_get_extents(atk_component, &x, &y, nullptr, nullptr,
                            ATK_XY_SCREEN);
  EXPECT_EQ(kScrollToY, y);

  constexpr int kScrollToY_2 = 243;
  atk_component_scroll_to_point(atk_component, ATK_XY_SCREEN, 0, kScrollToY_2);
  ASSERT_TRUE(location_changed_waiter.WaitForNotification());
  atk_component_get_extents(atk_component, nullptr, &y, nullptr, nullptr,
                            ATK_XY_SCREEN);
  EXPECT_EQ(kScrollToY_2, y);

  atk_component_scroll_to_point(atk_component, ATK_XY_SCREEN, 0, 129);
  ASSERT_TRUE(location_changed_waiter.WaitForNotification());
  atk_component_get_extents(atk_component, nullptr, &y, nullptr, nullptr,
                            ATK_XY_SCREEN);

  AtkObject* frame = FindAtkObjectParentFrame(ATK_OBJECT(atk_component));
  int frame_y;
  atk_component_get_extents(ATK_COMPONENT(frame), nullptr, &frame_y, nullptr,
                            nullptr, ATK_XY_SCREEN);
  EXPECT_EQ(frame_y, y);

  g_object_unref(atk_text);
}

// TODO(crbug.com/40866728): Enable this test.
IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       DISABLED_TestScrollTo) {
  LoadInitialAccessibilityTreeFromHtml(
      R"HTML(<!DOCTYPE html>
      <html>
      <body>
        <div style="height: 5000px; width: 5000px;"></div>
        <img style="display: relative; left: 1000px;" alt="Target1">
        <div style="height: 5000px;"></div>
        <img style="display: relative; left: 1000px;" alt="Target2">
        <div style="height: 5000px;"></div>
        <span>Target 3</span>
        <div style="height: 5000px;"></div>
      </body>
      </html>)HTML");

  // Retrieve the AtkObject interface for the document node.
  AtkObject* document = GetRendererAccessible();
  ASSERT_TRUE(ATK_IS_COMPONENT(document));

  // Get the dimensions of the document.
  int doc_x, doc_y, doc_width, doc_height;
  atk_component_get_extents(ATK_COMPONENT(document), &doc_x, &doc_y, &doc_width,
                            &doc_height, ATK_XY_SCREEN);

  // The document should only have three children, two img elements
  // and a single span element.
  ASSERT_EQ(3, atk_object_get_n_accessible_children(document));

  AtkObject* target = atk_object_ref_accessible_child(document, 0);
  AtkObject* target2 = atk_object_ref_accessible_child(document, 1);
  AtkObject* target3 = atk_object_ref_accessible_child(document, 2);

  ASSERT_TRUE(ATK_IS_COMPONENT(target));
  ASSERT_TRUE(ATK_IS_COMPONENT(target2));
  ASSERT_TRUE(ATK_IS_COMPONENT(target3));

  ASSERT_EQ(ATK_ROLE_IMAGE, atk_object_get_role(target));
  ASSERT_EQ(ATK_ROLE_IMAGE, atk_object_get_role(target2));

  AccessibilityNotificationWaiter waiter(
      shell()->web_contents(), ax::mojom::Event::kScrollPositionChanged);
  ASSERT_TRUE(
      atk_component_scroll_to(ATK_COMPONENT(target), ATK_SCROLL_TOP_EDGE));
  ASSERT_TRUE(waiter.WaitForNotification());
  int x, y;
  atk_component_get_extents(ATK_COMPONENT(target), &x, &y, nullptr, nullptr,
                            ATK_XY_SCREEN);
  EXPECT_EQ(y, doc_y);
  EXPECT_NE(x, doc_x);

  ASSERT_TRUE(
      atk_component_scroll_to(ATK_COMPONENT(target), ATK_SCROLL_TOP_LEFT));
  ASSERT_TRUE(waiter.WaitForNotification());
  atk_component_get_extents(ATK_COMPONENT(target), &x, &y, nullptr, nullptr,
                            ATK_XY_SCREEN);
  EXPECT_EQ(y, doc_y);
  EXPECT_EQ(x, doc_x);

  ASSERT_TRUE(
      atk_component_scroll_to(ATK_COMPONENT(target), ATK_SCROLL_BOTTOM_EDGE));
  ASSERT_TRUE(waiter.WaitForNotification());
  atk_component_get_extents(ATK_COMPONENT(target), &x, &y, nullptr, nullptr,
                            ATK_XY_SCREEN);
  EXPECT_NE(y, doc_y);
  EXPECT_EQ(x, doc_x);

  ASSERT_TRUE(
      atk_component_scroll_to(ATK_COMPONENT(target), ATK_SCROLL_RIGHT_EDGE));
  ASSERT_TRUE(waiter.WaitForNotification());
  atk_component_get_extents(ATK_COMPONENT(target), &x, &y, nullptr, nullptr,
                            ATK_XY_SCREEN);
  EXPECT_NE(y, doc_y);
  EXPECT_NE(x, doc_x);

  ASSERT_TRUE(
      atk_component_scroll_to(ATK_COMPONENT(target2), ATK_SCROLL_LEFT_EDGE));
  ASSERT_TRUE(waiter.WaitForNotification());
  atk_component_get_extents(ATK_COMPONENT(target2), &x, &y, nullptr, nullptr,
                            ATK_XY_SCREEN);
  EXPECT_NE(y, doc_y);
  EXPECT_EQ(x, doc_x);

  ASSERT_TRUE(
      atk_component_scroll_to(ATK_COMPONENT(target2), ATK_SCROLL_TOP_LEFT));
  ASSERT_TRUE(waiter.WaitForNotification());
  atk_component_get_extents(ATK_COMPONENT(target2), &x, &y, nullptr, nullptr,
                            ATK_XY_SCREEN);
  EXPECT_EQ(y, doc_y);
  EXPECT_EQ(x, doc_x);

  // Orca expects atk_text_set_caret_offset to operate like scroll to the
  // target node like atk_component_scroll_to, so we test that here.
  ASSERT_TRUE(ATK_IS_TEXT(target3));
  AccessibilityNotificationWaiter waiter3(
      shell()->web_contents(), ax::mojom::Event::kScrollPositionChanged);
  atk_text_set_caret_offset(ATK_TEXT(target3), 0);
  ASSERT_TRUE(waiter3.WaitForNotification());

  // The text area should be scrolled to somewhere near the bottom of the
  // screen. We check that it is in the bottom quarter of the screen here,
  // but still fully onscreen.
  int height;
  atk_component_get_extents(ATK_COMPONENT(target3), nullptr, &y, nullptr,
                            &height, ATK_XY_SCREEN);

  int doc_bottom = doc_y + doc_height;
  int bottom_third = doc_bottom - (static_cast<float>(doc_height) / 3.0);
  EXPECT_GT(y, bottom_third);
  EXPECT_LT(y, doc_bottom - height + 1);

  g_object_unref(target);
  g_object_unref(target2);
  g_object_unref(target3);
}

// TODO(crbug.com/40866728): Enable this test.
IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       DISABLED_TestScrollSubstringTo) {
  LoadInitialAccessibilityTreeFromHtml(
      R"HTML(<!DOCTYPE html>
      <html>
      <body>
        <div style="height: 50000px; width: 50000px;"></div>
        <div style="position: relative; left: 1000px;">Target 1</div>
        <div style="height: 50000px;"></div>
        <div style="position: relative; left: 10000px;"> Target 2</div>
        <div style="height: 50000px;"></div>
        <div style="position: relative; left: 100000px;"> Target 3</div>
        <div style="height: 50000px;"></div>
      </body>
      </html>)HTML");

  // Retrieve the AtkObject interface for the document node.
  AtkObject* document = GetRendererAccessible();
  ASSERT_TRUE(ATK_IS_COMPONENT(document));

  // Get the dimensions of the document.
  int doc_x, doc_y, doc_width, doc_height;
  atk_component_get_extents(ATK_COMPONENT(document), &doc_x, &doc_y, &doc_width,
                            &doc_height, ATK_XY_SCREEN);

  // The document should only have three children, three span elements.
  ASSERT_EQ(3, atk_object_get_n_accessible_children(document));

  AtkObject* target1 = atk_object_ref_accessible_child(document, 0);
  ASSERT_TRUE(ATK_IS_TEXT(target1));
  ASSERT_EQ(ATK_ROLE_SECTION, atk_object_get_role(target1));

  AccessibilityNotificationWaiter waiter(
      shell()->web_contents(), ax::mojom::Event::kScrollPositionChanged);
  ASSERT_TRUE(atk_text_scroll_substring_to(ATK_TEXT(target1), 1, 2,
                                           ATK_SCROLL_TOP_EDGE));
  ASSERT_TRUE(waiter.WaitForNotification());
  int x, y;
  atk_text_get_character_extents(ATK_TEXT(target1), 1, &x, &y, nullptr, nullptr,
                                 ATK_XY_SCREEN);
  EXPECT_EQ(y, doc_y);
  EXPECT_NE(x, doc_x);

  ASSERT_TRUE(atk_text_scroll_substring_to(ATK_TEXT(target1), 1, 2,
                                           ATK_SCROLL_TOP_LEFT));
  ASSERT_TRUE(waiter.WaitForNotification());
  atk_text_get_character_extents(ATK_TEXT(target1), 1, &x, &y, nullptr, nullptr,
                                 ATK_XY_SCREEN);
  EXPECT_EQ(y, doc_y);
  EXPECT_EQ(x, doc_x);

  ASSERT_TRUE(atk_text_scroll_substring_to(ATK_TEXT(target1), 1, 2,
                                           ATK_SCROLL_BOTTOM_EDGE));
  ASSERT_TRUE(waiter.WaitForNotification());
  atk_text_get_character_extents(ATK_TEXT(target1), 1, &x, &y, nullptr, nullptr,
                                 ATK_XY_SCREEN);
  EXPECT_NE(y, doc_y);
  EXPECT_EQ(x, doc_x);

  ASSERT_TRUE(atk_text_scroll_substring_to(ATK_TEXT(target1), 1, 2,
                                           ATK_SCROLL_RIGHT_EDGE));
  ASSERT_TRUE(waiter.WaitForNotification());
  atk_text_get_character_extents(ATK_TEXT(target1), 1, &x, &y, nullptr, nullptr,
                                 ATK_XY_SCREEN);
  EXPECT_NE(y, doc_y);
  EXPECT_NE(x, doc_x);

  ASSERT_TRUE(atk_text_scroll_substring_to(ATK_TEXT(target1), 1, 2,
                                           ATK_SCROLL_LEFT_EDGE));
  ASSERT_TRUE(waiter.WaitForNotification());
  atk_text_get_character_extents(ATK_TEXT(target1), 1, &x, &y, nullptr, nullptr,
                                 ATK_XY_SCREEN);
  EXPECT_NE(y, doc_y);
  EXPECT_EQ(x, doc_x);

  ASSERT_TRUE(atk_text_scroll_substring_to(ATK_TEXT(target1), 1, 2,
                                           ATK_SCROLL_TOP_LEFT));
  ASSERT_TRUE(waiter.WaitForNotification());
  atk_text_get_character_extents(ATK_TEXT(target1), 1, &x, &y, nullptr, nullptr,
                                 ATK_XY_SCREEN);
  EXPECT_EQ(y, doc_y);
  EXPECT_EQ(x, doc_x);

  g_object_unref(target1);
}

// TODO(crbug.com/40866728): Enable this test.
IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       DISABLED_TestScrollSubstringToPoint) {
  LoadSampleParagraphInScrollableDocument();
  AtkText* atk_text = GetSampleParagraph();
  ASSERT_TRUE(ATK_IS_COMPONENT(atk_text));
  AtkComponent* atk_component = ATK_COMPONENT(atk_text);

  int prev_x, prev_y, x, y;
  atk_text_get_character_extents(atk_text, 1, &prev_x, &prev_y, nullptr,
                                 nullptr, ATK_XY_SCREEN);

  AccessibilityNotificationWaiter location_changed_waiter(
      shell()->web_contents(), ax::mojom::Event::kLocationChanged);
  atk_text_scroll_substring_to_point(atk_text, 1, 2, ATK_XY_PARENT, 0, 0);
  ASSERT_TRUE(location_changed_waiter.WaitForNotification());

  atk_text_get_character_extents(atk_text, 1, &x, &y, nullptr, nullptr,
                                 ATK_XY_SCREEN);
  EXPECT_EQ(prev_x, x);
  EXPECT_GT(prev_y, y);

  constexpr int kScrollToY = 0;
  atk_text_scroll_substring_to_point(atk_text, 1, 2, ATK_XY_SCREEN, 0,
                                     kScrollToY);
  ASSERT_TRUE(location_changed_waiter.WaitForNotification());
  atk_text_get_character_extents(atk_text, 1, &x, &y, nullptr, nullptr,
                                 ATK_XY_SCREEN);
  EXPECT_EQ(kScrollToY, y);

  constexpr int kScrollToY_2 = 243;
  atk_text_scroll_substring_to_point(atk_text, 1, 2, ATK_XY_SCREEN, 0,
                                     kScrollToY_2);
  ASSERT_TRUE(location_changed_waiter.WaitForNotification());
  atk_text_get_character_extents(atk_text, 1, &x, &y, nullptr, nullptr,
                                 ATK_XY_SCREEN);
  EXPECT_EQ(kScrollToY_2, y);

  atk_text_scroll_substring_to_point(atk_text, 1, 2, ATK_XY_SCREEN, 0, 129);
  ASSERT_TRUE(location_changed_waiter.WaitForNotification());
  atk_text_get_character_extents(atk_text, 1, &x, &y, nullptr, nullptr,
                                 ATK_XY_SCREEN);

  AtkObject* frame = FindAtkObjectParentFrame(ATK_OBJECT(atk_component));
  int frame_y;
  atk_component_get_extents(ATK_COMPONENT(frame), nullptr, &frame_y, nullptr,
                            nullptr, ATK_XY_SCREEN);

  // We do a check that the vertical position is within 5 pixels of the frame
  // position.
  EXPECT_LT(std::abs(frame_y - y), 5);

  g_object_unref(atk_text);
}

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
// Flaky on crbug.com/1026149
#define MAYBE_TestSetSelection DISABLED_TestSetSelection
#else
#define MAYBE_TestSetSelection TestSetSelection
#endif
IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       MAYBE_TestSetSelection) {
  AtkText* atk_text = SetUpInputField();

  int start_offset, end_offset;
  gchar* selected_text =
      atk_text_get_selection(atk_text, 0, &start_offset, &end_offset);
  EXPECT_EQ(nullptr, selected_text);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(0, end_offset);

  AccessibilityNotificationWaiter waiter(
      shell()->web_contents(),
      ui::AXEventGenerator::Event::TEXT_SELECTION_CHANGED);
  int contents_string_length = static_cast<int>(InputContentsString().size());
  start_offset = 0;
  end_offset = contents_string_length;

  EXPECT_TRUE(atk_text_set_selection(atk_text, 0, start_offset, end_offset));
  ASSERT_TRUE(waiter.WaitForNotification());
  selected_text =
      atk_text_get_selection(atk_text, 0, &start_offset, &end_offset);
  EXPECT_NE(nullptr, selected_text);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(contents_string_length, end_offset);
  g_free(selected_text);

  start_offset = contents_string_length;
  end_offset = 1;
  EXPECT_TRUE(atk_text_set_selection(atk_text, 0, start_offset, end_offset));
  ASSERT_TRUE(waiter.WaitForNotification());
  selected_text =
      atk_text_get_selection(atk_text, 0, &start_offset, &end_offset);
  EXPECT_NE(nullptr, selected_text);
  EXPECT_EQ(1, start_offset);
  EXPECT_EQ(contents_string_length, end_offset);
  g_free(selected_text);

  g_object_unref(atk_text);
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       SetSelectionWithIgnoredObjects) {
  LoadInitialAccessibilityTreeFromHtml(R"HTML(<!DOCTYPE html>
      <html>
        <body>
          <ul>
            <li>
              <div role="presentation"></div>
              <p role="presentation">
                <span>Banana</span>
              </p>
              <span>fruit.</span>
            </li>
          </ul>
        </body>
      </html>)HTML");

  AtkText* atk_list_item = FindNode(ATK_ROLE_LIST_ITEM);
  ASSERT_NE(nullptr, atk_list_item);

  // The hypertext expose by "list_item_text" includes a bullet (U+2022)
  // followed by a space for the list bullet and the joined word "Bananafruit.".
  // The word "Banana" is exposed as text because its container paragraph is
  // ignored.
  int n_characters = atk_text_get_character_count(atk_list_item);
  ASSERT_EQ(14, n_characters);

  AccessibilityNotificationWaiter waiter(
      shell()->web_contents(), ax::mojom::Event::kDocumentSelectionChanged);

  // First select the whole of the text found in the hypertext.
  int start_offset = 0;
  int end_offset = n_characters;
  std::string bullet = base::UTF16ToUTF8(kString16Bullet);
  char* selected_text = nullptr;

  EXPECT_TRUE(
      atk_text_set_selection(atk_list_item, 0, start_offset, end_offset));
  ASSERT_TRUE(waiter.WaitForNotification());

  selected_text =
      atk_text_get_selection(atk_list_item, 0, &start_offset, &end_offset);
  ASSERT_NE(nullptr, selected_text);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(n_characters, end_offset);
  // The list bullet should be represented by a bullet character (U+2022)
  // followed by a space.
  EXPECT_STREQ((bullet + std::string("Bananafruit.")).c_str(), selected_text);
  g_free(selected_text);

  // Select only the list bullet.
  start_offset = 0;
  end_offset = 2;
  EXPECT_TRUE(
      atk_text_set_selection(atk_list_item, 0, start_offset, end_offset));
  ASSERT_TRUE(waiter.WaitForNotification());

  selected_text =
      atk_text_get_selection(atk_list_item, 0, &start_offset, &end_offset);
  ASSERT_NE(nullptr, selected_text);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(2, end_offset);
  // The list bullet should be represented by a bullet character (U+2022)
  // followed by a space.
  EXPECT_STREQ(bullet.c_str(), selected_text);
  g_free(selected_text);

  // Select the word "Banana" in the ignored paragraph.
  start_offset = 2;
  end_offset = 8;
  EXPECT_TRUE(
      atk_text_set_selection(atk_list_item, 0, start_offset, end_offset));
  ASSERT_TRUE(waiter.WaitForNotification());

  selected_text =
      atk_text_get_selection(atk_list_item, 0, &start_offset, &end_offset);
  ASSERT_NE(nullptr, selected_text);
  EXPECT_EQ(2, start_offset);
  EXPECT_EQ(8, end_offset);
  EXPECT_STREQ("Banana", selected_text);
  g_free(selected_text);

  // Select both the list bullet and the word "Banana" in the ignored paragraph.
  start_offset = 0;
  end_offset = 8;
  EXPECT_TRUE(
      atk_text_set_selection(atk_list_item, 0, start_offset, end_offset));
  ASSERT_TRUE(waiter.WaitForNotification());

  selected_text =
      atk_text_get_selection(atk_list_item, 0, &start_offset, &end_offset);
  ASSERT_NE(nullptr, selected_text);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(8, end_offset);
  // The list bullet should be represented by a bullet character (U+2022)
  // followed by a space.
  EXPECT_STREQ((bullet + std::string("Banana")).c_str(), selected_text);
  g_free(selected_text);

  // Select the joined word "Bananafruit." both in the ignored paragraph and in
  // the unignored span.
  start_offset = 2;
  end_offset = n_characters;
  EXPECT_TRUE(
      atk_text_set_selection(atk_list_item, 0, start_offset, end_offset));
  ASSERT_TRUE(waiter.WaitForNotification());

  selected_text =
      atk_text_get_selection(atk_list_item, 0, &start_offset, &end_offset);
  ASSERT_NE(nullptr, selected_text);
  EXPECT_EQ(2, start_offset);
  EXPECT_EQ(n_characters, end_offset);
  EXPECT_STREQ("Bananafruit.", selected_text);
  g_free(selected_text);

  g_object_unref(atk_list_item);
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest, TestAtkTextListItem) {
  LoadInitialAccessibilityTreeFromHtml(
      R"HTML(<!DOCTYPE html>
      <html>
      <body>
        <li>Text 1</li>
        <li>Text 2</li>
        <li>Text 3</li>
      </body>
      </html>)HTML");

  // Retrieve the AtkObject interface for the document node.
  AtkObject* document = GetRendererAccessible();
  EXPECT_EQ(3, atk_object_get_n_accessible_children(document));
  AtkObject* list_item_1 = atk_object_ref_accessible_child(document, 0);
  AtkObject* list_item_2 = atk_object_ref_accessible_child(document, 1);

  EXPECT_TRUE(ATK_IS_TEXT(list_item_1));

  std::string expected_string = base::UTF16ToUTF8(kString16Bullet) + "Text 1";

  // The text of the list item should include the list marker as a bullet char.
  gchar* text = atk_text_get_text(ATK_TEXT(list_item_1), 0, -1);
  EXPECT_STREQ(text, expected_string.c_str());
  g_free(text);

  text = atk_text_get_text_at_offset(
      ATK_TEXT(list_item_2), 0, ATK_TEXT_BOUNDARY_WORD_START, nullptr, nullptr);
  ASSERT_STREQ(text, base::UTF16ToUTF8(kString16Bullet).c_str());
  g_free(text);

  text = atk_text_get_text_at_offset(
      ATK_TEXT(list_item_2), 2, ATK_TEXT_BOUNDARY_WORD_START, nullptr, nullptr);
  ASSERT_STREQ(text, "Text ");
  g_free(text);

  g_object_unref(list_item_1);
  g_object_unref(list_item_2);
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       TestTextSelectionChangedDuplicateSignals) {
  LoadInitialAccessibilityTreeFromHtml(
      R"HTML(<!DOCTYPE html>
      <html>
      <body>
      <div>
        Sufficiently long div content
      </div>
      </body>
      </html>)HTML");

  // Retrieve the AtkObject interface for the document node.
  AtkObject* document = GetRendererAccessible();
  ASSERT_TRUE(ATK_IS_COMPONENT(document));

  AtkObject* div = atk_object_ref_accessible_child(document, 0);
  EXPECT_NE(div, nullptr);

  int selection_changed_signals = 0;
  g_signal_connect(div, "text-selection-changed",
                   G_CALLBACK(+[](AtkText*, int* count) { *count += 1; }),
                   &selection_changed_signals);

  int caret_moved_signals = 0;
  g_signal_connect(div, "text-caret-moved",
                   G_CALLBACK(+[](AtkText*, gint, int* count) { *count += 1; }),
                   &caret_moved_signals);

  auto waiter = std::make_unique<AccessibilityNotificationWaiter>(
      shell()->web_contents(), ax::mojom::Event::kDocumentSelectionChanged);
  atk_text_set_caret_offset(ATK_TEXT(div), 0);
  ASSERT_TRUE(waiter->WaitForNotification());
  ASSERT_EQ(selection_changed_signals, 0);
  ASSERT_EQ(caret_moved_signals, 1);

  caret_moved_signals = selection_changed_signals = 0;
  atk_text_set_selection(ATK_TEXT(div), 0, 0, 3);
  ASSERT_TRUE(waiter->WaitForNotification());
  ASSERT_EQ(selection_changed_signals, 1);
  ASSERT_EQ(caret_moved_signals, 1);

  caret_moved_signals = selection_changed_signals = 0;
  atk_text_set_caret_offset(ATK_TEXT(div), 3);
  ASSERT_TRUE(waiter->WaitForNotification());
  ASSERT_EQ(selection_changed_signals, 1);
  ASSERT_EQ(caret_moved_signals, 0);

  caret_moved_signals = selection_changed_signals = 0;
  atk_text_set_caret_offset(ATK_TEXT(div), 2);
  ASSERT_TRUE(waiter->WaitForNotification());
  ASSERT_EQ(selection_changed_signals, 0);
  ASSERT_EQ(caret_moved_signals, 1);

  g_object_unref(div);
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       TestTextSelectionAcrossElements) {
  LoadInitialAccessibilityTreeFromHtml(std::string(
      R"HTML(<!DOCTYPE html>
          <html>
          <body>
            <div id="parent" contenteditable="true">
              <div id="child1">Child 1</div>
              <div id="child2">Child 2</div>
            </div>
          </body>
          </html>)HTML"));

  AtkObject* document = GetRendererAccessible();
  EXPECT_EQ(1, atk_object_get_n_accessible_children(document));

  AtkText* parent = ATK_TEXT(atk_object_ref_accessible_child(document, 0));
  EXPECT_EQ(2, atk_object_get_n_accessible_children(ATK_OBJECT(parent)));
  AtkText* child1 =
      ATK_TEXT(atk_object_ref_accessible_child(ATK_OBJECT(parent), 0));
  AtkText* child2 =
      ATK_TEXT(atk_object_ref_accessible_child(ATK_OBJECT(parent), 1));
  EXPECT_NE(nullptr, child1);
  EXPECT_NE(nullptr, child2);

  auto callback = G_CALLBACK(+[](AtkText*, bool* flag) { *flag = true; });
  bool saw_selection_change_in_parent = false;
  g_signal_connect(parent, "text-selection-changed", callback,
                   &saw_selection_change_in_parent);
  bool saw_selection_change_in_child1 = false;
  g_signal_connect(child1, "text-selection-changed", callback,
                   &saw_selection_change_in_child1);
  bool saw_selection_change_in_child2 = false;
  g_signal_connect(child2, "text-selection-changed", callback,
                   &saw_selection_change_in_child2);

  AccessibilityNotificationWaiter selection_waiter(
      shell()->web_contents(), ax::mojom::Event::kDocumentSelectionChanged);
  ExecuteScript(
      u"let parent = document.getElementById('parent');"
      u"let child1 = document.getElementById('child1');"
      u"let child2 = document.getElementById('child2');"
      u"let range = document.createRange();"
      u"range.setStart(child1.firstChild, 3);"
      u"range.setEnd(child1.firstChild, 5);"
      u"parent.focus();"
      u"document.getSelection().removeAllRanges();"
      u"document.getSelection().addRange(range);");
  ASSERT_TRUE(selection_waiter.WaitForNotification());

  EXPECT_FALSE(saw_selection_change_in_parent);
  EXPECT_TRUE(saw_selection_change_in_child1);
  EXPECT_FALSE(saw_selection_change_in_child2);

  saw_selection_change_in_parent = false;
  saw_selection_change_in_child1 = false;
  saw_selection_change_in_child2 = false;

  EXPECT_TRUE(atk_text_remove_selection(parent, 0));
  ASSERT_TRUE(selection_waiter.WaitForNotification());

  EXPECT_FALSE(saw_selection_change_in_parent);
  EXPECT_TRUE(saw_selection_change_in_child1);
  EXPECT_FALSE(saw_selection_change_in_child2);

  saw_selection_change_in_parent = false;
  saw_selection_change_in_child1 = false;
  saw_selection_change_in_child2 = false;

  ExecuteScript(
      u"let range2 = document.createRange();"
      u"range2.setStart(child1.firstChild, 0);"
      u"range2.setEnd(child2.firstChild, 3);"
      u"parent.focus();"
      u"document.getSelection().removeAllRanges();"
      u"document.getSelection().addRange(range2);");
  ASSERT_TRUE(selection_waiter.WaitForNotification());

  EXPECT_TRUE(saw_selection_change_in_parent);
  EXPECT_FALSE(saw_selection_change_in_child1);
  EXPECT_FALSE(saw_selection_change_in_child2);
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       SetCaretInTextWithGeneratedContent) {
  LoadInitialAccessibilityTreeFromHtml(
      R"HTML(<!DOCTYPE html>
      <html>
      <body contenteditable>
      <style>h1.generated::before{content:"   [   ";}</style>
      <style>h1.generated::after{content:"   ]   ";}</style>
      <h1 class="generated">Foo</h1>
      </body>
      </html>)HTML");

  AtkObject* document = GetRendererAccessible();

  AtkObject* contenteditable = atk_object_ref_accessible_child(document, 0);
  ASSERT_NE(nullptr, contenteditable);
  ASSERT_EQ(ATK_ROLE_SECTION, atk_object_get_role(contenteditable));
  ASSERT_TRUE(ATK_IS_TEXT(contenteditable));

  AtkObject* heading = atk_object_ref_accessible_child(contenteditable, 0);
  ASSERT_NE(nullptr, heading);
  ASSERT_EQ(atk_object_get_role(heading), ATK_ROLE_HEADING);

  // The accessible text for the heading should match the rendered text and
  // not the DOM text.
  gchar* text = atk_text_get_text(ATK_TEXT(heading), 0, -1);
  ASSERT_STREQ(text, "[ Foo ]");
  g_free(text);

  AccessibilityNotificationWaiter waiter(
      shell()->web_contents(), ax::mojom::Event::kDocumentSelectionChanged);

  // Caret can't be set inside generated content, it will go to the closest
  // allowed place. Ordered the targets so that the caret will always actually
  // move somewhere between steps, and thus the waiter will always be satisfied.
  std::vector<int> target_offset = {0, 3, 1, 4, 2, 4, 5, 4, 6};
  std::vector<int> expect_offset = {2, 3, 2, 4, 2, 4, 2, 4, 2};
  for (size_t i = 0; i < target_offset.size(); i++) {
    atk_text_set_caret_offset(ATK_TEXT(heading), target_offset[i]);
    ASSERT_TRUE(waiter.WaitForNotification());
    ASSERT_EQ(expect_offset[i], atk_text_get_caret_offset(ATK_TEXT(heading)));
  }

  g_object_unref(heading);
  g_object_unref(contenteditable);
}

// TODO(crbug.com/41469621): This flakes on linux.
IN_PROC_BROWSER_TEST_F(
    AccessibilityAuraLinuxBrowserTest,
    DISABLED_TestSetCaretSetsSequentialFocusNavigationStartingPoint) {
  LoadInitialAccessibilityTreeFromHtml(
      R"HTML(<!DOCTYPE html>
      <html>
      <body>
      <div>
        0
        <a href="http://google.com">1</a>
        2
        <a href="http://google.com">3</a>
        4
        <a href="http://google.com">5</a>
        6
        <a href="http://google.com"><div>7</div></a>
        8
      </div>
      </body>
      </html>)HTML");

  // Retrieve the AtkObject interface for the document node.
  AtkObject* document = GetRendererAccessible();
  ASSERT_TRUE(ATK_IS_COMPONENT(document));

  AtkObject* child_2 = atk_object_ref_accessible_child(document, 2);
  AtkObject* child_3 = atk_object_ref_accessible_child(document, 3);
  AtkObject* child_7 = atk_object_ref_accessible_child(document, 7);
  EXPECT_NE(child_2, nullptr);
  EXPECT_NE(child_3, nullptr);
  EXPECT_NE(child_7, nullptr);

  // Move the caret to the "3" div. This should also set the sequential
  // focus navigation starting point.
  atk_text_set_caret_offset(ATK_TEXT(child_2), 0);

  auto waiter = std::make_unique<AccessibilityNotificationWaiter>(
      shell()->web_contents(), ax::mojom::Event::kFocus);

  // Now send two tab presses to advance the focus.
  // TODO(mrobinson): For some reason, in the test harness two tabs are
  // necessary to advance focus after setting the selection (caret). This isn't
  // necessary when running interactively.
  SimulateKeyPress(shell()->web_contents(), ui::DomKey::TAB, ui::DomCode::TAB,
                   ui::VKEY_TAB, false, false, false, false);
  ASSERT_TRUE(waiter->WaitForNotification());

  SimulateKeyPress(shell()->web_contents(), ui::DomKey::TAB, ui::DomCode::TAB,
                   ui::VKEY_TAB, false, false, false, false);
  ASSERT_TRUE(waiter->WaitForNotification());
  ASSERT_TRUE(IsAtkObjectFocused(child_3));

  // Now we repeat a similar test, but this time setting the caret offset on
  // the document. In this case, the sequential navigation starting point
  // should move to the appropriate child.
  atk_text_set_caret_offset(ATK_TEXT(document), 13);
  SimulateKeyPress(shell()->web_contents(), ui::DomKey::TAB, ui::DomCode::TAB,
                   ui::VKEY_TAB, false, false, false, false);
  ASSERT_TRUE(waiter->WaitForNotification());

  SimulateKeyPress(shell()->web_contents(), ui::DomKey::TAB, ui::DomCode::TAB,
                   ui::VKEY_TAB, false, false, false, false);
  ASSERT_TRUE(waiter->WaitForNotification());

  ASSERT_TRUE(IsAtkObjectFocused(child_7));

  // Now test setting the caret in a node that can accept focus. That
  // node should actually receive focus.
  atk_text_set_caret_offset(ATK_TEXT(child_3), 0);
  SimulateKeyPress(shell()->web_contents(), ui::DomKey::TAB, ui::DomCode::TAB,
                   ui::VKEY_TAB, false, false, false, false);
  ASSERT_TRUE(waiter->WaitForNotification());
  ASSERT_TRUE(IsAtkObjectFocused(child_3));

  AtkObject* link_section = atk_object_ref_accessible_child(child_7, 0);
  EXPECT_NE(link_section, nullptr);
  AtkObject* link_text = atk_object_ref_accessible_child(link_section, 0);
  EXPECT_NE(link_text, nullptr);
  atk_text_set_caret_offset(ATK_TEXT(link_text), 0);
  ASSERT_TRUE(waiter->WaitForNotification());
  ASSERT_TRUE(IsAtkObjectFocused(child_7));

  g_object_unref(link_section);
  g_object_unref(link_text);
  g_object_unref(child_2);
  g_object_unref(child_3);
  g_object_unref(child_7);
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       SelectionTriggersReparentingOnSelectionStart) {
  LoadInitialAccessibilityTreeFromHtml(
      R"HTML(<!DOCTYPE html>
      <html>
      <head>
        <script>
          document.onselectstart = () => {
            var tomove = document.getElementById("tomove");
            document.getElementById("div").appendChild(tomove);
          }
        </script>
      </head>
      <body>
         <div id="tomove">Move me</div>
         <p id="paragraph">hello world</p>
         <div id="div"></div>
      </body>
      </html>)HTML");

  AtkObject* document = GetRendererAccessible();
  AtkObject* paragraph = atk_object_ref_accessible_child(document, 1);
  ASSERT_EQ(atk_object_get_role(paragraph), ATK_ROLE_PARAGRAPH);

  AccessibilityNotificationWaiter waiter(
      shell()->web_contents(), ax::mojom::Event::kDocumentSelectionChanged);

  EXPECT_TRUE(atk_text_set_selection(ATK_TEXT(paragraph), 0, 0, 5));
  ASSERT_TRUE(waiter.WaitForNotification());

  gchar* selected =
      atk_text_get_selection(ATK_TEXT(paragraph), 0, nullptr, nullptr);
  EXPECT_STREQ(selected, "hello");
  g_free(selected);

  g_object_unref(paragraph);
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       SelectionTriggersAnchorDeletionOnSelectionStart) {
  LoadInitialAccessibilityTreeFromHtml(
      R"HTML(<!DOCTYPE html>
      <html>
      <head>
        <script>
          document.onselectstart = () => {
          document.getElementById("p").removeChild(p.childNodes[0]);
          }
        </script>
      </head>
      <body>
         <p id="p"><span>hello</span> <span>world</span></p>
         <button id="button">ok</button>
      </body>
      </html>)HTML");

  AtkObject* document = GetRendererAccessible();
  AtkObject* paragraph = atk_object_ref_accessible_child(document, 0);
  ASSERT_EQ(atk_object_get_role(paragraph), ATK_ROLE_PARAGRAPH);

  AtkObject* button = atk_object_ref_accessible_child(document, 1);
  ASSERT_EQ(atk_object_get_role(button), ATK_ROLE_PUSH_BUTTON);

  AccessibilityNotificationWaiter waiter(shell()->web_contents(),
                                         ax::mojom::Event::kFocus);

  EXPECT_TRUE(atk_text_set_selection(ATK_TEXT(paragraph), 0, 0, 11));
  atk_component_grab_focus(ATK_COMPONENT(button));
  ASSERT_TRUE(waiter.WaitForNotification());

  gchar* selected =
      atk_text_get_selection(ATK_TEXT(paragraph), 0, nullptr, nullptr);
  EXPECT_STREQ(selected, nullptr);
  g_free(selected);

  g_object_unref(paragraph);
  g_object_unref(button);
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       SelectionTriggersFocusDeletionOnSelectionStart) {
  LoadInitialAccessibilityTreeFromHtml(
      R"HTML(<!DOCTYPE html>
      <head>
        <script>
          document.onselectstart = () => {
          document.getElementById("p").removeChild(p.childNodes[2]);
          }
        </script>
      </head>
      <body>
         <p id="p"><span>hello</span> <span>world</span></p>
         <button id="button">ok</button>
      </body>
      </html>)HTML");

  AtkObject* document = GetRendererAccessible();
  AtkObject* paragraph = atk_object_ref_accessible_child(document, 0);
  ASSERT_EQ(atk_object_get_role(paragraph), ATK_ROLE_PARAGRAPH);

  AtkObject* button = atk_object_ref_accessible_child(document, 1);
  ASSERT_EQ(atk_object_get_role(button), ATK_ROLE_PUSH_BUTTON);

  AccessibilityNotificationWaiter waiter(shell()->web_contents(),
                                         ax::mojom::Event::kFocus);

  EXPECT_TRUE(atk_text_set_selection(ATK_TEXT(paragraph), 0, 0, 11));
  atk_component_grab_focus(ATK_COMPONENT(button));
  ASSERT_TRUE(waiter.WaitForNotification());

  gchar* selected =
      atk_text_get_selection(ATK_TEXT(paragraph), 0, nullptr, nullptr);
  EXPECT_STREQ(selected, nullptr);
  g_free(selected);

  g_object_unref(paragraph);
  g_object_unref(button);
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       SelectionTriggersReparentingOnFocus) {
  LoadInitialAccessibilityTreeFromHtml(
      R"HTML(<!DOCTYPE html>
      <html>
      <head>
        <script>
          function go() {
            var edit = document.getElementById("edit");
            document.getElementById("search").appendChild(edit);
          }
        </script>
      </head>
      <body>
        <span id="edit" tabindex="0" contenteditable onfocusin="go()">foo</span>
        <div id="search" role="search"></div>
      </body>
      </html>)HTML");

  AtkObject* document = GetRendererAccessible();
  AtkObject* section = atk_object_ref_accessible_child(document, 0);
  AtkObject* edit = atk_object_ref_accessible_child(section, 0);
  ASSERT_TRUE(IsAtkObjectEditable(edit));
  ASSERT_FALSE(IsAtkObjectFocused(edit));

  AccessibilityNotificationWaiter waiter(
      shell()->web_contents(), ax::mojom::Event::kDocumentSelectionChanged);

  EXPECT_TRUE(atk_text_set_selection(ATK_TEXT(edit), 0, 1, 2));
  ASSERT_TRUE(waiter.WaitForNotification());

  // When the unfocused contenteditable span has its selection set, focus will
  // be set. That will trigger the script in the source to move that span to
  // a different parent, causing focus to be removed and the selection cleared.
  ASSERT_FALSE(IsAtkObjectFocused(edit));
  gchar* selected = atk_text_get_selection(ATK_TEXT(edit), 0, nullptr, nullptr);
  EXPECT_STREQ(selected, nullptr);
  g_free(selected);

  g_object_unref(edit);
  g_object_unref(section);
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       TestFocusInputTextFields) {
  auto verify_selection = [](AtkObject* object, const char* selection) {
    gchar* selected_text =
        atk_text_get_selection(ATK_TEXT(object), 0, nullptr, nullptr);
    EXPECT_STREQ(selected_text, selection);
    g_free(selected_text);

    int n_selections = atk_text_get_n_selections(ATK_TEXT(object));
    EXPECT_EQ(n_selections, selection ? 1 : 0);
  };

  LoadInitialAccessibilityTreeFromHtml(
      R"HTML(<!DOCTYPE html>
      <html>
      <body>
      <div>
        <input value="First Field">
        <input value="Second Field">
        <input value="Third Field">
        <input value="Fourth Field">
      </div>
      </body>
      </html>)HTML");

  // Retrieve the AtkObject interface for the document node.
  AtkObject* document = GetRendererAccessible();
  ASSERT_TRUE(ATK_IS_COMPONENT(document));

  AtkObject* container = atk_object_ref_accessible_child(document, 0);

  AtkObject* field_1 = atk_object_ref_accessible_child(container, 0);
  AtkObject* field_2 = atk_object_ref_accessible_child(container, 1);
  AtkObject* field_3 = atk_object_ref_accessible_child(container, 2);
  AtkObject* field_4 = atk_object_ref_accessible_child(container, 3);
  EXPECT_NE(field_1, nullptr);
  EXPECT_NE(field_2, nullptr);
  EXPECT_NE(field_3, nullptr);
  EXPECT_NE(field_4, nullptr);

  auto waiter = std::make_unique<AccessibilityNotificationWaiter>(
      shell()->web_contents(), ax::mojom::Event::kFocus);
  atk_component_grab_focus(ATK_COMPONENT(field_1));
  ASSERT_TRUE(waiter->WaitForNotification());

  waiter = std::make_unique<AccessibilityNotificationWaiter>(
      shell()->web_contents(),
      ui::AXEventGenerator::Event::TEXT_SELECTION_CHANGED);
  EXPECT_TRUE(atk_text_set_selection(ATK_TEXT(field_1), 0, 0, 5));
  ASSERT_TRUE(waiter->WaitForNotification());

  EXPECT_TRUE(atk_text_set_selection(ATK_TEXT(field_2), 0, 0, -1));
  ASSERT_TRUE(waiter->WaitForNotification());

  // Only the field that is currently focused should return a selection.
  ASSERT_FALSE(IsAtkObjectFocused(field_1));
  ASSERT_TRUE(IsAtkObjectFocused(field_2));
  verify_selection(field_1, nullptr);
  verify_selection(field_2, "Second Field");
  verify_selection(field_3, nullptr);
  verify_selection(field_4, nullptr);

  waiter = std::make_unique<AccessibilityNotificationWaiter>(
      shell()->web_contents(), ax::mojom::Event::kFocus);
  atk_component_grab_focus(ATK_COMPONENT(field_1));
  ASSERT_TRUE(waiter->WaitForNotification());

  // Now that the focus has returned to the first field, it should return the
  // original selection that we set on it.
  ASSERT_TRUE(IsAtkObjectFocused(field_1));
  ASSERT_FALSE(IsAtkObjectFocused(field_2));
  verify_selection(field_1, "First");
  verify_selection(field_2, nullptr);
  verify_selection(field_3, nullptr);
  verify_selection(field_4, nullptr);

  g_object_unref(field_1);
  g_object_unref(field_2);
  g_object_unref(field_3);
  g_object_unref(field_4);
  g_object_unref(container);
}

// Adapt a GCallback that sets a flag to a base::RepeatingCallback.
base::RepeatingCallback<void(AtkObject*, gint)> AdaptGCallbackToSetFlag(
    bool* flag) {
  return base::BindRepeating(
      [](bool* flag, AtkObject* object, gint offset) {
        // Set the flag to true. This mimics the original GCallback's behavior.
        *flag = true;
      },
      base::Unretained(flag));
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       TestTextEventsInStaticText) {
  LoadInitialAccessibilityTreeFromHtml(std::string(
      R"HTML(<!DOCTYPE html>
          <html>
          <body>
            <div contenteditable="true">Text inside field</div>
            anonymous block
          </body>
          </html>)HTML"));

  AtkObject* document = GetRendererAccessible();
  EXPECT_EQ(2, atk_object_get_n_accessible_children(document));

  AtkObject* div_element = atk_object_ref_accessible_child(document, 0);
  EXPECT_EQ(1, atk_object_get_n_accessible_children(ATK_OBJECT(div_element)));
  AtkObject* text = atk_object_ref_accessible_child(ATK_OBJECT(div_element), 0);
  AtkObject* anonymous_block = atk_object_ref_accessible_child(document, 1);

  bool saw_caret_move_in_text = false;
  ScopedGSignal caret_move_in_text_signal(
      text, "text-caret-moved",
      AdaptGCallbackToSetFlag(&saw_caret_move_in_text));

  bool saw_caret_move_in_div = false;
  ScopedGSignal caret_move_in_div_signal(
      div_element, "text-caret-moved",
      AdaptGCallbackToSetFlag(&saw_caret_move_in_div));

  bool saw_caret_move_in_anonymous_block = false;
  ScopedGSignal caret_move_in_anonymous_block_signal(
      anonymous_block, "text-caret-moved",
      AdaptGCallbackToSetFlag(&saw_caret_move_in_anonymous_block));

  bool saw_caret_move_in_document = false;
  ScopedGSignal caret_move_in_document_signal(
      document, "text-caret-moved",
      AdaptGCallbackToSetFlag(&saw_caret_move_in_document));

  AccessibilityNotificationWaiter selection_waiter(
      shell()->web_contents(),
      ui::AXEventGenerator::Event::TEXT_SELECTION_CHANGED);
  ExecuteScript(
      u"let selection = document.getSelection();"
      u"let editable = document.querySelector('div[contenteditable=\"true\"]');"
      u"editable.focus();"
      u"let range = document.createRange();"
      u"range.setStart(editable.lastChild, 4);"
      u"range.setEnd(editable.lastChild, 4);"
      u"selection.removeAllRanges();"
      u"selection.addRange(range);");
  ASSERT_TRUE(selection_waiter.WaitForNotification());

  // We should see the event happen in div and not the static text element.
  EXPECT_TRUE(saw_caret_move_in_div);
  EXPECT_FALSE(saw_caret_move_in_text);
  EXPECT_FALSE(saw_caret_move_in_anonymous_block);
  EXPECT_FALSE(saw_caret_move_in_document);

  saw_caret_move_in_div = false;

  AccessibilityNotificationWaiter document_selection_waiter(
      shell()->web_contents(), ax::mojom::Event::kDocumentSelectionChanged);
  atk_text_set_caret_offset(ATK_TEXT(anonymous_block), 3);
  ASSERT_TRUE(document_selection_waiter.WaitForNotification());

  EXPECT_FALSE(saw_caret_move_in_div);
  EXPECT_FALSE(saw_caret_move_in_text);
  EXPECT_FALSE(saw_caret_move_in_anonymous_block);
  EXPECT_TRUE(saw_caret_move_in_document);

  g_object_unref(div_element);
  g_object_unref(anonymous_block);
  g_object_unref(text);
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       TextAttributesInInputWithAriaHidden) {
  LoadInitialAccessibilityTreeFromHtml(std::string(
      R"HTML(<!DOCTYPE html>
          <html>
          <body>
            <input aria-hidden="true" autofocus>
          </body>
          </html>)HTML"));

  AtkObject* document = GetRendererAccessible();
  EXPECT_EQ(1, atk_object_get_n_accessible_children(document));

  AtkObject* section = atk_object_ref_accessible_child(document, 0);
  AtkText* input_element =
      ATK_TEXT(atk_object_ref_accessible_child(section, 0));

  AtkAttributeSet* attributes =
      atk_text_get_run_attributes(input_element, 0, nullptr, nullptr);
  ASSERT_NE(attributes, nullptr);
  atk_attribute_set_free(attributes);

  g_object_unref(input_element);
  g_object_unref(section);
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       TestFindInPageEvents) {
  LoadInitialAccessibilityTreeFromHtml(
      R"HTML(<!DOCTYPE html>
      <html>
      <body>
      <div contenteditable="true">
        Sufficiently long div content
      </div>
      <div contenteditable="true">
        Second sufficiently long div content
      </div>
      </body>
      </html>)HTML");

  // Retrieve the AtkObject interface for the document node.
  AtkObject* document = GetRendererAccessible();
  ASSERT_TRUE(ATK_IS_COMPONENT(document));

  AtkObject* div1 = atk_object_ref_accessible_child(document, 0);
  AtkObject* div2 = atk_object_ref_accessible_child(document, 1);
  EXPECT_NE(div1, nullptr);
  EXPECT_NE(div2, nullptr);

  auto selection_callback =
      G_CALLBACK(+[](AtkText*, int* count) { *count += 1; });
  int selection_changed_signals = 0;
  g_signal_connect(div1, "text-selection-changed", selection_callback,
                   &selection_changed_signals);
  g_signal_connect(div2, "text-selection-changed", selection_callback,
                   &selection_changed_signals);

  auto caret_callback = G_CALLBACK(
      +[](AtkText*, int new_position, int* caret_position_from_event) {
        *caret_position_from_event = new_position;
      });
  int caret_position_from_event = -1;
  g_signal_connect(div1, "text-caret-moved", caret_callback,
                   &caret_position_from_event);
  g_signal_connect(div2, "text-caret-moved", caret_callback,
                   &caret_position_from_event);

  AccessibilityNotificationWaiter waiter(
      shell()->web_contents(),
      ui::AXEventGenerator::Event::TEXT_SELECTION_CHANGED);
  atk_text_set_caret_offset(ATK_TEXT(div1), 4);
  ASSERT_TRUE(waiter.WaitForNotification());

  ASSERT_EQ(atk_text_get_caret_offset(ATK_TEXT(div1)), 4);
  ASSERT_EQ(caret_position_from_event, 4);
  ASSERT_EQ(selection_changed_signals, 0);

  caret_position_from_event = -1;
  selection_changed_signals = 0;
  auto* node = static_cast<ui::AXPlatformNodeAuraLinux*>(
      ui::AXPlatformNode::FromNativeViewAccessible(div2));
  node->ActivateFindInPageResult(1, 3);

  ASSERT_EQ(selection_changed_signals, 1);
  ASSERT_EQ(caret_position_from_event, 3);
  ASSERT_EQ(atk_text_get_caret_offset(ATK_TEXT(div2)), 3);
  ASSERT_EQ(atk_text_get_caret_offset(ATK_TEXT(div1)), 4);

  caret_position_from_event = -1;
  selection_changed_signals = 0;
  node->TerminateFindInPage();

  ASSERT_EQ(selection_changed_signals, 0);
  ASSERT_EQ(caret_position_from_event, -1);
  ASSERT_EQ(atk_text_get_caret_offset(ATK_TEXT(div2)), -1);
  ASSERT_EQ(atk_text_get_caret_offset(ATK_TEXT(div1)), 4);

  g_object_unref(div1);
  g_object_unref(div2);
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       TestOffsetsOfSelectionAll) {
  LoadInitialAccessibilityTreeFromHtml(R"HTML(
      <p>Hello world.</p>
      <p>Another paragraph.</p>
      <p>Goodbye world.</p>
      <script>
      var root = document.documentElement;
      window.getSelection().selectAllChildren(root);
      </script>)HTML");

  // Retrieve the AtkObject interface for the document node.
  AtkObject* document = GetRendererAccessible();
  ASSERT_TRUE(ATK_IS_COMPONENT(document));

  {
    auto* node = static_cast<ui::AXPlatformNodeAuraLinux*>(
        ui::AXPlatformNode::FromNativeViewAccessible(document));
    std::pair<int, int> offsets = node->GetSelectionOffsetsForAtk();
    EXPECT_EQ(0, offsets.first);
    EXPECT_EQ(3, offsets.second);
  }

  std::vector<int> expected = {12, 18, 14};  // text length of each child
  int number_of_children = atk_object_get_n_accessible_children(document);
  for (int i = 0; i < number_of_children; i++) {
    AtkObject* p = atk_object_ref_accessible_child(document, i);
    EXPECT_NE(p, nullptr);
    auto* node = static_cast<ui::AXPlatformNodeAuraLinux*>(
        ui::AXPlatformNode::FromNativeViewAccessible(p));
    std::pair<int, int> offsets = node->GetSelectionOffsetsForAtk();
    EXPECT_EQ(0, offsets.first);
    EXPECT_EQ(expected[i], offsets.second);
    g_object_unref(p);
  }
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       UniqueIdIsStableAfterRoleChange) {
  LoadInitialAccessibilityTreeFromHtml("<h1>Hello</h1>");

  AtkObject* document = GetRendererAccessible();
  AtkObject* atk_heading = atk_object_ref_accessible_child(document, 0);
  auto* heading = static_cast<ui::AXPlatformNodeBase*>(
      ui::AXPlatformNode::FromNativeViewAccessible(atk_heading));
  EXPECT_EQ(heading->GetRole(), ax::mojom::Role::kHeading);
  int32_t heading_unique_id = heading->GetUniqueId();
  EXPECT_GT(heading_unique_id, 0);

  // Change the heading to a group. This will cause it to get a new AXObject on
  // the renderer side, but the id will remain the same.
  AccessibilityNotificationWaiter waiter(
      shell()->web_contents(), ui::AXEventGenerator::Event::ROLE_CHANGED);
  ExecuteScript(u"document.querySelector('h1').setAttribute('role', 'group');");
  ASSERT_TRUE(waiter.WaitForNotification());

  AtkObject* atk_group = atk_object_ref_accessible_child(document, 0);
  auto* group = static_cast<ui::AXPlatformNodeBase*>(
      ui::AXPlatformNode::FromNativeViewAccessible(atk_group));
  EXPECT_EQ(group->GetRole(), ax::mojom::Role::kGroup);
  int32_t group_unique_id = group->GetUniqueId();
  EXPECT_GT(group_unique_id, 0);

  // The incoming id from the renderer remains the same.
  ASSERT_EQ(heading->GetNodeId(), group->GetNodeId());
  // The outgoing id assigned on the browser side, which is unique within the
  // window, also remains the same.
  ASSERT_EQ(heading_unique_id, group_unique_id);

  g_object_unref(atk_heading);
  g_object_unref(atk_group);
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       UniqueIdIsStableAfterLayoutObjectReplacement) {
  LoadInitialAccessibilityTreeFromHtml(
      "<main style='display:block'>Hello</main>");

  AtkObject* document = GetRendererAccessible();
  AtkObject* atk_block = atk_object_ref_accessible_child(document, 0);
  auto* block = static_cast<ui::AXPlatformNodeBase*>(
      ui::AXPlatformNode::FromNativeViewAccessible(atk_block));
  EXPECT_EQ(block->GetRole(), ax::mojom::Role::kMain);
  int32_t block_unique_id = block->GetUniqueId();
  EXPECT_GT(block_unique_id, 0);

  // Change the block to a inline_block. This will cause it to get a new
  // AXObject on the renderer side, but the id will remain the same.
  AccessibilityNotificationWaiter waiter(shell()->web_contents(),
                                         ax::mojom::Event::kEndOfTest);
  ExecuteScript(
      u"document.querySelector('main').style.display = 'inline-block';");
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());
  ui::BrowserAccessibilityManager* manager =
      web_contents->GetRootBrowserAccessibilityManager();
  manager->SignalEndOfTest();
  ASSERT_TRUE(waiter.WaitForNotification());

  AtkObject* atk_inline_block = atk_object_ref_accessible_child(document, 0);
  auto* inline_block = static_cast<ui::AXPlatformNodeBase*>(
      ui::AXPlatformNode::FromNativeViewAccessible(atk_inline_block));
  EXPECT_EQ(inline_block->GetRole(), ax::mojom::Role::kMain);
  int32_t inline_block_unique_id = inline_block->GetUniqueId();
  EXPECT_GT(inline_block_unique_id, 0);

  // The incoming id from the renderer remains the same.
  ASSERT_EQ(block->GetNodeId(), inline_block->GetNodeId());
  // The outgoing id assigned on the browser side, which is unique within the
  // window, also remains the same.
  ASSERT_EQ(block_unique_id, inline_block_unique_id);

  g_object_unref(atk_block);
  g_object_unref(atk_inline_block);
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       TestGetIndexInParent) {
  LoadInitialAccessibilityTreeFromHtml(R"HTML(
      <p>Hello world</p>
      <p>Another paragraph.</p>
      <p>Goodbye world.</p>
      )HTML");

  // Retrieve the AtkObject interface for the document node.
  AtkObject* document = GetRendererAccessible();
  ASSERT_TRUE(ATK_IS_COMPONENT(document));
  EXPECT_EQ(0, atk_object_get_index_in_parent(document));

  int number_of_children = atk_object_get_n_accessible_children(document);
  for (int i = 0; i < number_of_children; i++) {
    AtkObject* p = atk_object_ref_accessible_child(document, i);
    EXPECT_NE(p, nullptr);
    EXPECT_EQ(i, atk_object_get_index_in_parent(p));
    g_object_unref(p);
  }
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       HitTestOnAncestorOfWebRoot) {
  // Load the page.
  LoadInitialAccessibilityTreeFromHtml(R"HTML(
      <button>This is a button</button>
      )HTML");

  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());
  ui::BrowserAccessibilityManager* manager =
      web_contents->GetRootBrowserAccessibilityManager();

  // Find a node to hit test. Note that this is a really simple page,
  // so synchronous hit testing will work fine.
  ui::BrowserAccessibility* node = manager->GetBrowserAccessibilityRoot();
  while (node && node->GetRole() != ax::mojom::Role::kButton) {
    node = manager->NextInTreeOrder(node);
  }
  DCHECK(node);

  // Get the screen bounds of the hit target and find the point in the middle.
  gfx::Rect bounds = node->GetClippedScreenBoundsRect();
  gfx::Point point = bounds.CenterPoint();

  // Get the root AXPlatformNodeAuraLinux.
  ui::AXPlatformNodeAuraLinux* root_platform_node =
      static_cast<ui::AXPlatformNodeAuraLinux*>(
          ui::AXPlatformNode::FromNativeViewAccessible(
              manager->GetBrowserAccessibilityRoot()
                  ->GetNativeViewAccessible()));

  // First test that calling accHitTest on the root node returns the button.
  {
    gfx::NativeViewAccessible hit_child = root_platform_node->HitTestSync(
        point.x(), point.y(), AtkCoordType::ATK_XY_SCREEN);
    ASSERT_NE(nullptr, hit_child);
    ui::AXPlatformNode* hit_child_node =
        ui::AXPlatformNode::FromNativeViewAccessible(hit_child);
    ASSERT_NE(nullptr, hit_child_node);
    EXPECT_EQ(node->GetId(), hit_child_node->GetDelegate()->GetData().id);
  }

  // Now test it again, but this time caliing accHitTest on the parent
  // IAccessible of the web root node.
  {
    RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>(
        shell()->web_contents()->GetRenderWidgetHostView());
    gfx::NativeViewAccessible ancestor = rwhva->GetParentNativeViewAccessible();

    ASSERT_NE(nullptr, ancestor);

    ui::AXPlatformNodeAuraLinux* ancestor_node =
        static_cast<ui::AXPlatformNodeAuraLinux*>(
            ui::AXPlatformNode::FromNativeViewAccessible(ancestor));
    ASSERT_NE(nullptr, ancestor_node);

    gfx::NativeViewAccessible hit_child = ancestor_node->HitTestSync(
        point.x(), point.y(), AtkCoordType::ATK_XY_SCREEN);
    ASSERT_NE(nullptr, hit_child);
    ui::AXPlatformNode* hit_child_node =
        ui::AXPlatformNode::FromNativeViewAccessible(hit_child);
    ASSERT_NE(nullptr, hit_child_node);
    EXPECT_EQ(node->GetId(), hit_child_node->GetDelegate()->GetData().id);
  }
}

// Tests if it does not DCHECK when textarea has a placeholder break element.
IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       TestGetTextContainerFromTextArea) {
  std::string content = std::string("<textarea style=\"height:100px;\">hello") +
                        std::string("\n") + std::string("</textarea>");
  LoadInitialAccessibilityTreeFromHtml(content);

  AtkText* atk_text = FindNode(ATK_ROLE_ENTRY);
  AtkTextRectangle atk_rect;
  // atk_text_get_range_extents() calls GetTextContainerForPlainTextField() and
  // DCHECK on checking children counts.
  atk_text_get_range_extents(atk_text, 0, 7, AtkCoordType::ATK_XY_SCREEN,
                             &atk_rect);
  g_object_unref(atk_text);
}

IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
                       TestCaretMovedInNumberInput) {
  LoadInitialAccessibilityTreeFromHtml(
      R"HTML(<input type="number" value="12">
      )HTML");
  AccessibilityNotificationWaiter waiter(
      shell()->web_contents(),
      ui::AXEventGenerator::Event::TEXT_SELECTION_CHANGED);
  auto caret_callback =
      G_CALLBACK(+[](AtkText*, int new_position, int* out_caret_position) {
        *out_caret_position = new_position;
      });
  int out_caret_position = -1;
  AtkText* input_text = FindNode(ATK_ROLE_SPIN_BUTTON);
  g_signal_connect(input_text, "text-caret-moved", caret_callback,
                   &out_caret_position);

  atk_text_set_caret_offset(input_text, 0);
  ASSERT_TRUE(waiter.WaitForNotification());
  EXPECT_EQ(atk_text_get_caret_offset(input_text), 0);
  EXPECT_EQ(out_caret_position, 0);

  atk_text_set_caret_offset(input_text, 1);
  ASSERT_TRUE(waiter.WaitForNotification());
  EXPECT_EQ(atk_text_get_caret_offset(input_text), 1);
  EXPECT_EQ(out_caret_position, 1);

  atk_text_set_caret_offset(input_text, 2);
  ASSERT_TRUE(waiter.WaitForNotification());
  EXPECT_EQ(atk_text_get_caret_offset(input_text), 2);
  EXPECT_EQ(out_caret_position, 2);

  g_object_unref(input_text);
}

}  // namespace content
