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

#include "content/browser/accessibility/browser_accessibility.h"

#include "build/build_config.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/accessibility/test_browser_accessibility_delegate.h"
#include "content/public/browser/browser_accessibility_state.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/accessibility/ax_node_position.h"

namespace content {

using RetargetEventType = ui::AXTreeManager::RetargetEventType;

class BrowserAccessibilityTest : public ::testing::Test {
 public:
  BrowserAccessibilityTest();

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

  ~BrowserAccessibilityTest() override;

 protected:
  std::unique_ptr<TestBrowserAccessibilityDelegate>
      test_browser_accessibility_delegate_;

 private:
  void SetUp() override;

  BrowserTaskEnvironment task_environment_;
  content::testing::ScopedContentAXModeSetter ax_mode_setter_;
};

BrowserAccessibilityTest::BrowserAccessibilityTest()
    : ax_mode_setter_(ui::kAXModeComplete) {}

BrowserAccessibilityTest::~BrowserAccessibilityTest() = default;

void BrowserAccessibilityTest::SetUp() {
  test_browser_accessibility_delegate_ =
      std::make_unique<TestBrowserAccessibilityDelegate>();
}

TEST_F(BrowserAccessibilityTest, TestCanFireEvents) {
  ui::AXNodeData text1;
  text1.id = 111;
  text1.role = ax::mojom::Role::kStaticText;
  text1.SetName("One two three.");

  ui::AXNodeData para1;
  para1.id = 11;
  para1.role = ax::mojom::Role::kParagraph;
  para1.child_ids.push_back(text1.id);

  ui::AXNodeData root;
  root.id = 1;
  root.role = ax::mojom::Role::kRootWebArea;
  root.child_ids.push_back(para1.id);

  std::unique_ptr<BrowserAccessibilityManager> manager(
      BrowserAccessibilityManager::Create(
          MakeAXTreeUpdateForTesting(root, para1, text1),
          test_browser_accessibility_delegate_.get()));

  BrowserAccessibility* root_obj = manager->GetBrowserAccessibilityRoot();
  EXPECT_FALSE(root_obj->IsLeaf());
  EXPECT_TRUE(root_obj->CanFireEvents());

  BrowserAccessibility* para_obj = root_obj->PlatformGetChild(0);
  EXPECT_TRUE(para_obj->CanFireEvents());
#if BUILDFLAG(IS_ANDROID)
  EXPECT_TRUE(para_obj->IsLeaf());
#else
  EXPECT_FALSE(para_obj->IsLeaf());
#endif

  BrowserAccessibility* text_obj = manager->GetFromID(111);
  EXPECT_TRUE(text_obj->IsLeaf());
#if !BUILDFLAG(IS_ANDROID)
  EXPECT_TRUE(text_obj->CanFireEvents());
#endif
  BrowserAccessibility* retarget =
      manager->RetargetBrowserAccessibilityForEvents(
          text_obj, RetargetEventType::RetargetEventTypeBlinkHover);
  EXPECT_TRUE(retarget->CanFireEvents());

  manager.reset();
}

#if BUILDFLAG(IS_WIN) || BUILDFLAG(USE_ATK)
TEST_F(BrowserAccessibilityTest, PlatformChildIterator) {
  // (i) => node is ignored
  // Parent Tree
  // 1
  // |__________
  // |     |   |
  // 2(i)  3   4
  // |__________________________________
  // |              |      |           |
  // 5              6      7(i)        8(i)
  // |              |      |________
  // |              |      |       |
  // Child Tree     9(i)   10(i)   11
  //                |      |____
  //                |      |   |
  //                12(i)  13  14
  // Child Tree
  // 1
  // |_________
  // |    |   |
  // 2    3   4
  //      |
  //      5
  ui::AXTreeID parent_tree_id = ui::AXTreeID::CreateNewAXTreeID();
  ui::AXTreeID child_tree_id = ui::AXTreeID::CreateNewAXTreeID();

  ui::AXTreeUpdate parent_tree_update;
  parent_tree_update.tree_data.tree_id = parent_tree_id;
  parent_tree_update.has_tree_data = true;
  parent_tree_update.root_id = 1;
  parent_tree_update.nodes.resize(14);
  parent_tree_update.nodes[0].id = 1;
  parent_tree_update.nodes[0].child_ids = {2, 3, 4};

  parent_tree_update.nodes[1].id = 2;
  parent_tree_update.nodes[1].child_ids = {5, 6, 7, 8};
  parent_tree_update.nodes[1].AddState(ax::mojom::State::kIgnored);

  parent_tree_update.nodes[2].id = 3;
  parent_tree_update.nodes[3].id = 4;

  parent_tree_update.nodes[4].id = 5;
  parent_tree_update.nodes[4].AddChildTreeId(child_tree_id);

  parent_tree_update.nodes[5].id = 6;
  parent_tree_update.nodes[5].child_ids = {9};

  parent_tree_update.nodes[6].id = 7;
  parent_tree_update.nodes[6].child_ids = {10, 11};
  parent_tree_update.nodes[6].AddState(ax::mojom::State::kIgnored);

  parent_tree_update.nodes[7].id = 8;
  parent_tree_update.nodes[7].AddState(ax::mojom::State::kIgnored);

  parent_tree_update.nodes[8].id = 9;
  parent_tree_update.nodes[8].child_ids = {12};
  parent_tree_update.nodes[8].AddState(ax::mojom::State::kIgnored);

  parent_tree_update.nodes[9].id = 10;
  parent_tree_update.nodes[9].child_ids = {13, 14};
  parent_tree_update.nodes[9].AddState(ax::mojom::State::kIgnored);

  parent_tree_update.nodes[10].id = 11;

  parent_tree_update.nodes[11].id = 12;
  parent_tree_update.nodes[11].AddState(ax::mojom::State::kIgnored);

  parent_tree_update.nodes[12].id = 13;

  parent_tree_update.nodes[13].id = 14;

  ui::AXTreeUpdate child_tree_update;
  child_tree_update.tree_data.tree_id = child_tree_id;
  child_tree_update.tree_data.parent_tree_id = parent_tree_id;
  child_tree_update.has_tree_data = true;
  child_tree_update.root_id = 1;
  child_tree_update.nodes.resize(5);
  child_tree_update.nodes[0].id = 1;
  child_tree_update.nodes[0].child_ids = {2, 3, 4};

  child_tree_update.nodes[1].id = 2;

  child_tree_update.nodes[2].id = 3;
  child_tree_update.nodes[2].child_ids = {5};

  child_tree_update.nodes[3].id = 4;

  child_tree_update.nodes[4].id = 5;

  std::unique_ptr<BrowserAccessibilityManager> parent_manager(
      BrowserAccessibilityManager::Create(parent_tree_update, nullptr));

  std::unique_ptr<BrowserAccessibilityManager> child_manager(
      BrowserAccessibilityManager::Create(child_tree_update, nullptr));

  BrowserAccessibility* root_obj =
      parent_manager->GetBrowserAccessibilityRoot();
  // Test traversal
  // PlatformChildren(root_obj) = {5, 6, 13, 15, 11, 3, 4}
  BrowserAccessibility::PlatformChildIterator platform_iterator =
      root_obj->PlatformChildrenBegin();
  EXPECT_EQ(5, platform_iterator->GetId());
  EXPECT_EQ(nullptr, platform_iterator->PlatformGetPreviousSibling());
  EXPECT_EQ(1u, platform_iterator->PlatformChildCount());

  // Test Child-Tree Traversal
  BrowserAccessibility* child_tree_root =
      platform_iterator->PlatformGetFirstChild();
  EXPECT_EQ(1, child_tree_root->GetId());
  BrowserAccessibility::PlatformChildIterator child_tree_iterator =
      child_tree_root->PlatformChildrenBegin();

  EXPECT_EQ(2, child_tree_iterator->GetId());
  ++child_tree_iterator;
  EXPECT_EQ(3, child_tree_iterator->GetId());
  ++child_tree_iterator;
  EXPECT_EQ(4, child_tree_iterator->GetId());

  ++platform_iterator;
  EXPECT_EQ(6, platform_iterator->GetId());

  ++platform_iterator;
  EXPECT_EQ(13, platform_iterator->GetId());

  ++platform_iterator;
  EXPECT_EQ(14, platform_iterator->GetId());

  --platform_iterator;
  EXPECT_EQ(13, platform_iterator->GetId());

  --platform_iterator;
  EXPECT_EQ(6, platform_iterator->GetId());

  ++platform_iterator;
  EXPECT_EQ(13, platform_iterator->GetId());

  ++platform_iterator;
  EXPECT_EQ(14, platform_iterator->GetId());

  ++platform_iterator;
  EXPECT_EQ(11, platform_iterator->GetId());

  ++platform_iterator;
  EXPECT_EQ(3, platform_iterator->GetId());

  ++platform_iterator;
  EXPECT_EQ(4, platform_iterator->GetId());

  ++platform_iterator;
  EXPECT_EQ(root_obj->PlatformChildrenEnd(), platform_iterator);

  // test empty list
  // PlatformChildren(3) = {}
  BrowserAccessibility* node2 = parent_manager->GetFromID(3);
  platform_iterator = node2->PlatformChildrenBegin();
  EXPECT_EQ(node2->PlatformChildrenEnd(), platform_iterator);

  // empty list from ignored node
  // PlatformChildren(8) = {}
  BrowserAccessibility* node8 = parent_manager->GetFromID(8);
  platform_iterator = node8->PlatformChildrenBegin();
  EXPECT_EQ(node8->PlatformChildrenEnd(), platform_iterator);

  // non-empty list from ignored node
  // PlatformChildren(10) = {13, 15}
  BrowserAccessibility* node10 = parent_manager->GetFromID(10);
  platform_iterator = node10->PlatformChildrenBegin();
  EXPECT_EQ(13, platform_iterator->GetId());

  // Two UnignoredChildIterators from the same parent at the same position
  // should be equivalent, even in end position.
  platform_iterator = root_obj->PlatformChildrenBegin();
  BrowserAccessibility::PlatformChildIterator platform_iterator2 =
      root_obj->PlatformChildrenBegin();
  auto end = root_obj->PlatformChildrenEnd();
  while (platform_iterator != end) {
    ASSERT_EQ(platform_iterator, platform_iterator2);
    ++platform_iterator;
    ++platform_iterator2;
  }
  ASSERT_EQ(platform_iterator, platform_iterator2);
}
#endif  // BUILDFLAG(IS_WIN) || BUILDFLAG(USE_ATK)

TEST_F(BrowserAccessibilityTest, GetInnerTextRangeBoundsRect) {
  ui::AXNodeData root;
  root.id = 1;
  root.role = ax::mojom::Role::kRootWebArea;
  root.relative_bounds.bounds = gfx::RectF(0, 0, 800, 600);

  ui::AXNodeData static_text;
  static_text.id = 2;
  static_text.role = ax::mojom::Role::kStaticText;
  static_text.SetName("Hello, world.");
  static_text.relative_bounds.bounds = gfx::RectF(100, 100, 29, 18);
  root.child_ids.push_back(2);

  ui::AXNodeData inline_text1;
  inline_text1.id = 3;
  inline_text1.role = ax::mojom::Role::kInlineTextBox;
  inline_text1.SetName("Hello, ");
  inline_text1.relative_bounds.bounds = gfx::RectF(100, 100, 29, 9);
  inline_text1.SetTextDirection(ax::mojom::WritingDirection::kLtr);
  std::vector<int32_t> character_offsets1;
  character_offsets1.push_back(6);
  character_offsets1.push_back(11);
  character_offsets1.push_back(16);
  character_offsets1.push_back(21);
  character_offsets1.push_back(26);
  character_offsets1.push_back(29);
  character_offsets1.push_back(29);
  inline_text1.AddIntListAttribute(
      ax::mojom::IntListAttribute::kCharacterOffsets, character_offsets1);
  static_text.child_ids.push_back(3);

  ui::AXNodeData inline_text2;
  inline_text2.id = 4;
  inline_text2.role = ax::mojom::Role::kInlineTextBox;
  inline_text2.SetName("world.");
  inline_text2.relative_bounds.bounds = gfx::RectF(100, 109, 28, 9);
  inline_text2.SetTextDirection(ax::mojom::WritingDirection::kLtr);
  std::vector<int32_t> character_offsets2;
  character_offsets2.push_back(5);
  character_offsets2.push_back(10);
  character_offsets2.push_back(15);
  character_offsets2.push_back(20);
  character_offsets2.push_back(25);
  character_offsets2.push_back(28);
  inline_text2.AddIntListAttribute(
      ax::mojom::IntListAttribute::kCharacterOffsets, character_offsets2);
  static_text.child_ids.push_back(4);

  std::unique_ptr<BrowserAccessibilityManager> browser_accessibility_manager(
      BrowserAccessibilityManager::Create(
          MakeAXTreeUpdateForTesting(root, static_text, inline_text1,
                                     inline_text2),
          test_browser_accessibility_delegate_.get()));

  BrowserAccessibility* root_accessible =
      browser_accessibility_manager->GetBrowserAccessibilityRoot();
  ASSERT_NE(nullptr, root_accessible);
  BrowserAccessibility* static_text_accessible =
      root_accessible->PlatformGetChild(0);
  ASSERT_NE(nullptr, static_text_accessible);

#if BUILDFLAG(IS_ANDROID)
  // Android disallows getting inner text from root accessibility nodes.
  EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(),
            root_accessible
                ->GetInnerTextRangeBoundsRect(
                    0, 1, ui::AXCoordinateSystem::kRootFrame,
                    ui::AXClippingBehavior::kUnclipped)
                .ToString());
#else
  // Validate the bounding box of 'H' from root.
  EXPECT_EQ(gfx::Rect(100, 100, 6, 9).ToString(),
            root_accessible
                ->GetInnerTextRangeBoundsRect(
                    0, 1, ui::AXCoordinateSystem::kRootFrame,
                    ui::AXClippingBehavior::kUnclipped)
                .ToString());
#endif

