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

#include "ui/accessibility/ax_node.h"

#include <stdint.h>
#include <memory>
#include <utility>
#include <vector>

#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/accessibility/ax_position.h"
#include "ui/accessibility/ax_tree.h"
#include "ui/accessibility/ax_tree_data.h"
#include "ui/accessibility/ax_tree_id.h"
#include "ui/accessibility/test_ax_tree_update.h"
#include "ui/accessibility/test_single_ax_tree_manager.h"
#include "ui/gfx/geometry/rect_f.h"

namespace ui {

namespace {

// The third argument is an optional description string which we don't need
// because, after verifying manually, test errors are descriptive enough.
MATCHER_P(HasAXNodeID, ax_node_data, "") {
  return arg->id() == ax_node_data.id;
}

}  // namespace

using ::testing::ElementsAre;

TEST(AXNodeTest, TreeWalking) {
  // ++kRootWebArea
  // ++++kParagraph
  // ++++++kStaticText IGNORED
  // ++++kParagraph IGNORED
  // ++++++kStaticText
  // ++++kParagraph
  // ++++++kStaticText
  // ++++kParagraph IGNORED
  // ++++++kLink IGNORED
  // ++++++++kStaticText
  // ++++++kButton

  // Numbers at the end of variable names indicate their position under the
  // root.
  AXNodeData root;
  AXNodeData paragraph_0;
  AXNodeData static_text_0_0_ignored;
  AXNodeData paragraph_1_ignored;
  AXNodeData static_text_1_0;
  AXNodeData paragraph_2;
  AXNodeData static_text_2_0;
  AXNodeData paragraph_3_ignored;
  AXNodeData link_3_0_ignored;
  AXNodeData static_text_3_0_0;
  AXNodeData button_3_1;

  root.id = 1;
  paragraph_0.id = 2;
  static_text_0_0_ignored.id = 3;
  paragraph_1_ignored.id = 4;
  static_text_1_0.id = 5;
  paragraph_2.id = 6;
  static_text_2_0.id = 7;
  paragraph_3_ignored.id = 8;
  link_3_0_ignored.id = 9;
  static_text_3_0_0.id = 10;
  button_3_1.id = 11;

  root.role = ax::mojom::Role::kRootWebArea;
  root.child_ids = {paragraph_0.id, paragraph_1_ignored.id, paragraph_2.id,
                    paragraph_3_ignored.id};

  paragraph_0.role = ax::mojom::Role::kParagraph;
  paragraph_0.child_ids = {static_text_0_0_ignored.id};

  static_text_0_0_ignored.role = ax::mojom::Role::kStaticText;
  static_text_0_0_ignored.AddState(ax::mojom::State::kIgnored);
  static_text_0_0_ignored.SetName("static_text_0_0_ignored");

  paragraph_1_ignored.role = ax::mojom::Role::kParagraph;
  paragraph_1_ignored.AddState(ax::mojom::State::kIgnored);
  paragraph_1_ignored.child_ids = {static_text_1_0.id};

  static_text_1_0.role = ax::mojom::Role::kStaticText;
  static_text_1_0.SetName("static_text_1_0");

  paragraph_2.role = ax::mojom::Role::kParagraph;
  paragraph_2.child_ids = {static_text_2_0.id};

  static_text_2_0.role = ax::mojom::Role::kStaticText;
  static_text_2_0.SetName("static_text_2_0");

  paragraph_3_ignored.role = ax::mojom::Role::kParagraph;
  paragraph_3_ignored.AddState(ax::mojom::State::kIgnored);
  paragraph_3_ignored.child_ids = {link_3_0_ignored.id, button_3_1.id};

  link_3_0_ignored.role = ax::mojom::Role::kLink;
  link_3_0_ignored.AddState(ax::mojom::State::kLinked);
  link_3_0_ignored.AddState(ax::mojom::State::kIgnored);
  link_3_0_ignored.child_ids = {static_text_3_0_0.id};

  static_text_3_0_0.role = ax::mojom::Role::kStaticText;
  static_text_3_0_0.SetName("static_text_3_0_0");

  button_3_1.role = ax::mojom::Role::kButton;
  button_3_1.SetName("button_3_1");

  AXTreeUpdate initial_state;
  initial_state.root_id = root.id;
  initial_state.nodes = {root,
                         paragraph_0,
                         static_text_0_0_ignored,
                         paragraph_1_ignored,
                         static_text_1_0,
                         paragraph_2,
                         static_text_2_0,
                         paragraph_3_ignored,
                         link_3_0_ignored,
                         static_text_3_0_0,
                         button_3_1};
  initial_state.has_tree_data = true;

  AXTreeData tree_data;
  tree_data.tree_id = AXTreeID::CreateNewAXTreeID();
  tree_data.title = "Application";
  initial_state.tree_data = tree_data;

  AXTree tree;
  ASSERT_TRUE(tree.Unserialize(initial_state)) << tree.error();

  const AXNode* root_node = tree.root();
  ASSERT_EQ(root.id, root_node->id());

  EXPECT_THAT(
      root_node->GetAllChildren(),
      ElementsAre(HasAXNodeID(paragraph_0), HasAXNodeID(paragraph_1_ignored),
                  HasAXNodeID(paragraph_2), HasAXNodeID(paragraph_3_ignored)));
  EXPECT_EQ(4u, root_node->GetChildCount());
  EXPECT_EQ(4u, root_node->GetChildCountCrossingTreeBoundary());
  EXPECT_EQ(5u, root_node->GetUnignoredChildCount());
  EXPECT_EQ(5u, root_node->GetUnignoredChildCountCrossingTreeBoundary());

  EXPECT_EQ(paragraph_0.id, root_node->GetChildAtIndex(0)->id());
  EXPECT_EQ(paragraph_1_ignored.id, root_node->GetChildAtIndex(1)->id());
  EXPECT_EQ(paragraph_2.id, root_node->GetChildAtIndex(2)->id());
  EXPECT_EQ(paragraph_3_ignored.id, root_node->GetChildAtIndex(3)->id());
  EXPECT_EQ(nullptr, root_node->GetChildAtIndex(4));

  EXPECT_EQ(paragraph_0.id,
            root_node->GetChildAtIndexCrossingTreeBoundary(0)->id());
  EXPECT_EQ(paragraph_1_ignored.id,
            root_node->GetChildAtIndexCrossingTreeBoundary(1)->id());
  EXPECT_EQ(paragraph_2.id,
            root_node->GetChildAtIndexCrossingTreeBoundary(2)->id());
  EXPECT_EQ(paragraph_3_ignored.id,
            root_node->GetChildAtIndexCrossingTreeBoundary(3)->id());
  EXPECT_EQ(nullptr, root_node->GetChildAtIndexCrossingTreeBoundary(4));

  EXPECT_EQ(paragraph_0.id, root_node->GetUnignoredChildAtIndex(0)->id());
  EXPECT_EQ(static_text_1_0.id, root_node->GetUnignoredChildAtIndex(1)->id());
  EXPECT_EQ(paragraph_2.id, root_node->GetUnignoredChildAtIndex(2)->id());
  EXPECT_EQ(static_text_3_0_0.id, root_node->GetUnignoredChildAtIndex(3)->id());
  EXPECT_EQ(button_3_1.id, root_node->GetUnignoredChildAtIndex(4)->id());
  EXPECT_EQ(nullptr, root_node->GetUnignoredChildAtIndex(5));

  EXPECT_EQ(paragraph_0.id,
            root_node->GetUnignoredChildAtIndexCrossingTreeBoundary(0)->id());
  EXPECT_EQ(static_text_1_0.id,
            root_node->GetUnignoredChildAtIndexCrossingTreeBoundary(1)->id());
  EXPECT_EQ(paragraph_2.id,
            root_node->GetUnignoredChildAtIndexCrossingTreeBoundary(2)->id());
  EXPECT_EQ(static_text_3_0_0.id,
            root_node->GetUnignoredChildAtIndexCrossingTreeBoundary(3)->id());
  EXPECT_EQ(button_3_1.id,
            root_node->GetUnignoredChildAtIndexCrossingTreeBoundary(4)->id());
  EXPECT_EQ(nullptr,
            root_node->GetUnignoredChildAtIndexCrossingTreeBoundary(5));

  EXPECT_EQ(nullptr, root_node->GetParent());
  EXPECT_EQ(nullptr, root_node->GetParentCrossingTreeBoundary());
  EXPECT_EQ(nullptr, root_node->GetUnignoredParent());
  EXPECT_EQ(nullptr, root_node->GetUnignoredParentCrossingTreeBoundary());

  EXPECT_EQ(root_node, tree.GetFromId(paragraph_0.id)->GetParent());
  EXPECT_EQ(root_node,
            tree.GetFromId(paragraph_0.id)->GetParentCrossingTreeBoundary());
  EXPECT_EQ(root_node, tree.GetFromId(paragraph_0.id)->GetUnignoredParent());
  EXPECT_EQ(
      root_node,
      tree.GetFromId(paragraph_0.id)->GetUnignoredParentCrossingTreeBoundary());

  EXPECT_EQ(tree.GetFromId(paragraph_1_ignored.id),
            tree.GetFromId(static_text_1_0.id)->GetParent());
  EXPECT_EQ(
      tree.GetFromId(paragraph_1_ignored.id),
      tree.GetFromId(static_text_1_0.id)->GetParentCrossingTreeBoundary());
  EXPECT_EQ(root_node,
            tree.GetFromId(static_text_1_0.id)->GetUnignoredParent());
  EXPECT_EQ(root_node, tree.GetFromId(static_text_1_0.id)
                           ->GetUnignoredParentCrossingTreeBoundary());

  EXPECT_EQ(0u, root_node->GetIndexInParent());
  EXPECT_EQ(0u, root_node->GetUnignoredIndexInParent());

  EXPECT_EQ(2u, tree.GetFromId(paragraph_2.id)->GetIndexInParent());
  EXPECT_EQ(1u,
            tree.GetFromId(static_text_1_0.id)->GetUnignoredIndexInParent());
  EXPECT_EQ(2u, tree.GetFromId(paragraph_2.id)->GetUnignoredIndexInParent());

  EXPECT_EQ(paragraph_0.id, root_node->GetFirstChild()->id());
  EXPECT_EQ(paragraph_0.id,
            root_node->GetFirstChildCrossingTreeBoundary()->id());
  EXPECT_EQ(paragraph_0.id, root_node->GetFirstUnignoredChild()->id());
  EXPECT_EQ(paragraph_0.id,
            root_node->GetFirstUnignoredChildCrossingTreeBoundary()->id());

  EXPECT_EQ(paragraph_3_ignored.id, root_node->GetLastChild()->id());
  EXPECT_EQ(paragraph_3_ignored.id,
            root_node->GetLastChildCrossingTreeBoundary()->id());
  EXPECT_EQ(button_3_1.id, root_node->GetLastUnignoredChild()->id());
  EXPECT_EQ(button_3_1.id,
            root_node->GetLastUnignoredChildCrossingTreeBoundary()->id());

  EXPECT_EQ(static_text_0_0_ignored.id,
            root_node->GetDeepestFirstDescendant()->id());
  EXPECT_EQ(paragraph_0.id,
            root_node->GetDeepestFirstUnignoredDescendant()->id());

  EXPECT_EQ(button_3_1.id, root_node->GetDeepestLastDescendant()->id());
  EXPECT_EQ(button_3_1.id,
            root_node->GetDeepestLastUnignoredDescendant()->id());

  {
    std::vector<AXNode*> siblings;
    for (AXNode* sibling = tree.GetFromId(paragraph_0.id); sibling;
         sibling = sibling->GetNextSibling()) {
      siblings.push_back(sibling);
    }
    EXPECT_THAT(siblings, ElementsAre(HasAXNodeID(paragraph_0),
                                      HasAXNodeID(paragraph_1_ignored),
                                      HasAXNodeID(paragraph_2),
                                      HasAXNodeID(paragraph_3_ignored)));
  }

  {
    std::vector<AXNode*> siblings;
    for (AXNode* sibling = tree.GetFromId(paragraph_0.id); sibling;
         sibling = sibling->GetNextUnignoredSibling()) {
      siblings.push_back(sibling);
    }
    EXPECT_THAT(
        siblings,
        ElementsAre(HasAXNodeID(paragraph_0), HasAXNodeID(static_text_1_0),
                    HasAXNodeID(paragraph_2), HasAXNodeID(static_text_3_0_0),
                    HasAXNodeID(button_3_1)));
  }

  {
    std::vector<AXNode*> siblings;
    for (AXNode* sibling = tree.GetFromId(paragraph_3_ignored.id);
         sibling; sibling = sibling->GetPreviousSibling()) {
      siblings.push_back(sibling);
    }
    EXPECT_THAT(siblings, ElementsAre(HasAXNodeID(paragraph_3_ignored),
                                      HasAXNodeID(paragraph_2),
                                      HasAXNodeID(paragraph_1_ignored),
                                      HasAXNodeID(paragraph_0)));
  }

  {
    std::vector<AXNode*> siblings;
    for (AXNode* sibling = tree.GetFromId(button_3_1.id); sibling;
         sibling = sibling->GetPreviousUnignoredSibling()) {
      siblings.push_back(sibling);
    }
    EXPECT_THAT(
        siblings,
        ElementsAre(HasAXNodeID(button_3_1), HasAXNodeID(static_text_3_0_0),
                    HasAXNodeID(paragraph_2), HasAXNodeID(static_text_1_0),
                    HasAXNodeID(paragraph_0)));
  }

  {
    std::vector<AXNode*> siblings;
    for (AXNode* child : root_node->GetAllChildren()) {
      siblings.push_back(child);
    }
    EXPECT_THAT(siblings, ElementsAre(HasAXNodeID(paragraph_0),
                                      HasAXNodeID(paragraph_1_ignored),
                                      HasAXNodeID(paragraph_2),
                                      HasAXNodeID(paragraph_3_ignored)));
  }

  {
    std::vector< AXNode::AllChildCrossingTreeBoundaryIterator> siblings;
    for (auto iter = root_node->AllChildrenCrossingTreeBoundaryBegin();
         iter != root_node->AllChildrenCrossingTreeBoundaryEnd(); ++iter) {
      siblings.push_back(iter);
    }
    EXPECT_THAT(siblings, ElementsAre(HasAXNodeID(paragraph_0),
                                      HasAXNodeID(paragraph_1_ignored),
                                      HasAXNodeID(paragraph_2),
                                      HasAXNodeID(paragraph_3_ignored)));
  }

  {
    std::vector<AXNode::UnignoredChildIterator> siblings;
    for (auto iter = root_node->UnignoredChildrenBegin();
         iter != root_node->UnignoredChildrenEnd(); ++iter) {
      siblings.push_back(iter);
    }
    EXPECT_THAT(
        siblings,
        ElementsAre(HasAXNodeID(paragraph_0), HasAXNodeID(static_text_1_0),
                    HasAXNodeID(paragraph_2), HasAXNodeID(static_text_3_0_0),
                    HasAXNodeID(button_3_1)));
  }

  {
    std::vector<AXNode::UnignoredChildCrossingTreeBoundaryIterator>
        siblings;
    for (auto iter = root_node->UnignoredChildrenCrossingTreeBoundaryBegin();
         iter != root_node->UnignoredChildrenCrossingTreeBoundaryEnd();
         ++iter) {
      siblings.push_back(iter);
    }
    EXPECT_THAT(
        siblings,
        ElementsAre(HasAXNodeID(paragraph_0), HasAXNodeID(static_text_1_0),
                    HasAXNodeID(paragraph_2), HasAXNodeID(static_text_3_0_0),
                    HasAXNodeID(button_3_1)));
  }
}

TEST(AXNodeTest, TreeWalkingCrossingTreeBoundary) {
  AXTreeData tree_data_1;
  tree_data_1.tree_id = AXTreeID::CreateNewAXTreeID();
  tree_data_1.title = "Application";

  AXTreeData tree_data_2;
  tree_data_2.tree_id = AXTreeID::CreateNewAXTreeID();
  tree_data_2.parent_tree_id = tree_data_1.tree_id;
  tree_data_2.title = "Iframe";

  AXNodeData root_1;
  AXNodeData root_2;
  root_1.id = 1;
  root_2.id = 1;
  root_1.role = ax::mojom::Role::kRootWebArea;
  root_1.AddChildTreeId(tree_data_2.tree_id);
  root_2.role = ax::mojom::Role::kRootWebArea;

  AXTreeUpdate initial_state_1;
  initial_state_1.root_id = root_1.id;
  initial_state_1.nodes = {root_1};
  initial_state_1.has_tree_data = true;
  initial_state_1.tree_data = tree_data_1;

  AXTreeUpdate initial_state_2;
  initial_state_2.root_id = root_2.id;
  initial_state_2.nodes = {root_2};
  initial_state_2.has_tree_data = true;
  initial_state_2.tree_data = tree_data_2;

  auto tree_1 = std::make_unique<AXTree>(initial_state_1);
  TestSingleAXTreeManager tree_manager_1(std::move(tree_1));
  auto tree_2 = std::make_unique<AXTree>(initial_state_2);
  TestSingleAXTreeManager tree_manager_2(std::move(tree_2));

  const AXNode* root_node_1 = tree_manager_1.GetRoot();
  ASSERT_EQ(root_1.id, root_node_1->id());

  const AXNode* root_node_2 = tree_manager_2.GetRoot();
  ASSERT_EQ(root_2.id, root_node_2->id());

  EXPECT_EQ(0u, root_node_1->GetChildCount());
  EXPECT_EQ(1u, root_node_1->GetChildCountCrossingTreeBoundary());
  EXPECT_EQ(0u, root_node_1->GetUnignoredChildCount());
  EXPECT_EQ(1u, root_node_1->GetUnignoredChildCountCrossingTreeBoundary());

  EXPECT_EQ(nullptr, root_node_1->GetChildAtIndex(0));
  EXPECT_EQ(root_node_2, root_node_1->GetChildAtIndexCrossingTreeBoundary(0));
  EXPECT_EQ(nullptr, root_node_1->GetUnignoredChildAtIndex(0));
  EXPECT_EQ(root_node_2,
            root_node_1->GetUnignoredChildAtIndexCrossingTreeBoundary(0));

  EXPECT_EQ(nullptr, root_node_2->GetParent());
  EXPECT_EQ(root_node_1, root_node_2->GetParentCrossingTreeBoundary());
  EXPECT_EQ(nullptr, root_node_2->GetUnignoredParent());
  EXPECT_EQ(root_node_1, root_node_2->GetUnignoredParentCrossingTreeBoundary());
}

TEST(AXNodeTest, GetValueForControlTextField) {
  ScopedAXEmbeddedObjectBehaviorSetter ax_embedded_object_behavior(
      AXEmbeddedObjectBehavior::kSuppressCharacter);

  // kRootWebArea
  // ++kTextField (contenteditable)
  // ++++kGenericContainer
  // ++++++kStaticText "Line 1"
  // ++++++kImage
  // ++++++kLineBreak '\n'
  // ++++++kStaticText "Line 2"

  AXNodeData root;
  root.id = 1;
  AXNodeData rich_text_field;
  rich_text_field.id = 2;
  AXNodeData rich_text_field_text_container;
  rich_text_field_text_container.id = 3;
  AXNodeData rich_text_field_line_1;
  rich_text_field_line_1.id = 4;
  AXNodeData rich_text_field_image;
  rich_text_field_image.id = 5;
  AXNodeData rich_text_field_line_break;
  rich_text_field_line_break.id = 6;
  AXNodeData rich_text_field_line_2;
  rich_text_field_line_2.id = 7;

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

  rich_text_field.role = ax::mojom::Role::kTextField;
  rich_text_field.AddState(ax::mojom::State::kEditable);
  rich_text_field.AddState(ax::mojom::State::kRichlyEditable);
  rich_text_field.AddBoolAttribute(
      ax::mojom::BoolAttribute::kNonAtomicTextFieldRoot, true);
  rich_text_field.SetName("Rich text field");
  rich_text_field.child_ids = {rich_text_field_text_container.id};

  rich_text_field_text_container.role = ax::mojom::Role::kGenericContainer;
  rich_text_field_text_container.AddState(ax::mojom::State::kIgnored);
  rich_text_field_text_container.AddState(ax::mojom::State::kEditable);
  rich_text_field_text_container.AddState(ax::mojom::State::kRichlyEditable);
  rich_text_field_text_container.child_ids = {
      rich_text_field_line_1.id, rich_text_field_image.id,
      rich_text_field_line_break.id, rich_text_field_line_2.id};

  rich_text_field_line_1.role = ax::mojom::Role::kStaticText;
  rich_text_field_line_1.AddState(ax::mojom::State::kEditable);
  rich_text_field_line_1.AddState(ax::mojom::State::kRichlyEditable);
  rich_text_field_line_1.SetName("Line 1");

  rich_text_field_image.role = ax::mojom::Role::kImage;
  rich_text_field_image.AddState(ax::mojom::State::kEditable);
  rich_text_field_image.AddState(ax::mojom::State::kRichlyEditable);
  rich_text_field_image.SetName(AXNode::kEmbeddedObjectCharacterUTF8);

  rich_text_field_line_break.role = ax::mojom::Role::kLineBreak;
  rich_text_field_line_break.AddState(ax::mojom::State::kEditable);
  rich_text_field_line_break.AddState(ax::mojom::State::kRichlyEditable);
  rich_text_field_line_break.SetName("\n");

  rich_text_field_line_2.role = ax::mojom::Role::kStaticText;
  rich_text_field_line_2.AddState(ax::mojom::State::kEditable);
  rich_text_field_line_2.AddState(ax::mojom::State::kRichlyEditable);
  rich_text_field_line_2.SetName("Line 2");

  AXTreeUpdate update;
  update.has_tree_data = true;
  update.tree_data.tree_id = AXTreeID::CreateNewAXTreeID();
  update.root_id = root.id;
  update.nodes = {root,
                  rich_text_field,
                  rich_text_field_text_container,
                  rich_text_field_line_1,
                  rich_text_field_image,
                  rich_text_field_line_break,
                  rich_text_field_line_2};

  auto tree = std::make_unique<AXTree>(update);
  TestSingleAXTreeManager manager(std::move(tree));

  {
    const AXNode* text_field_node =
        manager.GetTree()->GetFromId(rich_text_field.id);
    ASSERT_NE(nullptr, text_field_node);
    // In the accessibility tree's text representation, there is an implicit
    // line break before every embedded object, such as an image.
    EXPECT_EQ("Line 1\n\nLine 2", text_field_node->GetValueForControl());
  }

  // Only rich text fields should have their value attribute automatically
  // computed from their inner text. Atomic text fields, such as <input> or
  // <textarea> should not.
  rich_text_field.RemoveState(ax::mojom::State::kRichlyEditable);
  rich_text_field.RemoveBoolAttribute(
      ax::mojom::BoolAttribute::kNonAtomicTextFieldRoot);
  AXTreeUpdate update_2;
  update_2.nodes = {rich_text_field};

  ASSERT_TRUE(manager.GetTree()->Unserialize(update_2))
      << manager.GetTree()->error();
  {
    const AXNode* text_field_node =
        manager.GetTree()->GetFromId(rich_text_field.id);
    ASSERT_NE(nullptr, text_field_node);
    EXPECT_EQ("", text_field_node->GetValueForControl());
  }

  rich_text_field.AddState(ax::mojom::State::kRichlyEditable);
  rich_text_field.AddBoolAttribute(
      ax::mojom::BoolAttribute::kNonAtomicTextFieldRoot, true);

  // A node's data should override any computed node data.
  rich_text_field.SetValue("Line 1\nLine 2");
  AXTreeUpdate update_3;
  update_3.nodes = {rich_text_field};

  ASSERT_TRUE(manager.GetTree()->Unserialize(update_3))
      << manager.GetTree()->error();
  {
    const AXNode* text_field_node =
        manager.GetTree()->GetFromId(rich_text_field.id);
    ASSERT_NE(nullptr, text_field_node);
    EXPECT_EQ("Line 1\nLine 2", text_field_node->GetValueForControl());
  }
}

TEST(AXNodeTest, GetLowestPlatformAncestor) {
  // ++kRootWebArea
  // ++++kButton (IsLeaf=false)
  // ++++++kGenericContainer ignored
  // ++++++++kStaticText "Hello"
  // ++++++++++kInlineTextBox "Hello" (IsLeaf=true)
  // ++++kTextField "World" (IsLeaf=true)
  // ++++++kStaticText "World"
  // ++++++++kInlineTextBox "World" (IsLeaf=true)
  AXNodeData root;
  AXNodeData button;
  AXNodeData generic_container;
  AXNodeData static_text_1;
  AXNodeData inline_box_1;
  AXNodeData text_field;
  AXNodeData static_text_2;
  AXNodeData inline_box_2;

  root.id = 1;
  button.id = 2;
  generic_container.id = 3;
  static_text_1.id = 4;
  inline_box_1.id = 5;
  text_field.id = 6;
  static_text_2.id = 7;
  inline_box_2.id = 8;

  root.role = ax::mojom::Role::kRootWebArea;
  root.child_ids = {button.id, text_field.id};

  button.role = ax::mojom::Role::kButton;
  button.SetValue("Hello");
  button.child_ids = {generic_container.id};

  generic_container.role = ax::mojom::Role::kGenericContainer;
  generic_container.AddState(ax::mojom::State::kIgnored);
  generic_container.child_ids = {static_text_1.id};

  static_text_1.role = ax::mojom::Role::kStaticText;
  static_text_1.SetName("Hello");
  static_text_1.child_ids = {inline_box_1.id};

  inline_box_1.role = ax::mojom::Role::kInlineTextBox;
  inline_box_1.SetName("Hello");

  text_field.role = ax::mojom::Role::kTextField;
  text_field.AddState(ax::mojom::State::kEditable);
  text_field.AddStringAttribute(ax::mojom::StringAttribute::kHtmlTag, "input");
  text_field.SetValue("World");
  text_field.child_ids = {static_text_2.id};

  static_text_2.role = ax::mojom::Role::kStaticText;
  static_text_2.AddState(ax::mojom::State::kEditable);
  static_text_2.SetName("World");
  static_text_2.child_ids = {inline_box_2.id};

  inline_box_2.role = ax::mojom::Role::kInlineTextBox;
  inline_box_2.AddState(ax::mojom::State::kEditable);
  inline_box_2.SetName("World");

  AXTreeUpdate initial_state;
  initial_state.root_id = root.id;
  initial_state.nodes = {root,          button,       generic_container,
                         static_text_1, inline_box_1, text_field,
                         static_text_2, inline_box_2};
  initial_state.has_tree_data = true;

  AXTreeData tree_data;
  tree_data.tree_id = AXTreeID::CreateNewAXTreeID();
  tree_data.title = "Application";
  initial_state.tree_data = tree_data;

  AXTree tree;
  ASSERT_TRUE(tree.Unserialize(initial_state)) << tree.error();

  const AXNode* root_node = tree.root();
  ASSERT_EQ(root.id, root_node->id());
  EXPECT_EQ(root_node, root_node->GetLowestPlatformAncestor());

  const AXNode* button_node = root_node->children()[0];
  ASSERT_EQ(button.id, button_node->id());
  EXPECT_EQ(button_node, button_node->GetLowestPlatformAncestor());

  const AXNode* generic_container_node = button_node->children()[0];
  ASSERT_EQ(generic_container.id, generic_container_node->id());
  EXPECT_EQ(button_node, generic_container_node->GetLowestPlatformAncestor());

  const AXNode* static_text_1_node = generic_container_node->children()[0];
  ASSERT_EQ(static_text_1.id, static_text_1_node->id());
  EXPECT_EQ(static_text_1_node,
            static_text_1_node->GetLowestPlatformAncestor());

  const AXNode* inline_box_1_node = static_text_1_node->children()[0];
  ASSERT_EQ(inline_box_1.id, inline_box_1_node->id());
  EXPECT_EQ(static_text_1_node, inline_box_1_node->GetLowestPlatformAncestor());

  const AXNode* text_field_node = root_node->children()[1];
  ASSERT_EQ(text_field.id, text_field_node->id());
  EXPECT_EQ(text_field_node, text_field_node->GetLowestPlatformAncestor());

  const AXNode* static_text_2_node = text_field_node->children()[0];
  ASSERT_EQ(static_text_2.id, static_text_2_node->id());
  EXPECT_EQ(text_field_node, static_text_2_node->GetLowestPlatformAncestor());

  const AXNode* inline_box_2_node = static_text_2_node->children()[0];
  ASSERT_EQ(inline_box_2.id, inline_box_2_node->id());
  EXPECT_EQ(text_field_node, inline_box_2_node->GetLowestPlatformAncestor());
}

TEST(AXNodeTest, GetTextContentRangeBounds) {
  constexpr char16_t kEnglishText[] = u"Hey";
  const std::vector<int32_t> kEnglishCharacterOffsets = {12, 19, 27};
  // A Hindi word (which means "Hindi") consisting of two letters.
  constexpr char16_t kHindiText[] = u"\x0939\x093F\x0928\x094D\x0926\x0940";
  const std::vector<int32_t> kHindiCharacterOffsets = {40, 40, 59, 59, 59, 59};
  // A Thai word (which means "feel") consisting of 3 letters.
  constexpr char16_t kThaiText[] = u"\x0E23\x0E39\x0E49\x0E2A\x0E36\x0E01";
  const std::vector<int32_t> kThaiCharacterOffsets = {66, 66, 66, 76, 76, 85};

  AXNodeData root_data;
  root_data.id = 1;
  root_data.role = ax::mojom::Role::kRootWebArea;

  AXNodeData text_data1;
  text_data1.id = 2;
  text_data1.role = ax::mojom::Role::kStaticText;
  text_data1.SetName(kEnglishText);
  text_data1.AddIntAttribute(
      ax::mojom::IntAttribute::kTextDirection,
      static_cast<int32_t>(ax::mojom::WritingDirection::kLtr));
  text_data1.AddIntListAttribute(ax::mojom::IntListAttribute::kCharacterOffsets,
                                 kEnglishCharacterOffsets);

  AXNodeData text_data2;
  text_data2.id = 3;
  text_data2.role = ax::mojom::Role::kStaticText;
  text_data2.SetName(kHindiText);
  text_data2.AddIntAttribute(
      ax::mojom::IntAttribute::kTextDirection,
      static_cast<int32_t>(ax::mojom::WritingDirection::kRtl));
  text_data2.AddIntListAttribute(ax::mojom::IntListAttribute::kCharacterOffsets,
                                 kHindiCharacterOffsets);

  AXNodeData text_data3;
  text_data3.id = 4;
  text_data3.role = ax::mojom::Role::kStaticText;
  text_data3.SetName(kThaiText);
  text_data3.AddIntAttribute(
      ax::mojom::IntAttribute::kTextDirection,
      static_cast<int32_t>(ax::mojom::WritingDirection::kTtb));
  text_data3.AddIntListAttribute(ax::mojom::IntListAttribute::kCharacterOffsets,
                                 kThaiCharacterOffsets);

  root_data.child_ids = {text_data1.id, text_data2.id, text_data3.id};

  AXTreeUpdate update;
  update.root_id = root_data.id;
  update.nodes = {root_data, text_data1, text_data2, text_data3};
  update.has_tree_data = true;

  AXTreeData tree_data;
  tree_data.tree_id = AXTreeID::CreateNewAXTreeID();
  tree_data.title = "Application";
  update.tree_data = tree_data;

  AXTree tree;
  ASSERT_TRUE(tree.Unserialize(update)) << tree.error();

  const AXNode* root_node = tree.root();
  ASSERT_EQ(root_data.id, root_node->id());

  const AXNode* text1_node = root_node->GetUnignoredChildAtIndex(0);
  ASSERT_EQ(text_data1.id, text1_node->id());
  const AXNode* text2_node = root_node->GetUnignoredChildAtIndex(1);
  ASSERT_EQ(text_data2.id, text2_node->id());
  const AXNode* text3_node = root_node->GetUnignoredChildAtIndex(2);
  ASSERT_EQ(text_data3.id, text3_node->id());

  // Offsets correspond to code units in UTF-16
  // Each character is a single glyph in `kEnglishText`.
  EXPECT_EQ(gfx::RectF(0, 0, 27, 0),
            text1_node->GetTextContentRangeBoundsUTF16(0, 3));
  EXPECT_EQ(gfx::RectF(12, 0, 7, 0),
            text1_node->GetTextContentRangeBoundsUTF16(1, 2));
  EXPECT_EQ(gfx::RectF(), text1_node->GetTextContentRangeBoundsUTF16(2, 4));

  // `kHindiText` is 6 code units in UTF-16.
  EXPECT_EQ(gfx::RectF(0, 0, 59, 0),
            text2_node->GetTextContentRangeBoundsUTF16(0, 6));
  EXPECT_EQ(gfx::RectF(0, 0, 19, 0),
            text2_node->GetTextContentRangeBoundsUTF16(2, 4));

  // `kThaiText` is 6 code units in UTF-16.
  EXPECT_EQ(gfx::RectF(0, 0, 0, 85),
            text3_node->GetTextContentRangeBoundsUTF16(0, 6));
  EXPECT_EQ(gfx::RectF(0, 66, 0, 10),
            text3_node->GetTextContentRangeBoundsUTF16(2, 4));
}

TEST(AXNodeTest, IsGridCellReadOnlyOrDisabled) {
  // ++kRootWebArea
  // ++++kGrid
  // ++++kRow
  // ++++++kGridCell
  // ++++++kGridCell
  AXNodeData root;
  AXNodeData grid;
  AXNodeData row;
  AXNodeData gridcell_1;
  AXNodeData gridcell_2;
  AXNodeData gridcell_3;

  root.id = 1;
  grid.id = 2;
  row.id = 3;
  gridcell_1.id = 4;
  gridcell_2.id = 5;
  gridcell_3.id = 6;

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

  grid.role = ax::mojom::Role::kGrid;
  grid.child_ids = {row.id};

  row.role = ax::mojom::Role::kRow;
  row.child_ids = {gridcell_1.id, gridcell_2.id, gridcell_3.id};

  gridcell_1.role = ax::mojom::Role::kCell;
  gridcell_1.AddIntAttribute(
      ax::mojom::IntAttribute::kRestriction,
      static_cast<int32_t>(ax::mojom::Restriction::kNone));

  gridcell_2.role = ax::mojom::Role::kCell;
  gridcell_2.AddIntAttribute(
      ax::mojom::IntAttribute::kRestriction,
      static_cast<int32_t>(ax::mojom::Restriction::kReadOnly));

  gridcell_3.role = ax::mojom::Role::kCell;
  gridcell_3.AddIntAttribute(
      ax::mojom::IntAttribute::kRestriction,
      static_cast<int32_t>(ax::mojom::Restriction::kDisabled));

  AXTreeUpdate initial_state;
  initial_state.root_id = root.id;
  initial_state.nodes = {root, grid, row, gridcell_1, gridcell_2, gridcell_3};
  initial_state.has_tree_data = true;

  AXTreeData tree_data;
  tree_data.tree_id = AXTreeID::CreateNewAXTreeID();
  tree_data.title = "Application";
  initial_state.tree_data = tree_data;

  AXTree tree;
  ASSERT_TRUE(tree.Unserialize(initial_state)) << tree.error();

  const AXNode* root_node = tree.root();
  ASSERT_EQ(root.id, root_node->id());

  const AXNode* grid_node = root_node->children()[0];
  ASSERT_EQ(grid.id, grid_node->id());
  EXPECT_FALSE(grid_node->IsReadOnlyOrDisabled());

  const AXNode* row_node = grid_node->children()[0];
  ASSERT_EQ(row.id, row_node->id());
  EXPECT_TRUE(row_node->IsReadOnlyOrDisabled());

  const AXNode* gridcell_1_node = row_node->children()[0];
  ASSERT_EQ(gridcell_1.id, gridcell_1_node->id());
  EXPECT_FALSE(gridcell_1_node->IsReadOnlyOrDisabled());

  const AXNode* gridcell_2_node = row_node->children()[1];
  ASSERT_EQ(gridcell_2.id, gridcell_2_node->id());
  EXPECT_TRUE(gridcell_2_node->IsReadOnlyOrDisabled());

  const AXNode* gridcell_3_node = row_node->children()[2];
  ASSERT_EQ(gridcell_3.id, gridcell_3_node->id());
  EXPECT_TRUE(gridcell_3_node->IsReadOnlyOrDisabled());
}

TEST(AXNodeTest, GetLowestCommonAncestor) {
  // ++kRootWebArea
  // ++++kParagraph
  // ++++++kStaticText
  // ++++kParagraph
  // ++++++kLink
  // ++++++++kStaticText
  // ++++++kButton

  // Numbers at the end of variable names indicate their position under the
  // root.
  AXNodeData root;
  AXNodeData paragraph_0;
  AXNodeData static_text_0_0;
  AXNodeData paragraph_1;
  AXNodeData link_1_0;
  AXNodeData static_text_1_0_0;
  AXNodeData button_1_1;

  root.id = 1;
  paragraph_0.id = 2;
  static_text_0_0.id = 3;
  paragraph_1.id = 4;
  link_1_0.id = 5;
  static_text_1_0_0.id = 6;
  button_1_1.id = 7;

  root.role = ax::mojom::Role::kRootWebArea;
  root.child_ids = {paragraph_0.id, paragraph_1.id};

  paragraph_0.role = ax::mojom::Role::kParagraph;
  paragraph_0.child_ids = {static_text_0_0.id};

  static_text_0_0.role = ax::mojom::Role::kStaticText;
  static_text_0_0.SetName("static_text_0_0");

  paragraph_1.role = ax::mojom::Role::kParagraph;
  paragraph_1.child_ids = {link_1_0.id, button_1_1.id};

  link_1_0.role = ax::mojom::Role::kLink;
  link_1_0.AddState(ax::mojom::State::kLinked);
  link_1_0.child_ids = {static_text_1_0_0.id};

  static_text_1_0_0.role = ax::mojom::Role::kStaticText;
  static_text_1_0_0.SetName("static_text_1_0_0");

  button_1_1.role = ax::mojom::Role::kButton;
  button_1_1.SetName("button_1_1");

  AXTreeUpdate initial_state;
  initial_state.root_id = root.id;
  initial_state.nodes = {root,        paragraph_0, static_text_0_0,
                         paragraph_1, link_1_0,    static_text_1_0_0,
                         button_1_1};
  initial_state.has_tree_data = true;

  AXTreeData tree_data;
  tree_data.tree_id = AXTreeID::CreateNewAXTreeID();
  tree_data.title = "Application";
  initial_state.tree_data = tree_data;

  AXTree tree;
  ASSERT_TRUE(tree.Unserialize(initial_state)) << tree.error();

  AXNode* root_node = tree.GetFromId(root.id);
  AXNode* paragraph_0_node = tree.GetFromId(paragraph_0.id);
  AXNode* static_text_0_0_node = tree.GetFromId(static_text_0_0.id);
  AXNode* paragraph_1_node = tree.GetFromId(paragraph_1.id);
  AXNode* link_1_0_node = tree.GetFromId(link_1_0.id);
  AXNode* static_text_1_0_0_node = tree.GetFromId(static_text_1_0_0.id);
  AXNode* button_1_1_node = tree.GetFromId(button_1_1.id);

  // The lowest common ancestor of a node and itself is itself.
  ASSERT_EQ(root_node, root_node->GetLowestCommonAncestor(*root_node));
  ASSERT_EQ(paragraph_0_node,
            paragraph_0_node->GetLowestCommonAncestor(*paragraph_0_node));

  // Lowest common ancestor is reflexive.
  ASSERT_EQ(paragraph_1_node,
            link_1_0_node->GetLowestCommonAncestor(*button_1_1_node));
  ASSERT_EQ(paragraph_1_node,
            button_1_1_node->GetLowestCommonAncestor(*link_1_0_node));

  // Finds the lowest common ancestor for two nodes not on the same level.
  ASSERT_EQ(root_node, static_text_1_0_0_node->GetLowestCommonAncestor(
                           *static_text_0_0_node));
  ASSERT_EQ(link_1_0_node,
            static_text_1_0_0_node->GetLowestCommonAncestor(*link_1_0_node));
}

TEST(AXNodeTest, DescendantOfNonAtomicTextField) {
  // The test covers the different scenarios for descendants of a non-atomic
  // text field:
  // <div contenteditable role=spinbutton>
  //  <div role=spinbutton></div>
  //  <input type=text role=spinbutton>
  //  <div></div>
  // </div>
  // ++1 kRootWebArea
  // ++++2 kSpinButton
  // ++++++3 kSpinButton
  // ++++++4 kSpinButton
  // ++++++5 kGenericContainer

  AXNodeData root_1;
  AXNodeData spin_button_2;
  AXNodeData spin_button_3;
  AXNodeData spin_button_4;
  AXNodeData generic_container_5;

  root_1.id = 1;
  spin_button_2.id = 2;
  spin_button_3.id = 3;
  spin_button_4.id = 4;
  generic_container_5.id = 5;

  root_1.role = ax::mojom::Role::kRootWebArea;
  root_1.child_ids = {spin_button_2.id};

  spin_button_2.role = ax::mojom::Role::kSpinButton;
  spin_button_2.AddState(ax::mojom::State::kRichlyEditable);
  spin_button_2.AddState(ax::mojom::State::kEditable);
  spin_button_2.AddBoolAttribute(
      ax::mojom::BoolAttribute::kNonAtomicTextFieldRoot, true);
  spin_button_2.child_ids = {spin_button_3.id, spin_button_4.id,
                             generic_container_5.id};

  spin_button_3.role = ax::mojom::Role::kSpinButton;

  spin_button_4.role = ax::mojom::Role::kSpinButton;
  spin_button_4.AddState(ax::mojom::State::kEditable);

  generic_container_5.role = ax::mojom::Role::kGenericContainer;

  AXTreeUpdate initial_state;
  initial_state.root_id = root_1.id;
  initial_state.nodes = {root_1, spin_button_2, spin_button_3, spin_button_4,
                         generic_container_5};
  initial_state.has_tree_data = true;
  initial_state.tree_data.tree_id = AXTreeID::CreateNewAXTreeID();

  AXTree tree(initial_state);

  EXPECT_TRUE(tree.GetFromId(spin_button_2.id)->data().IsSpinnerTextField());
  EXPECT_TRUE(tree.GetFromId(spin_button_2.id)->data().IsTextField());
  EXPECT_FALSE(
      tree.GetFromId(spin_button_3.id)->data().IsSpinnerTextField());
  EXPECT_FALSE(tree.GetFromId(spin_button_3.id)->data().IsTextField());
  EXPECT_TRUE(tree.GetFromId(spin_button_4.id)->data().IsSpinnerTextField());
  EXPECT_FALSE(tree.GetFromId(generic_container_5.id)->data().IsSpinnerTextField());
}

TEST(AXNodeTest, MenuItemCheckboxPosInSet) {
  TestAXTreeUpdate update(std::string(R"HTML(
    ++1 kRootWebArea
    ++++2 kGroup
    ++++++3 kMenuItemCheckBox
    ++++++++4 kStaticText name="item"
    ++++++++++5 kInlineTextBox name="item"
    ++++++6 kMenuItemCheckBox
    ++++++++7 kStaticText name="item2"
    ++++++++++8 kInlineTextBox name="item2"
  )HTML"));

  AXTree tree(update);

  EXPECT_EQ(tree.GetFromId(3)->GetPosInSet(), 1);
  EXPECT_EQ(tree.GetFromId(3)->GetSetSize(), 2);
  EXPECT_EQ(tree.GetFromId(6)->GetPosInSet(), 2);
  EXPECT_EQ(tree.GetFromId(6)->GetSetSize(), 2);
}

TEST(AXNodeTest, TreeItemAsTreeItemParentPosInSetSetSize) {
  TestAXTreeUpdate update(std::string(R"HTML(
    ++1 kRootWebArea
    ++++2 kTree
    ++++++3 kTreeItem intAttribute=kPosInSet,1 intAttribute=kSetSize,2
    ++++++++4 kTreeItem intAttribute=kPosInSet,1 intAttribute=kSetSize,6
    ++++++++5 kTreeItem intAttribute=kPosInSet,2 intAttribute=kSetSize,6
    ++++++6 kTreeItem intAttribute=kPosInSet,2 intAttribute=kSetSize,2
    ++++++++7 kTreeItem intAttribute=kPosInSet,3 intAttribute=kSetSize,6
  )HTML"));

  AXTree tree(update);

  EXPECT_EQ(tree.GetFromId(3)->GetPosInSet(), 1);
  EXPECT_EQ(tree.GetFromId(3)->GetSetSize(), 2);

  EXPECT_EQ(tree.GetFromId(4)->GetPosInSet(), 1);
  EXPECT_EQ(tree.GetFromId(4)->GetSetSize(), 6);

  EXPECT_EQ(tree.GetFromId(5)->GetPosInSet(), 2);
  EXPECT_EQ(tree.GetFromId(5)->GetSetSize(), 6);

  EXPECT_EQ(tree.GetFromId(6)->GetPosInSet(), 2);
  EXPECT_EQ(tree.GetFromId(6)->GetSetSize(), 2);

  EXPECT_EQ(tree.GetFromId(7)->GetPosInSet(), 3);
  EXPECT_EQ(tree.GetFromId(7)->GetSetSize(), 6);
}

TEST(AXNodeTest, GroupAsTreeItemParentPosInSetSetSize) {
  TestAXTreeUpdate update(std::string(R"HTML(
    ++1 kRootWebArea
    ++++2 kTree
    ++++++3 kGroup
    ++++++++4 kTreeItem intAttribute=kPosInSet,1 intAttribute=kSetSize,6
    ++++++++5 kTreeItem intAttribute=kPosInSet,2 intAttribute=kSetSize,6
    ++++++6 kTreeItem
    ++++++++7 kGroup
    ++++++++++8 kTreeItem intAttribute=kPosInSet,1 intAttribute=kSetSize,6
  )HTML"));

  AXTree tree(update);

  EXPECT_EQ(tree.GetFromId(4)->GetPosInSet(), 1);
  EXPECT_EQ(tree.GetFromId(4)->GetSetSize(), 6);

  EXPECT_EQ(tree.GetFromId(5)->GetPosInSet(), 2);
  EXPECT_EQ(tree.GetFromId(5)->GetSetSize(), 6);

  EXPECT_EQ(tree.GetFromId(8)->GetPosInSet(), 1);
  EXPECT_EQ(tree.GetFromId(8)->GetSetSize(), 6);
}

TEST(AXNodeTest, GridCellsFocusableViaARIAActiveDescendant) {
  TestAXTreeUpdate update(std::string(R"HTML(
    ++1 kRootWebArea
    ++++2 kGrid stringAttribute=kHtmlTag,"table" intAttribute=kActivedescendantId,4
    ++++++3 kRow stringAttribute=kHtmlTag,"tr"
    ++++++++4 kColumnHeader stringAttribute=kHtmlId,"row1-cell1" stringAttribute=kHtmlTag,"th"
    ++++++5 kRow stringAttribute=kHtmlTag,"tr"
    ++++++++6 kGridCell stringAttribute=kHtmlId,"row2-cell1" stringAttribute=kHtmlTag,"td"
    ++++7 kGrid stringAttribute=kHtmlTag,"table"
    ++++++8 kRow stringAttribute=kHtmlTag,"tr"
    ++++++++9 kColumnHeader stringAttribute=kHtmlId,"row1-cell1" stringAttribute=kHtmlTag,"th"
    ++++++10 kRow stringAttribute=kHtmlTag,"tr"
    ++++++++11 kGridCell stringAttribute=kHtmlId,"row2-cell1" stringAttribute=kHtmlTag,"td"
  )HTML"));

  AXTree tree(update);

  // Grid with aria-activedescendant should have focusable cells because they
  // have HTML ids. Rows shouldn't. None of the cells in the grid without
  // aria-activedescendant should be focusable.
  for (int id : {4, 6}) {
    const AXNode* n = tree.GetFromId(id);
    ASSERT_NE(n, nullptr) << "Node " << id << " missing";
    EXPECT_TRUE(n->IsFocusable()) << "cell with " << id << " not focusable";
  }

  for (int id : {2, 3, 5, 7, 8, 9, 10, 11}) {
    const AXNode* n = tree.GetFromId(id);
    ASSERT_NE(n, nullptr) << "Node " << id << " missing";
    EXPECT_FALSE(n->IsFocusable()) << "Node " << id << " is focusable";
  }
}

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN)
TEST(AXNodeTest, ExtraAnnouncementNodesNotCreated) {
  AXNodeData root;
  root.id = 1;
  root.role = ax::mojom::Role::kRootWebArea;

  AXTreeUpdate initial_state;
  initial_state.root_id = root.id;
  initial_state.nodes = {root};
  initial_state.has_tree_data = true;

  AXTreeData tree_data;
  tree_data.tree_id = AXTreeID::CreateNewAXTreeID();
  tree_data.title = "Application";
  initial_state.tree_data = tree_data;

  AXTree tree;
  ASSERT_TRUE(tree.Unserialize(initial_state)) << tree.error();

  const AXNode* root_node = tree.root();
  ASSERT_EQ(root.id, root_node->id());

  // Extra announcement nodes should not be created unless a call to
  // GetExtraAnnouncementNode is made.
  ASSERT_EQ(nullptr, tree.extra_announcement_nodes());
}

TEST(AXNodeTest, GetExtraAnnouncementNodeByPriority) {
  AXNodeData root;
  root.id = 1;
  root.role = ax::mojom::Role::kRootWebArea;

  AXTreeUpdate initial_state;
  initial_state.root_id = root.id;
  initial_state.nodes = {root};
  initial_state.has_tree_data = true;

  AXTreeData tree_data;
  tree_data.tree_id = AXTreeID::CreateNewAXTreeID();
  tree_data.title = "Application";
  initial_state.tree_data = tree_data;

  AXTree tree;
  ASSERT_TRUE(tree.Unserialize(initial_state)) << tree.error();

  const AXNode* root_node = tree.root();
  ASSERT_EQ(root.id, root_node->id());

  const AXNode* assertive_node = root_node->GetExtraAnnouncementNode(
      ax::mojom::AriaNotificationPriority::kHigh);
  EXPECT_EQ(assertive_node->id(), -1);
  EXPECT_EQ(assertive_node->data().GetStringAttribute(
                ax::mojom::StringAttribute::kContainerLiveStatus),
            "assertive");

  const AXNode* polite_node = root_node->GetExtraAnnouncementNode(
      ax::mojom::AriaNotificationPriority::kNormal);
  EXPECT_EQ(polite_node->id(), -2);
  EXPECT_EQ(polite_node->data().GetStringAttribute(
                ax::mojom::StringAttribute::kContainerLiveStatus),
            "polite");
}
#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN)

TEST(AXNodeTest, GetParagraphContainerAncestor) {
  // Tree:
  // RootWebArea(1) [kIsLineBreaking]
  // ├── GenericContainer(2) [kIsLineBreaking]  // div
  // │   └── StaticText(3) "hello"
  // ├── LineBreak(4) [kIsLineBreaking]  // br
  // │   └── InlineTextBox(5) "\n" [kIsLineBreaking]
  // └── GenericContainer(6) [kIsLineBreaking]  // div
  //     └── StaticText(7) "world"

  AXNodeData root;
  root.id = 1;
  root.role = ax::mojom::Role::kRootWebArea;
  root.AddBoolAttribute(ax::mojom::BoolAttribute::kIsLineBreakingObject, true);
  root.child_ids = {2, 4, 6};

  AXNodeData div1;
  div1.id = 2;
  div1.role = ax::mojom::Role::kGenericContainer;
  div1.AddBoolAttribute(ax::mojom::BoolAttribute::kIsLineBreakingObject, true);
  div1.child_ids = {3};

  AXNodeData text_hello;
  text_hello.id = 3;
  text_hello.role = ax::mojom::Role::kStaticText;
  text_hello.SetName("hello");

  AXNodeData line_break;
  line_break.id = 4;
  line_break.role = ax::mojom::Role::kLineBreak;
  line_break.AddBoolAttribute(ax::mojom::BoolAttribute::kIsLineBreakingObject,
                              true);
  line_break.SetName("\n");
  line_break.child_ids = {5};

  AXNodeData inline_text_newline;
  inline_text_newline.id = 5;
  inline_text_newline.role = ax::mojom::Role::kInlineTextBox;
  inline_text_newline.AddBoolAttribute(
      ax::mojom::BoolAttribute::kIsLineBreakingObject, true);
  inline_text_newline.SetName("\n");

  AXNodeData div2;
  div2.id = 6;
  div2.role = ax::mojom::Role::kGenericContainer;
  div2.AddBoolAttribute(ax::mojom::BoolAttribute::kIsLineBreakingObject, true);
  div2.child_ids = {7};

  AXNodeData text_world;
  text_world.id = 7;
  text_world.role = ax::mojom::Role::kStaticText;
  text_world.SetName("world");

  AXTreeUpdate initial_state;
  initial_state.root_id = root.id;
  initial_state.nodes = {
      root, div1,      text_hello, line_break, inline_text_newline,
      div2, text_world};
  initial_state.has_tree_data = true;

  AXTreeData tree_data;
  tree_data.tree_id = AXTreeID::CreateNewAXTreeID();
  initial_state.tree_data = tree_data;

  AXTree tree;
  ASSERT_TRUE(tree.Unserialize(initial_state)) << tree.error();

  // StaticText(3) "hello" → GenericContainer(2)
  EXPECT_EQ(tree.GetFromId(3)->GetParagraphContainerAncestor(),
            tree.GetFromId(2));

  // LineBreak(4) → RootWebArea(1) (skips LineBreak itself)
  EXPECT_EQ(tree.GetFromId(4)->GetParagraphContainerAncestor(),
            tree.GetFromId(1));

  // InlineTextBox(5) child of LineBreak → RootWebArea(1)
  EXPECT_EQ(tree.GetFromId(5)->GetParagraphContainerAncestor(),
            tree.GetFromId(1));

  // StaticText(7) "world" → GenericContainer(6)
  EXPECT_EQ(tree.GetFromId(7)->GetParagraphContainerAncestor(),
            tree.GetFromId(6));

  // GenericContainer(2) → itself
  EXPECT_EQ(tree.GetFromId(2)->GetParagraphContainerAncestor(),
            tree.GetFromId(2));

  // RootWebArea(1) → itself
  EXPECT_EQ(tree.GetFromId(1)->GetParagraphContainerAncestor(),
            tree.GetFromId(1));
}

}  // namespace ui