  // Validate the bounding box of 'H' from static text.
  EXPECT_EQ(gfx::Rect(100, 100, 6, 9).ToString(),
            static_text_accessible
                ->GetInnerTextRangeBoundsRect(
                    0, 1, ui::AXCoordinateSystem::kRootFrame,
                    ui::AXClippingBehavior::kUnclipped)
                .ToString());

  // Validate the bounding box of 'Hello' from static text.
  EXPECT_EQ(gfx::Rect(100, 100, 26, 9).ToString(),
            static_text_accessible
                ->GetInnerTextRangeBoundsRect(
                    0, 5, ui::AXCoordinateSystem::kRootFrame,
                    ui::AXClippingBehavior::kUnclipped)
                .ToString());

  // Validate the bounding box of 'Hello, world.' from static text.
  EXPECT_EQ(gfx::Rect(100, 100, 29, 18).ToString(),
            static_text_accessible
                ->GetInnerTextRangeBoundsRect(
                    0, 13, ui::AXCoordinateSystem::kRootFrame,
                    ui::AXClippingBehavior::kUnclipped)
                .ToString());

#if BUILDFLAG(IS_ANDROID)
  // Android disallows getting inner text from root accessibility nodes.
  EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(),
            root_accessible
                ->GetInnerTextRangeBoundsRect(
                    0, 13, ui::AXCoordinateSystem::kRootFrame,
                    ui::AXClippingBehavior::kUnclipped)
                .ToString());
#else
  // Validate the bounding box of 'Hello, world.' from root.
  EXPECT_EQ(gfx::Rect(100, 100, 29, 18).ToString(),
            root_accessible
                ->GetInnerTextRangeBoundsRect(
                    0, 13, ui::AXCoordinateSystem::kRootFrame,
                    ui::AXClippingBehavior::kUnclipped)
                .ToString());
#endif
}

TEST_F(BrowserAccessibilityTest, GetInnerTextRangeBoundsRectPlainTextField) {
  // Text area with 'Hello' text
  // rootWebArea
  // ++textField
  // ++++genericContainer
  // ++++++staticText
  // ++++++++inlineTextBox
  ui::AXNodeData root;
  root.id = 1;
  root.role = ax::mojom::Role::kRootWebArea;
  root.relative_bounds.bounds = gfx::RectF(0, 0, 800, 600);

  ui::AXNodeData textarea;
  textarea.id = 2;
  textarea.role = ax::mojom::Role::kTextField;
  textarea.SetValue("Hello");
  textarea.relative_bounds.bounds = gfx::RectF(100, 100, 150, 20);
  root.child_ids.push_back(2);

  ui::AXNodeData container;
  container.id = 3;
  container.role = ax::mojom::Role::kGenericContainer;
  container.relative_bounds.bounds = textarea.relative_bounds.bounds;
  textarea.child_ids.push_back(3);

  ui::AXNodeData static_text;
  static_text.id = 4;
  static_text.role = ax::mojom::Role::kStaticText;
  static_text.SetName("Hello");
  static_text.relative_bounds.bounds = gfx::RectF(100, 100, 50, 10);
  container.child_ids.push_back(4);

  ui::AXNodeData inline_text1;
  inline_text1.id = 5;
  inline_text1.role = ax::mojom::Role::kInlineTextBox;
  inline_text1.SetName("Hello");
  inline_text1.relative_bounds.bounds = gfx::RectF(100, 100, 50, 10);
  inline_text1.AddIntListAttribute(
      ax::mojom::IntListAttribute::kCharacterOffsets, {10, 20, 30, 40, 50});

  inline_text1.SetTextDirection(ax::mojom::WritingDirection::kLtr);
  static_text.child_ids.push_back(5);

  std::unique_ptr<BrowserAccessibilityManager> browser_accessibility_manager(
      BrowserAccessibilityManager::Create(
          MakeAXTreeUpdateForTesting(root, textarea, container, static_text,
                                     inline_text1),
          test_browser_accessibility_delegate_.get()));

  BrowserAccessibility* root_accessible =
      browser_accessibility_manager->GetBrowserAccessibilityRoot();
  ASSERT_NE(nullptr, root_accessible);
  BrowserAccessibility* textarea_accessible =
      root_accessible->PlatformGetChild(0);
  ASSERT_NE(nullptr, textarea_accessible);

  // Validate the bounds of 'ell'.
  EXPECT_EQ(gfx::Rect(110, 100, 30, 10),
            textarea_accessible->GetInnerTextRangeBoundsRect(
                1, 4, ui::AXCoordinateSystem::kRootFrame,
                ui::AXClippingBehavior::kUnclipped));
}

TEST_F(BrowserAccessibilityTest, GetInnerTextRangeBoundsRectMultiElement) {
  ui::AXNodeData root;
  root.id = 1;
  root.role = ax::mojom::Role::kRootWebArea;
  root.relative_bounds.bounds = gfx::RectF(0, 0, 800, 600);

  ui::AXNodeData static_text;
  static_text.id = 2;
  static_text.role = ax::mojom::Role::kStaticText;
  static_text.SetName("ABC");
  static_text.relative_bounds.bounds = gfx::RectF(0, 20, 33, 9);
  root.child_ids.push_back(2);

  ui::AXNodeData inline_text1;
  inline_text1.id = 3;
  inline_text1.role = ax::mojom::Role::kInlineTextBox;
  inline_text1.SetName("ABC");
  inline_text1.relative_bounds.bounds = gfx::RectF(0, 20, 33, 9);
  inline_text1.SetTextDirection(ax::mojom::WritingDirection::kLtr);
  std::vector<int32_t> character_offsets{10, 21, 33};
  inline_text1.AddIntListAttribute(
      ax::mojom::IntListAttribute::kCharacterOffsets, character_offsets);
  static_text.child_ids.push_back(3);

  ui::AXNodeData static_text2;
  static_text2.id = 4;
  static_text2.role = ax::mojom::Role::kStaticText;
  static_text2.SetName("ABC");
  static_text2.relative_bounds.bounds = gfx::RectF(10, 40, 33, 9);
  root.child_ids.push_back(4);

  ui::AXNodeData inline_text2;
  inline_text2.id = 5;
  inline_text2.role = ax::mojom::Role::kInlineTextBox;
  inline_text2.SetName("ABC");
  inline_text2.relative_bounds.bounds = gfx::RectF(10, 40, 33, 9);
  inline_text2.SetTextDirection(ax::mojom::WritingDirection::kLtr);
  inline_text2.AddIntListAttribute(
      ax::mojom::IntListAttribute::kCharacterOffsets, character_offsets);
  static_text2.child_ids.push_back(5);

  std::unique_ptr<BrowserAccessibilityManager> browser_accessibility_manager(
      BrowserAccessibilityManager::Create(
          MakeAXTreeUpdateForTesting(root, static_text, inline_text1,
                                     static_text2, inline_text2),
          test_browser_accessibility_delegate_.get()));

  BrowserAccessibility* root_accessible =
      browser_accessibility_manager->GetBrowserAccessibilityRoot();
  ASSERT_NE(nullptr, root_accessible);
  BrowserAccessibility* static_text_accessible =
      root_accessible->PlatformGetChild(0);
  ASSERT_NE(nullptr, static_text_accessible);
  BrowserAccessibility* static_text_accessible2 =
      root_accessible->PlatformGetChild(1);
  ASSERT_NE(nullptr, static_text_accessible);

  // Validate the bounds of 'ABC' on the first line.
  EXPECT_EQ(gfx::Rect(0, 20, 33, 9).ToString(),
            static_text_accessible
                ->GetInnerTextRangeBoundsRect(
                    0, 3, ui::AXCoordinateSystem::kRootFrame,
                    ui::AXClippingBehavior::kUnclipped)
                .ToString());

  // Validate the bounds of only 'AB' on the first line.
  EXPECT_EQ(gfx::Rect(0, 20, 21, 9).ToString(),
            static_text_accessible
                ->GetInnerTextRangeBoundsRect(
                    0, 2, ui::AXCoordinateSystem::kRootFrame,
                    ui::AXClippingBehavior::kUnclipped)
                .ToString());

  // Validate the bounds of only 'BC' on the first line.
  EXPECT_EQ(gfx::Rect(10, 20, 23, 9).ToString(),
            static_text_accessible
                ->GetInnerTextRangeBoundsRect(
                    1, 3, ui::AXCoordinateSystem::kRootFrame,
                    ui::AXClippingBehavior::kUnclipped)
                .ToString());

  // Validate the bounds of 'ABC' on the second line.
  EXPECT_EQ(gfx::Rect(10, 40, 33, 9).ToString(),
            static_text_accessible2
                ->GetInnerTextRangeBoundsRect(
                    0, 3, ui::AXCoordinateSystem::kRootFrame,
                    ui::AXClippingBehavior::kUnclipped)
                .ToString());

#if BUILDFLAG(IS_ANDROID)
  // Android disallows getting inner text from accessibility root nodes.
  EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(),
            root_accessible
                ->GetInnerTextRangeBoundsRect(
                    0, 6, ui::AXCoordinateSystem::kRootFrame,
                    ui::AXClippingBehavior::kUnclipped)
                .ToString());

  // Android disallows getting inner text from accessibility root nodes.
  EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(),
            root_accessible
                ->GetInnerTextRangeBoundsRect(
                    2, 4, ui::AXCoordinateSystem::kRootFrame,
                    ui::AXClippingBehavior::kUnclipped)
                .ToString());
#else
  // Validate the bounds of 'ABCABC' from both lines.
  EXPECT_EQ(gfx::Rect(0, 20, 43, 29).ToString(),
            root_accessible
                ->GetInnerTextRangeBoundsRect(
                    0, 6, ui::AXCoordinateSystem::kRootFrame,
                    ui::AXClippingBehavior::kUnclipped)
                .ToString());

  // Validate the bounds of 'CA' from both lines.
  EXPECT_EQ(gfx::Rect(10, 20, 23, 29).ToString(),
            root_accessible
                ->GetInnerTextRangeBoundsRect(
                    2, 4, ui::AXCoordinateSystem::kRootFrame,
                    ui::AXClippingBehavior::kUnclipped)
                .ToString());
#endif
}

TEST_F(BrowserAccessibilityTest, GetInnerTextRangeBoundsRectBiDi) {
  // In this example, we assume that the string "123abc" is rendered with "123"
  // going left-to-right and "abc" going right-to-left. In other words,
  // on-screen it would look like "123cba".
  ui::AXNodeData root;
  root.id = 1;
  root.role = ax::mojom::Role::kRootWebArea;
  root.relative_bounds.bounds = gfx::RectF(0, 0, 800, 600);

  ui::AXNodeData static_text;
  static_text.id = 2;
  static_text.role = ax::mojom::Role::kStaticText;
  static_text.SetName("123abc");
  static_text.relative_bounds.bounds = gfx::RectF(100, 100, 60, 20);
  root.child_ids.push_back(2);

  ui::AXNodeData inline_text1;
  inline_text1.id = 3;
  inline_text1.role = ax::mojom::Role::kInlineTextBox;
  inline_text1.SetName("123");
  inline_text1.relative_bounds.bounds = gfx::RectF(100, 100, 30, 20);
  inline_text1.SetTextDirection(ax::mojom::WritingDirection::kLtr);
  std::vector<int32_t> character_offsets1;
  character_offsets1.push_back(10);  // 0
  character_offsets1.push_back(20);  // 1
  character_offsets1.push_back(30);  // 2
  inline_text1.AddIntListAttribute(
      ax::mojom::IntListAttribute::kCharacterOffsets, character_offsets1);
  static_text.child_ids.push_back(3);

  ui::AXNodeData inline_text2;
  inline_text2.id = 4;
  inline_text2.role = ax::mojom::Role::kInlineTextBox;
  inline_text2.SetName("abc");
  inline_text2.relative_bounds.bounds = gfx::RectF(130, 100, 30, 20);
  inline_text2.SetTextDirection(ax::mojom::WritingDirection::kRtl);
  std::vector<int32_t> character_offsets2;
  character_offsets2.push_back(10);
  character_offsets2.push_back(20);
  character_offsets2.push_back(30);
  inline_text2.AddIntListAttribute(
      ax::mojom::IntListAttribute::kCharacterOffsets, character_offsets2);
  static_text.child_ids.push_back(4);

  std::unique_ptr<BrowserAccessibilityManager> browser_accessibility_manager(
      BrowserAccessibilityManager::Create(
          MakeAXTreeUpdateForTesting(root, static_text, inline_text1,
                                     inline_text2),
          test_browser_accessibility_delegate_.get()));

  BrowserAccessibility* root_accessible =
      browser_accessibility_manager->GetBrowserAccessibilityRoot();
  ASSERT_NE(nullptr, root_accessible);
  BrowserAccessibility* static_text_accessible =
      root_accessible->PlatformGetChild(0);
  ASSERT_NE(nullptr, static_text_accessible);

  EXPECT_EQ(gfx::Rect(100, 100, 60, 20).ToString(),
            static_text_accessible
                ->GetInnerTextRangeBoundsRect(
                    0, 6, ui::AXCoordinateSystem::kRootFrame,
                    ui::AXClippingBehavior::kUnclipped)
                .ToString());

  EXPECT_EQ(gfx::Rect(100, 100, 10, 20).ToString(),
            static_text_accessible
                ->GetInnerTextRangeBoundsRect(
                    0, 1, ui::AXCoordinateSystem::kRootFrame,
                    ui::AXClippingBehavior::kUnclipped)
                .ToString());

  EXPECT_EQ(gfx::Rect(100, 100, 30, 20).ToString(),
            static_text_accessible
                ->GetInnerTextRangeBoundsRect(
                    0, 3, ui::AXCoordinateSystem::kRootFrame,
                    ui::AXClippingBehavior::kUnclipped)
                .ToString());

  EXPECT_EQ(gfx::Rect(150, 100, 10, 20).ToString(),
            static_text_accessible
                ->GetInnerTextRangeBoundsRect(
                    3, 4, ui::AXCoordinateSystem::kRootFrame,
                    ui::AXClippingBehavior::kUnclipped)
                .ToString());

  EXPECT_EQ(gfx::Rect(130, 100, 30, 20).ToString(),
            static_text_accessible
                ->GetInnerTextRangeBoundsRect(
                    3, 6, ui::AXCoordinateSystem::kRootFrame,
                    ui::AXClippingBehavior::kUnclipped)
                .ToString());

  // This range is only two characters, but because of the direction switch
  // the bounds are as wide as four characters.
  EXPECT_EQ(gfx::Rect(120, 100, 40, 20).ToString(),
            static_text_accessible
                ->GetInnerTextRangeBoundsRect(
                    2, 4, ui::AXCoordinateSystem::kRootFrame,
                    ui::AXClippingBehavior::kUnclipped)
                .ToString());
}

TEST_F(BrowserAccessibilityTest, GetInnerTextRangeBoundsRectScrolledWindow) {
  ui::AXNodeData root;
  root.id = 1;
  root.role = ax::mojom::Role::kRootWebArea;
  root.AddIntAttribute(ax::mojom::IntAttribute::kScrollX, 25);
  root.AddIntAttribute(ax::mojom::IntAttribute::kScrollY, 50);
  root.relative_bounds.bounds = gfx::RectF(0, 0, 800, 600);

  ui::AXNodeData static_text;
  static_text.id = 2;
  static_text.role = ax::mojom::Role::kStaticText;
  static_text.SetName("ABC");
  static_text.relative_bounds.bounds = gfx::RectF(100, 100, 16, 9);
  root.child_ids.push_back(2);

  ui::AXNodeData inline_text;
  inline_text.id = 3;
  inline_text.role = ax::mojom::Role::kInlineTextBox;
  inline_text.SetName("ABC");
  inline_text.relative_bounds.bounds = gfx::RectF(100, 100, 16, 9);
  inline_text.SetTextDirection(ax::mojom::WritingDirection::kLtr);
  std::vector<int32_t> character_offsets1;
  character_offsets1.push_back(6);   // 0
  character_offsets1.push_back(11);  // 1
  character_offsets1.push_back(16);  // 2
  inline_text.AddIntListAttribute(
      ax::mojom::IntListAttribute::kCharacterOffsets, character_offsets1);
  static_text.child_ids.push_back(3);

  std::unique_ptr<BrowserAccessibilityManager> browser_accessibility_manager(
      BrowserAccessibilityManager::Create(
          MakeAXTreeUpdateForTesting(root, static_text, inline_text),
          test_browser_accessibility_delegate_.get()));

  browser_accessibility_manager
      ->SetUseRootScrollOffsetsWhenComputingBoundsForTesting(true);

  BrowserAccessibility* root_accessible =
      browser_accessibility_manager->GetBrowserAccessibilityRoot();
  ASSERT_NE(nullptr, root_accessible);
  BrowserAccessibility* static_text_accessible =
      root_accessible->PlatformGetChild(0);
  ASSERT_NE(nullptr, static_text_accessible);

  if (browser_accessibility_manager
          ->UseRootScrollOffsetsWhenComputingBounds()) {
    EXPECT_EQ(gfx::Rect(75, 50, 16, 9).ToString(),
              static_text_accessible
                  ->GetInnerTextRangeBoundsRect(
                      0, 3, ui::AXCoordinateSystem::kRootFrame,
                      ui::AXClippingBehavior::kUnclipped)
                  .ToString());
  } else {
    EXPECT_EQ(gfx::Rect(100, 100, 16, 9).ToString(),
              static_text_accessible
                  ->GetInnerTextRangeBoundsRect(
                      0, 3, ui::AXCoordinateSystem::kRootFrame,
                      ui::AXClippingBehavior::kUnclipped)
                  .ToString());
  }
}

TEST_F(BrowserAccessibilityTest, GetAuthorUniqueId) {
  ui::AXNodeData root;
  root.id = 1;
  root.role = ax::mojom::Role::kRootWebArea;
  root.html_attributes.push_back(std::make_pair("id", "my_html_id"));

  std::unique_ptr<BrowserAccessibilityManager> browser_accessibility_manager(
      BrowserAccessibilityManager::Create(
          MakeAXTreeUpdateForTesting(root),
          test_browser_accessibility_delegate_.get()));
  ASSERT_NE(nullptr, browser_accessibility_manager.get());

  BrowserAccessibility* root_accessible =
      browser_accessibility_manager->GetBrowserAccessibilityRoot();
  ASSERT_NE(nullptr, root_accessible);

  ASSERT_EQ(u"my_html_id", root_accessible->GetAuthorUniqueId());
}

TEST_F(BrowserAccessibilityTest, NextWordPositionWithHypertext) {
  // Build a tree simulating an INPUT control with placeholder text.
  ui::AXNodeData root;
  root.id = 1;
  ui::AXNodeData input;
  input.id = 2;
  ui::AXNodeData text_container;
  text_container.id = 3;
  ui::AXNodeData static_text;
  static_text.id = 4;
  ui::AXNodeData inline_text;
  inline_text.id = 5;

  root.role = ax::mojom::Role::kRootWebArea;
  root.child_ids = {input.id};

  input.role = ax::mojom::Role::kTextField;
  input.AddState(ax::mojom::State::kEditable);
  input.SetName("Search the web");
  input.child_ids = {text_container.id};

  text_container.role = ax::mojom::Role::kGenericContainer;
  text_container.child_ids = {static_text.id};

  static_text.role = ax::mojom::Role::kStaticText;
  static_text.SetName("Search the web");
  static_text.child_ids = {inline_text.id};

  inline_text.role = ax::mojom::Role::kInlineTextBox;
  inline_text.SetName("Search the web");
  inline_text.AddIntListAttribute(ax::mojom::IntListAttribute::kWordStarts,
                                  {0, 7, 11});
  inline_text.AddIntListAttribute(ax::mojom::IntListAttribute::kWordEnds,
                                  {6, 10, 14});

  std::unique_ptr<BrowserAccessibilityManager> browser_accessibility_manager(
      BrowserAccessibilityManager::Create(
          MakeAXTreeUpdateForTesting(root, input, text_container, static_text,
                                     inline_text),
          test_browser_accessibility_delegate_.get()));
  ASSERT_NE(nullptr, browser_accessibility_manager.get());

  BrowserAccessibility* root_accessible =
      browser_accessibility_manager->GetBrowserAccessibilityRoot();
  ASSERT_NE(nullptr, root_accessible);
  ASSERT_NE(0u, root_accessible->InternalChildCount());
  BrowserAccessibility* input_accessible = root_accessible->InternalGetChild(0);
  ASSERT_NE(nullptr, input_accessible);

  // Create a text position at offset 0 in the input control
  BrowserAccessibility::AXPosition position =
      input_accessible->CreateTextPositionAt(0);

  // On platforms that expose IA2 or ATK hypertext, moving by word should work
  // the same as if the value of the text field is equal to the placeholder
  // text.
  //
  // This is because visually the placeholder text appears in the text field in
  // the same location as its value, and the user should be able to read it
  // using standard screen reader commands, such as "read current word" and
  // "read current line". Only once the user starts typing should the
  // placeholder disappear.

  BrowserAccessibility::AXPosition next_word_start =
      position->CreateNextWordStartPosition(
          {ui::AXBoundaryBehavior::kCrossBoundary,
           ui::AXBoundaryDetection::kDontCheckInitialPosition});
  if (position->MaxTextOffset() == 0) {
    EXPECT_TRUE(next_word_start->IsNullPosition());
  } else {
    EXPECT_EQ(
        "TextPosition anchor_id=2 text_offset=7 affinity=downstream "
        "annotated_text=Search <t>he web",
        next_word_start->ToString());
  }

  BrowserAccessibility::AXPosition next_word_end =
      position->CreateNextWordEndPosition(
          {ui::AXBoundaryBehavior::kCrossBoundary,
           ui::AXBoundaryDetection::kDontCheckInitialPosition});
  if (position->MaxTextOffset() == 0) {
    EXPECT_TRUE(next_word_end->IsNullPosition());
  } else {
    EXPECT_EQ(
        "TextPosition anchor_id=2 text_offset=6 affinity=downstream "
        "annotated_text=Search< >the web",
        next_word_end->ToString());
  }
}

// Tests that the browser manager retrieves the name from the root node of the
// child subtree for portals.
TEST_F(BrowserAccessibilityTest, PortalName) {
  ui::AXTreeID parent_tree_id = ui::AXTreeID::CreateNewAXTreeID();
  ui::AXTreeID child_tree_id = ui::AXTreeID::CreateNewAXTreeID();

  ui::AXTreeUpdate parent_tree_update;
  parent_tree_update.tree_data.tree_id = parent_tree_id;
  parent_tree_update.has_tree_data = true;
  parent_tree_update.root_id = 1;
  parent_tree_update.nodes.resize(1);

  parent_tree_update.nodes[0].id = 1;
  parent_tree_update.nodes[0].role = ax::mojom::Role::kPortal;
  parent_tree_update.nodes[0].AddChildTreeId(child_tree_id);

  ui::AXTreeUpdate child_tree_update;
  child_tree_update.tree_data.tree_id = child_tree_id;
  child_tree_update.tree_data.parent_tree_id = parent_tree_id;
  child_tree_update.has_tree_data = true;
  child_tree_update.root_id = 1;
  child_tree_update.nodes.resize(1);

  child_tree_update.nodes[0].id = 1;
  child_tree_update.nodes[0].role = ax::mojom::Role::kRootWebArea;
  child_tree_update.nodes[0].AddStringAttribute(
      ax::mojom::StringAttribute::kName, "name");

  std::unique_ptr<BrowserAccessibilityManager> parent_manager(
      BrowserAccessibilityManager::Create(parent_tree_update, nullptr));

  std::unique_ptr<BrowserAccessibilityManager> child_manager(
      BrowserAccessibilityManager::Create(child_tree_update, nullptr));

  // Portal node should use name from root of child tree.
  EXPECT_EQ("name", child_manager->GetBrowserAccessibilityRoot()->GetName());
  EXPECT_EQ("name", parent_manager->GetBrowserAccessibilityRoot()->GetName());

  // Explicitly add name to portal node.
  parent_tree_update.nodes[0].AddStringAttribute(
      ax::mojom::StringAttribute::kName, "name2");
  parent_tree_update.nodes[0].SetNameFrom(ax::mojom::NameFrom::kAttribute);
  parent_manager->Initialize(parent_tree_update);

  // Portal node should now use name from attribute.
  EXPECT_EQ("name", child_manager->GetBrowserAccessibilityRoot()->GetName());
  EXPECT_EQ("name2", parent_manager->GetBrowserAccessibilityRoot()->GetName());
}

TEST_F(BrowserAccessibilityTest, GetIndexInParent) {
  ui::AXNodeData root;
  root.id = 1;
  root.role = ax::mojom::Role::kRootWebArea;
  root.child_ids = {2};

  ui::AXNodeData static_text;
  static_text.id = 2;
  static_text.role = ax::mojom::Role::kStaticText;
  static_text.SetName("ABC");

  std::unique_ptr<BrowserAccessibilityManager> browser_accessibility_manager(
      BrowserAccessibilityManager::Create(
          MakeAXTreeUpdateForTesting(root, static_text),
          test_browser_accessibility_delegate_.get()));
  ASSERT_NE(nullptr, browser_accessibility_manager.get());

  BrowserAccessibility* root_accessible =
      browser_accessibility_manager->GetBrowserAccessibilityRoot();
  ASSERT_NE(nullptr, root_accessible);
  // Should be nullopt for kRootWebArea since it doesn't have a calculated
  // index.
  EXPECT_FALSE(root_accessible->GetIndexInParent().has_value());
  BrowserAccessibility* child_accessible = root_accessible->InternalGetChild(0);
  ASSERT_NE(nullptr, child_accessible);
  // Returns the index calculated in AXNode.
  EXPECT_EQ(0u, child_accessible->GetIndexInParent());
}

TEST_F(BrowserAccessibilityTest, CreatePositionAt) {
  ui::AXNodeData root_1;
  root_1.id = 1;
  root_1.role = ax::mojom::Role::kRootWebArea;
  root_1.child_ids = {2};

  ui::AXNodeData gc_2;
  gc_2.id = 2;
  gc_2.role = ax::mojom::Role::kGenericContainer;
  gc_2.child_ids = {3};

  ui::AXNodeData text_3;
  text_3.id = 3;
  text_3.role = ax::mojom::Role::kStaticText;
  text_3.SetName("text");

  std::unique_ptr<BrowserAccessibilityManager> browser_accessibility_manager(
      BrowserAccessibilityManager::Create(
          MakeAXTreeUpdateForTesting(root_1, gc_2, text_3),
          test_browser_accessibility_delegate_.get()));
  ASSERT_NE(nullptr, browser_accessibility_manager.get());

  BrowserAccessibility* gc_accessible =
      browser_accessibility_manager->GetBrowserAccessibilityRoot()
          ->PlatformGetChild(0);
  ASSERT_NE(nullptr, gc_accessible);

  BrowserAccessibility::AXPosition pos = gc_accessible->CreatePositionAt(0);
  EXPECT_TRUE(pos->IsTreePosition());

  ASSERT_EQ(1U, gc_accessible->InternalChildCount());
#if BUILDFLAG(IS_ANDROID)
  // On Android, nodes with only static text can drop their children.
  ASSERT_EQ(0U, gc_accessible->PlatformChildCount());
#else
  ASSERT_EQ(1U, gc_accessible->PlatformChildCount());
  BrowserAccessibility* text_accessible = gc_accessible->PlatformGetChild(0);
  ASSERT_NE(nullptr, text_accessible);

  pos = text_accessible->CreatePositionAt(0);
  EXPECT_TRUE(pos->IsTextPosition());
#endif  // BUILDFLAG(IS_ANDROID)
}

}  // namespace content
