// Copyright 2012 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/renderer/accessibility/render_accessibility_impl.h"

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/containers/adapters.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "content/public/common/buildflags.h"
#include "content/public/renderer/plugin_ax_tree_action_target_adapter.h"
#include "content/renderer/accessibility/ax_action_target_factory.h"
#include "content/renderer/accessibility/render_accessibility_impl_test.h"
#include "content/renderer/render_frame_impl.h"
#include "services/metrics/public/cpp/mojo_ukm_recorder.h"
#include "services/metrics/public/mojom/ukm_interface.mojom.h"
#include "third_party/blink/public/web/web_testing_support.h"
#include "third_party/blink/public/web/web_view.h"
#include "ui/accessibility/ax_action_target.h"
#include "ui/accessibility/ax_location_and_scroll_updates.h"
#include "ui/accessibility/ax_tree.h"
#include "ui/accessibility/null_ax_action_target.h"
#include "ui/native_theme/features/native_theme_features.h"

namespace content {

using blink::WebAXObject;
using blink::WebDocument;

TEST_F(RenderAccessibilityImplTest, SendFullAccessibilityTreeOnReload) {
  // The job of RenderAccessibilityImpl is to serialize the
  // accessibility tree built by WebKit and send it to the browser.
  // When the accessibility tree changes, it tries to send only
  // the nodes that actually changed or were reparented. This test
  // ensures that the messages sent are correct in cases when a page
  // reloads, and that internal state is properly garbage-collected.
  constexpr char html[] = R"HTML(
      <body>
        <div role="group" id="A">
          <div role="group" id="A1"></div>
          <div role="group" id="A2"></div>
        </div>
      </body>
      )HTML";
  LoadHTMLAndRefreshAccessibilityTree(html);

  EXPECT_EQ(6, CountAccessibilityNodesSentToBrowser());

  // If we post another event but the tree doesn't change,
  // we should only send 1 node to the browser.
  ClearHandledUpdates();
  WebDocument document = GetMainFrame()->GetDocument();
  WebAXObject root_obj = WebAXObject::FromWebDocument(document);
  GetRenderAccessibilityImpl()->MarkWebAXObjectDirty(root_obj);
  SendPendingAccessibilityEvents();
  EXPECT_EQ(1, CountAccessibilityNodesSentToBrowser());
  {
    // Make sure it's the root object that was updated.
    ui::AXTreeUpdate update = GetLastAccUpdate();
    EXPECT_EQ(root_obj.AxID(), update.nodes[0].id);
  }

  // If we reload the page and send a event, we should send
  // all 5 nodes to the browser. Also double-check that we didn't
  // leak any of the old BrowserTreeNodes.
  LoadHTML(html);
  document = GetMainFrame()->GetDocument();
  root_obj = WebAXObject::FromWebDocument(document);
  ClearHandledUpdates();
  SendPendingAccessibilityEvents();
  EXPECT_EQ(6, CountAccessibilityNodesSentToBrowser());

  // Even if the first event is sent on an element other than
  // the root, the whole tree should be updated because we know
  // the browser doesn't have the root element.
  // When the entire page is reloaded like this, all of the nodes are sent.
  LoadHTML(html);
  document = GetMainFrame()->GetDocument();
  root_obj = WebAXObject::FromWebDocument(document);
  SendPendingAccessibilityEvents();
  EXPECT_EQ(6, CountAccessibilityNodesSentToBrowser());
  ClearHandledUpdates();

  // Now fire a single event and ensure that only one update is sent.
  const WebAXObject& first_child = root_obj.ChildAt(0);
  GetRenderAccessibilityImpl()->HandleAXEvent(
      ui::AXEvent(first_child.AxID(), ax::mojom::Event::kFocus));
  SendPendingAccessibilityEvents();
  EXPECT_EQ(1, CountAccessibilityNodesSentToBrowser());
}

TEST_F(RenderAccessibilityImplTest, HideAccessibilityObject) {
  // Test RenderAccessibilityImpl and make sure it sends the
  // proper event to the browser when an object in the tree
  // is hidden, but its children are not.
  LoadHTMLAndRefreshAccessibilityTree(R"HTML(
      <body>
        <div role="group" id="A">
          <div role="group" id="B" lang="en-US">
            <div role="group" id="C" style="visibility: visible" lang="fr-CA">
            </div>
          </div>
        </div>
      </body>
      )HTML");

  EXPECT_EQ(6, CountAccessibilityNodesSentToBrowser());

  WebDocument document = GetMainFrame()->GetDocument();
  // Getting the root object will also force layout.
  WebAXObject root_obj = WebAXObject::FromWebDocument(document);
  WebAXObject html = root_obj.ChildAt(0);
  WebAXObject body = html.ChildAt(0);
  WebAXObject node_a = body.ChildAt(0);
  WebAXObject node_b = node_a.ChildAt(0);
  WebAXObject node_c = node_b.ChildAt(0);

  // Send a childrenChanged on "A".
  ClearHandledUpdates();
  GetRenderAccessibilityImpl()->MarkWebAXObjectDirty(node_a);

  // Hide node "B" ("C" stays visible).
  ExecuteJavaScriptForTests(
      "document.getElementById('B').style.visibility = 'hidden';");

  SendPendingAccessibilityEvents();
  ui::AXTreeUpdate update = GetLastAccUpdate();
  ASSERT_EQ(2U, update.nodes.size());

  // Since ignored nodes are included in the ax tree with State::kIgnored set,
  // "C" is NOT reparented, only the changed nodes are re-serialized.
  // "A" updates because it handled dirty object
  // "B" updates because its State::kIgnored has changed
  EXPECT_EQ(0, update.node_id_to_clear);
  EXPECT_EQ(node_a.AxID(), update.nodes[0].id);
  EXPECT_EQ(node_b.AxID(), update.nodes[1].id);
  EXPECT_EQ(2, CountAccessibilityNodesSentToBrowser());
}

TEST_F(RenderAccessibilityImplTest, ShowAccessibilityObject) {
  // Test RenderAccessibilityImpl and make sure it sends the
  // proper event to the browser when an object in the tree
  // is shown, causing its own already-visible children to be
  // reparented to it.
  LoadHTMLAndRefreshAccessibilityTree(R"HTML(
      <body>
        <div role="group" id="A" aria-describedby="B">
          <div role="group" id="B" style="visibility: hidden" lang="en-US">
            <div role="group" id="C" style="visibility: visible" lang="fr-CA">
            </div>
          </div>
        </div>
      </body>
      )HTML");

  EXPECT_EQ(6, CountAccessibilityNodesSentToBrowser());

  WebDocument document = GetMainFrame()->GetDocument();
  // Getting the root object also forces a layout.
  WebAXObject root_obj = WebAXObject::FromWebDocument(document);
  WebAXObject html = root_obj.ChildAt(0);
  WebAXObject body = html.ChildAt(0);
  WebAXObject node_a = body.ChildAt(0);
  WebAXObject node_b = node_a.ChildAt(0);
  WebAXObject node_c = node_b.ChildAt(0);

  // Send a childrenChanged on "A" and show node "B",
  GetRenderAccessibilityImpl()->MarkWebAXObjectDirty(node_a);
  ExecuteJavaScriptForTests(
      "document.getElementById('B').style.visibility = 'visible';");

  ClearHandledUpdates();

  SendPendingAccessibilityEvents();
  ui::AXTreeUpdate update = GetLastAccUpdate();

  // Since ignored nodes are included in the ax tree with State::kIgnored set,
  // "C" is NOT reparented, only the changed nodes are re-serialized.
  // "A" updates because it handled the dirty
  // "B" updates because its State::kIgnored has changed
  ASSERT_EQ(2U, update.nodes.size());
  EXPECT_EQ(0, update.node_id_to_clear);
  EXPECT_EQ(node_a.AxID(), update.nodes[0].id);
  EXPECT_EQ(node_b.AxID(), update.nodes[1].id);
  EXPECT_EQ(2, CountAccessibilityNodesSentToBrowser());
}

// Tests if the bounds of the fixed positioned node is updated after scrolling.
TEST_F(RenderAccessibilityImplTest, TestBoundsForFixedNodeAfterScroll) {
  constexpr char html[] = R"HTML(
      <div id="positioned" style="position:fixed; top:10px; font-size:40px;"
        role="group" aria-label="first">title</div>
      <div style="padding-top: 50px; font-size:40px;">
        <h2>Heading #1</h2>
        <h2>Heading #2</h2>
        <h2>Heading #3</h2>
        <h2>Heading #4</h2>
        <h2>Heading #5</h2>
        <h2>Heading #6</h2>
        <h2>Heading #7</h2>
        <h2>Heading #8</h2>
      </div>
      )HTML";
  LoadHTMLAndRefreshAccessibilityTree(html);

  int scroll_offset_y = 50;

  ui::AXNodeID expected_id = ui::kInvalidAXNodeID;
  ui::AXRelativeBounds expected_bounds;

  // Prepare the expected information from the tree.
  const std::vector<ui::AXTreeUpdate>& updates = GetHandledAccUpdates();
  for (const auto& update : base::Reversed(updates)) {
    for (const ui::AXNodeData& node : update.nodes) {
      if (node.GetStringAttribute(ax::mojom::StringAttribute::kName) ==
          "first") {
        expected_id = node.id;
        expected_bounds = node.relative_bounds;
        expected_bounds.bounds.set_y(expected_bounds.bounds.y() +
                                     scroll_offset_y);
        break;
      }
    }

    if (expected_id != ui::kInvalidAXNodeID)
      break;
  }

  ClearHandledUpdates();

  // Simulate scrolling down using JS.
  std::string js("window.scrollTo(0, " + base::NumberToString(scroll_offset_y) +
                 ");");
  ExecuteJavaScriptForTests(js.c_str());
  GetRenderAccessibilityImpl()->GetAXContext()->UpdateAXForAllDocuments();

  WebDocument document = GetMainFrame()->GetDocument();
  WebAXObject root_obj = WebAXObject::FromWebDocument(document);
  GetRenderAccessibilityImpl()->HandleAXEvent(
      ui::AXEvent(root_obj.AxID(), ax::mojom::Event::kScrollPositionChanged));
  SendPendingAccessibilityEvents();

  EXPECT_EQ(1, CountAccessibilityNodesSentToBrowser());

  // Make sure it's the root object that was updated for scrolling.
  ui::AXTreeUpdate update = GetLastAccUpdate();
  EXPECT_EQ(root_obj.AxID(), update.nodes[0].id);

  // Make sure that a location change is sent for the fixed-positioned node.
  std::vector<ui::AXLocationChange>& changes = GetLocationChanges();
  EXPECT_EQ(changes.size(), 1u);
  EXPECT_EQ(changes[0].id, expected_id);
  EXPECT_EQ(changes[0].new_location, expected_bounds);
}

// Tests if the bounds are updated when it has multiple fixed nodes.
TEST_F(RenderAccessibilityImplTest, TestBoundsForMultipleFixedNodeAfterScroll) {
  constexpr char html[] = R"HTML(
    <div id="positioned" style="position:fixed; top:10px; font-size:40px;"
      role="group" aria-label="first">title1</div>
    <div id="positioned" style="position:fixed; top:50px; font-size:40px;"
      role="group" aria-label="second">title2</div>
    <div style="padding-top: 50px; font-size:40px;">
      <h2>Heading #1</h2>
      <h2>Heading #2</h2>
      <h2>Heading #3</h2>
      <h2>Heading #4</h2>
      <h2>Heading #5</h2>
      <h2>Heading #6</h2>
      <h2>Heading #7</h2>
      <h2>Heading #8</h2>
    </div>)HTML";
  LoadHTMLAndRefreshAccessibilityTree(html);

  int scroll_offset_y = 50;

  std::map<ui::AXNodeID, ui::AXRelativeBounds> expected;

  // Prepare the expected information from the tree.
  const std::vector<ui::AXTreeUpdate>& updates = GetHandledAccUpdates();
  for (const ui::AXTreeUpdate& update : updates) {
    for (const ui::AXNodeData& node : update.nodes) {
      const std::string& name =
          node.GetStringAttribute(ax::mojom::StringAttribute::kName);
      if (name == "first" || name == "second") {
        ui::AXRelativeBounds ax_bounds = node.relative_bounds;
        ax_bounds.bounds.set_y(ax_bounds.bounds.y() + scroll_offset_y);
        expected[node.id] = ax_bounds;
      }
    }
  }

  ClearHandledUpdates();

  // Simulate scrolling down using JS.
  std::string js("window.scrollTo(0, " + base::NumberToString(scroll_offset_y) +
                 ");");
  ExecuteJavaScriptForTests(js.c_str());

  WebDocument document = GetMainFrame()->GetDocument();
  WebAXObject root_obj = WebAXObject::FromWebDocument(document);
  GetRenderAccessibilityImpl()->GetAXContext()->UpdateAXForAllDocuments();
  GetRenderAccessibilityImpl()->HandleAXEvent(
      ui::AXEvent(root_obj.AxID(), ax::mojom::Event::kScrollPositionChanged));
  SendPendingAccessibilityEvents();

  EXPECT_EQ(1, CountAccessibilityNodesSentToBrowser());

  // Make sure it's the root object that was updated for scrolling.
  ui::AXTreeUpdate update = GetLastAccUpdate();
  EXPECT_EQ(root_obj.AxID(), update.nodes[0].id);

  // Make sure that a location change is sent for the fixed-positioned node.
  std::vector<ui::AXLocationChange>& changes = GetLocationChanges();
  EXPECT_EQ(changes.size(), 2u);
  for (auto& change : changes) {
    auto search = expected.find(change.id);
    EXPECT_NE(search, expected.end());
    EXPECT_EQ(search->second, change.new_location);
  }
}

TEST_F(RenderAccessibilityImplTest, TestFocusConsistency) {
  // Using aria-describedby ensures rhe ignored button is included in the tree.
  constexpr char html[] = R"HTML(
      <body>
        <a id="link" tabindex=0>link</a>
        <button id="button" style="visibility:hidden" tabindex=0
                aria-describedby="button">button</button>
        <script>
          link.addEventListener("click", () => {
            button.style.visibility = "visible";
            button.focus();
          });
        </script>
      </body>
      )HTML";
  LoadHTMLAndRefreshAccessibilityTree(html);

  WebDocument document = GetMainFrame()->GetDocument();
  // Getting the root object also forces a layout.
  WebAXObject root_obj = WebAXObject::FromWebDocument(document);
  WebAXObject html_elem = root_obj.ChildAt(0);
  WebAXObject body = html_elem.ChildAt(0);
  WebAXObject link = body.ChildAt(0);
  WebAXObject button = body.ChildAt(1);

  // Set focus to the <a>, this will queue up an initial set of deferred
  // accessibility events to be queued up on AXObjectCacheImpl.
  ui::AXActionData action;
  action.target_node_id = link.AxID();
  action.action = ax::mojom::Action::kFocus;
  GetRenderAccessibilityImpl()->PerformAction(action);

  // Now perform the default action on the link, which will bounce focus to
  // the button element.
  action.target_node_id = link.AxID();
  action.action = ax::mojom::Action::kDoDefault;
  GetRenderAccessibilityImpl()->PerformAction(action);

  // The events and updates from the previous operation would normally be
  // processed in the next frame, but the initial focus operation caused a
  // ScheduleSendPendingAccessibilityEvents.
  SendPendingAccessibilityEvents();

  // The pattern up DOM/style updates above result in multiple AXTreeUpdates
  // sent over mojo. Search the updates to ensure that the button
  const std::vector<ui::AXTreeUpdate>& updates = GetHandledAccUpdates();
  ui::AXNodeID focused_node = ui::kInvalidAXNodeID;
  bool found_button_update = false;
  for (const auto& update : updates) {
    if (update.has_tree_data)
      focused_node = update.tree_data.focus_id;

    for (const auto& node_data : update.nodes) {
      if (node_data.id == button.AxID() &&
          !node_data.HasState(ax::mojom::State::kIgnored))
        found_button_update = true;
    }
  }

  EXPECT_EQ(focused_node, button.AxID());
  EXPECT_TRUE(found_button_update);
}

// Web popups don't exist on some platforms.
#if !BUILDFLAG(USE_EXTERNAL_POPUP_MENU)
TEST_F(RenderAccessibilityImplTest, TestHitTestPopupDoesNotCrash) {
  constexpr char html[] = R"HTML(
      <body>
      <select>
        <option>1</option>
        <option>2</option>
        <option>3</option>
        <option id="option_test">4</option>
      </select>
      <script>
        // Trigger endless layout updates in the popup so the cache is
        // processing deferred events.
        var option_test = document.getElementById("option_test");
        function update() {
          option_test.innerHTML = Math.random();
        }
        window.setInterval(update, 100);
      </script>
      </body>
      )HTML";
  LoadHTMLAndRefreshAccessibilityTree(html);

  WebDocument document = GetMainFrame()->GetDocument();
  // Getting the root object also forces a layout.
  WebAXObject root_obj = WebAXObject::FromWebDocument(document);
  WebAXObject html_elem = root_obj.ChildAt(0);
  WebAXObject body = html_elem.ChildAt(0);
  WebAXObject select = body.ChildAt(0);

  // Open the popup.
  ui::AXActionData action;
  action.target_node_id = select.AxID();
  action.action = ax::mojom::Action::kDoDefault;
  GetRenderAccessibilityImpl()->PerformAction(action);

  blink::WebPagePopup* popup = frame()->GetWebView()->GetPagePopup();
  DCHECK_NE(popup, nullptr);

  // Hit test the popup and ignore the result. This test is ensuring that hit
  // testing can occur while processing deferred events, which means the cache
  // needs to be frozen.
  GetRenderAccessibilityImpl()->HitTest(
      select.GetBoundsInFrameCoordinates().CenterPoint(),
      ax::mojom::Event::kHover, /*request_id*/ 0,
      base::BindOnce(
          [](mojo::StructPtr<blink::mojom::HitTestResponse>) { return; }));
  SendPendingAccessibilityEvents();
}
#endif  // #if !BUILDFLAG(USE_EXTERNAL_POPUP_MENU)

TEST_F(RenderAccessibilityImplTest, TestExpandCollapseTreeItem) {
  constexpr char html[] = R"HTML(
      <body>
        <div>
          <ol role="tree">
            <li role="treeitem" aria-expanded="false" id="1">
            </li>
          </ol>
        </div>
      </body>
    )HTML";
  LoadHTMLAndRefreshAccessibilityTree(html);

  WebDocument document = GetMainFrame()->GetDocument();
  WebAXObject root_obj = WebAXObject::FromWebDocument(document);
  WebAXObject html_elem = root_obj.ChildAt(0);
  WebAXObject body = html_elem.ChildAt(0);
  WebAXObject div = body.ChildAt(0);
  WebAXObject ol = div.ChildAt(0);
  WebAXObject tree_item = ol.ChildAt(0);

  std::string js(
      "document.getElementById('1').addEventListener('keydown', (event) => { "
      "let item = "
      "document.getElementById('1'); if (event.key === 'ArrowRight') { "
      "item.setAttribute('aria-expanded','true');} else if (event.key === "
      "'ArrowLeft') { item.setAttribute('aria-expanded','false'); }}, true);");
  ExecuteJavaScriptForTests(js.c_str());

  // Expanding.
  ui::AXActionData action;
  action.target_node_id = tree_item.AxID();
  action.action = ax::mojom::Action::kExpand;
  GetRenderAccessibilityImpl()->PerformAction(action);
  SendPendingAccessibilityEvents();

  const std::vector<ui::AXTreeUpdate>& updates = GetHandledAccUpdates();
  bool found_expanded_update = false;
  for (const auto& update : updates) {
    for (const auto& node_data : update.nodes) {
      if (node_data.id == tree_item.AxID() &&
          node_data.HasState(ax::mojom::State::kExpanded)) {
        found_expanded_update = true;
      }
    }
  }

  EXPECT_TRUE(found_expanded_update);

  // Expanding when expanded
  action.target_node_id = tree_item.AxID();
  action.action = ax::mojom::Action::kExpand;
  GetRenderAccessibilityImpl()->PerformAction(action);
  SendPendingAccessibilityEvents();

  const std::vector<ui::AXTreeUpdate>& updates_2 = GetHandledAccUpdates();
  found_expanded_update = false;
  for (const auto& update : updates_2) {
    for (const auto& node_data : update.nodes) {
      if (node_data.id == tree_item.AxID() &&
          node_data.HasState(ax::mojom::State::kExpanded)) {
        found_expanded_update = true;
      }
    }
  }

  // Since item was already expanded, it should remain as such.
  EXPECT_TRUE(found_expanded_update);

  // Collapse when expanded.
  action.target_node_id = tree_item.AxID();
  action.action = ax::mojom::Action::kCollapse;
  GetRenderAccessibilityImpl()->PerformAction(action);
  SendPendingAccessibilityEvents();

  const std::vector<ui::AXTreeUpdate>& updates_3 = GetHandledAccUpdates();
  bool found_collapsed_update = false;
  for (const auto& update : updates_3) {
    for (const auto& node_data : update.nodes) {
      if (node_data.id == tree_item.AxID() &&
          node_data.HasState(ax::mojom::State::kCollapsed)) {
        found_collapsed_update = true;
      }
    }
  }

  // Element should have collapsed.
  EXPECT_TRUE(found_collapsed_update);

  // Collapse when collapsed.
  action.target_node_id = tree_item.AxID();
  action.action = ax::mojom::Action::kCollapse;
  GetRenderAccessibilityImpl()->PerformAction(action);
  SendPendingAccessibilityEvents();

  const std::vector<ui::AXTreeUpdate>& updates_4 = GetHandledAccUpdates();
  found_collapsed_update = false;
  for (const auto& update : updates_4) {
    for (const auto& node_data : update.nodes) {
      if (node_data.id == tree_item.AxID() &&
          node_data.HasState(ax::mojom::State::kCollapsed)) {
        found_collapsed_update = true;
      }
    }
  }

  // Element should still be collapsed.
  EXPECT_TRUE(found_collapsed_update);
}

class MockPluginAccessibilityTreeSource
    : public ui::
          AXTreeSource<const ui::AXNode*, ui::AXTreeData*, ui::AXNodeData>,
      public content::PluginAXTreeActionTargetAdapter {
 public:
  MockPluginAccessibilityTreeSource(ui::AXNodeID root_node_id) {
    ax_tree_ = std::make_unique<ui::AXTree>();
    root_node_ =
        std::make_unique<ui::AXNode>(ax_tree_.get(), nullptr, root_node_id, 0);
  }

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

  ~MockPluginAccessibilityTreeSource() override {}
  bool GetTreeData(ui::AXTreeData* data) const override { return true; }
  ui::AXNode* GetRoot() const override { return root_node_.get(); }
  ui::AXNode* GetFromId(ui::AXNodeID id) const override {
    return (root_node_->data().id == id) ? root_node_.get() : nullptr;
  }
  int32_t GetId(const ui::AXNode* node) const override {
    return root_node_->data().id;
  }
  void CacheChildrenIfNeeded(const ui::AXNode*) override {}
  size_t GetChildCount(const ui::AXNode* node) const override {
    return node->children().size();
  }
  const ui::AXNode* ChildAt(const ui::AXNode* node,
                            size_t index) const override {
    return node->children()[index];
  }
  void ClearChildCache(const ui::AXNode*) override {}
  ui::AXNode* GetParent(const ui::AXNode* node) const override {
    return nullptr;
  }
  bool IsEqual(const ui::AXNode* node1,
               const ui::AXNode* node2) const override {
    return (node1 == node2);
  }
  const ui::AXNode* GetNull() const override { return nullptr; }
  void SerializeNode(const ui::AXNode* node,
                     ui::AXNodeData* out_data) const override {
    DCHECK(node);
    *out_data = node->data();
  }
  void HandleAction(const ui::AXActionData& action_data) {}
  void ResetAccActionStatus() {}
  bool IsIgnored(const ui::AXNode* node) const override { return false; }
  std::unique_ptr<ui::AXActionTarget> CreateActionTarget(
      ui::AXNodeID id) override {
    action_target_called_ = true;
    return std::make_unique<ui::NullAXActionTarget>();
  }
  bool GetActionTargetCalled() { return action_target_called_; }
  void ResetActionTargetCalled() { action_target_called_ = false; }

 private:
  std::unique_ptr<ui::AXTree> ax_tree_;
  std::unique_ptr<ui::AXNode> root_node_;
  bool action_target_called_ = false;
};

TEST_F(RenderAccessibilityImplTest, TestAXActionTargetFromNodeId) {
  // Validate that we create the correct type of AXActionTarget for a given
  // node id.
  constexpr char html[] = R"HTML(
      <body>
      </body>
      )HTML";
  LoadHTMLAndRefreshAccessibilityTree(html);

  WebDocument document = GetMainFrame()->GetDocument();
  WebAXObject root_obj = WebAXObject::FromWebDocument(document);
  WebAXObject body = root_obj.ChildAt(0);

  // An AxID for an HTML node should produce a Blink action target.
  std::unique_ptr<ui::AXActionTarget> body_action_target =
      AXActionTargetFactory::CreateFromNodeIdOrRole(document, nullptr,
                                                    body.AxID());
  EXPECT_EQ(ui::AXActionTarget::Type::kBlink, body_action_target->GetType());

  // An AxID for a Plugin node should produce a Plugin action target.
  ui::AXNodeID root_node_id = 100;
  MockPluginAccessibilityTreeSource pdf_acc_tree(root_node_id);
  //  GetRenderAccessibilityImpl()->SetPluginTreeSource(&pdf_acc_tree);

  // An AxId from Pdf, should call PdfAccessibilityTree::CreateActionTarget.
  std::unique_ptr<ui::AXActionTarget> pdf_action_target =
      AXActionTargetFactory::CreateFromNodeIdOrRole(document, &pdf_acc_tree,
                                                    root_node_id);
  EXPECT_TRUE(pdf_acc_tree.GetActionTargetCalled());
  pdf_acc_tree.ResetActionTargetCalled();

  // An invalid AxID should produce a null action target.
  std::unique_ptr<ui::AXActionTarget> null_action_target =
      AXActionTargetFactory::CreateFromNodeIdOrRole(document, &pdf_acc_tree,
                                                    -1);
  EXPECT_EQ(ui::AXActionTarget::Type::kNull, null_action_target->GetType());
}

TEST_F(RenderAccessibilityImplTest, SendPendingAccessibilityEventsPostLoad) {
  LoadHTMLAndRefreshAccessibilityTree(R"HTML(
      <body>
        <input id="text" value="Hello, World">
      </body>
      )HTML");

  // No logs initially.
  base::HistogramTester histogram_tester;
  histogram_tester.ExpectTotalCount(
      "Accessibility.Performance.SendPendingAccessibilityEvents2", 0);
  histogram_tester.ExpectTotalCount(
      "Accessibility.Performance.SendPendingAccessibilityEvents.PostLoad2", 0);

  // A load started event pauses logging.
  WebDocument document = GetMainFrame()->GetDocument();
  WebAXObject root_obj = WebAXObject::FromWebDocument(document);
  GetRenderAccessibilityImpl()->DidCommitProvisionalLoad(
      ui::PAGE_TRANSITION_LINK);
  GetRenderAccessibilityImpl()->HandleAXEvent(
      ui::AXEvent(root_obj.AxID(), ax::mojom::Event::kLoadStart));
  SendPendingAccessibilityEvents();
  histogram_tester.ExpectTotalCount(
      "Accessibility.Performance.SendPendingAccessibilityEvents2", 1);
  histogram_tester.ExpectTotalCount(
      "Accessibility.Performance.SendPendingAccessibilityEvents.PostLoad2", 0);

  // Do not log in the serialization immediately following load completion.
  GetRenderAccessibilityImpl()->HandleAXEvent(
      ui::AXEvent(root_obj.AxID(), ax::mojom::Event::kLoadComplete));
  SendPendingAccessibilityEvents();
  histogram_tester.ExpectTotalCount(
      "Accessibility.Performance.SendPendingAccessibilityEvents2", 2);
  histogram_tester.ExpectTotalCount(
      "Accessibility.Performance.SendPendingAccessibilityEvents.PostLoad2", 0);

  // Now we start logging.
  GetRenderAccessibilityImpl()->MarkWebAXObjectDirty(root_obj);
  SendPendingAccessibilityEvents();
  histogram_tester.ExpectTotalCount(
      "Accessibility.Performance.SendPendingAccessibilityEvents2", 3);
  histogram_tester.ExpectTotalCount(
      "Accessibility.Performance.SendPendingAccessibilityEvents.PostLoad2", 1);

  GetRenderAccessibilityImpl()->MarkWebAXObjectDirty(root_obj);
  SendPendingAccessibilityEvents();
  histogram_tester.ExpectTotalCount(
      "Accessibility.Performance.SendPendingAccessibilityEvents2", 4);
  histogram_tester.ExpectTotalCount(
      "Accessibility.Performance.SendPendingAccessibilityEvents.PostLoad2", 2);
}

class BlinkAXActionTargetTest : public RenderAccessibilityImplTest {
 protected:
  void SetUp() override {
    // Disable overlay scrollbars to avoid DCHECK on ChromeOS.
    feature_list_.InitAndDisableFeature(features::kOverlayScrollbar);

    RenderAccessibilityImplTest::SetUp();
  }

 private:
  base::test::ScopedFeatureList feature_list_;
};

TEST_F(BlinkAXActionTargetTest, TestSetRangeValue) {
  constexpr char html[] = R"HTML(
      <body>
        <input type=range min=1 value=2 max=3 step=1>
      </body>
      )HTML";
  LoadHTMLAndRefreshAccessibilityTree(html);

  WebDocument document = GetMainFrame()->GetDocument();
  WebAXObject root_obj = WebAXObject::FromWebDocument(document);
  WebAXObject html_elem = root_obj.ChildAt(0);
  WebAXObject body = html_elem.ChildAt(0);
  WebAXObject input_range = body.ChildAt(0);

  float value = 0.0f;
  EXPECT_TRUE(input_range.ValueForRange(&value));
  EXPECT_EQ(2.0f, value);
  std::unique_ptr<ui::AXActionTarget> input_range_action_target =
      AXActionTargetFactory::CreateFromNodeIdOrRole(document, nullptr,
                                                    input_range.AxID());
  EXPECT_EQ(ui::AXActionTarget::Type::kBlink,
            input_range_action_target->GetType());

  std::string value_to_set("1.0");
  {
    ui::AXActionData action_data;
    action_data.action = ax::mojom::Action::kSetValue;
    action_data.value = value_to_set;
    EXPECT_TRUE(input_range.PerformAction(action_data));
  }
  EXPECT_TRUE(input_range.ValueForRange(&value));
  EXPECT_EQ(1.0f, value);

  SendPendingAccessibilityEvents();
  EXPECT_EQ(1, CountAccessibilityNodesSentToBrowser());
  {
    // Make sure it's the input range object that was updated.
    ui::AXTreeUpdate update = GetLastAccUpdate();
    EXPECT_EQ(input_range.AxID(), update.nodes[0].id);
  }
}

TEST_F(BlinkAXActionTargetTest, TestMethods) {
  // Exercise the methods on BlinkAXActionTarget to ensure they have the
  // expected effects.
  constexpr char html[] = R"HTML(
      <body>
        <input type=checkbox>
        <input type=range min=1 value=2 max=3 step=1>
        <input type=text>
        <select size=2>
          <option>One</option>
          <option>Two</option>
        </select>
        <div style='width:100px; height: 100px; overflow:scroll'>
          <div style='width:1000px; height:900px'></div>
          <div style='width:1000px; height:100px'></div>
        </div>
        <div>Text Node One</div>
        <div>Text Node Two</div>
      </body>
      )HTML";
  LoadHTMLAndRefreshAccessibilityTree(html);

  WebDocument document = GetMainFrame()->GetDocument();
  WebAXObject root_obj = WebAXObject::FromWebDocument(document);
  WebAXObject html_elem = root_obj.ChildAt(0);
  WebAXObject body = html_elem.ChildAt(0);
  WebAXObject input_checkbox = body.ChildAt(0);
  WebAXObject input_range = body.ChildAt(1);
  WebAXObject input_text = body.ChildAt(2);
  WebAXObject option = body.ChildAt(3).ChildAt(0).ChildAt(0);
  WebAXObject scroller = body.ChildAt(4);
  WebAXObject scroller_child = body.ChildAt(4).ChildAt(1);
  WebAXObject text_one = body.ChildAt(5).ChildAt(0);
  WebAXObject text_two = body.ChildAt(6).ChildAt(0);

  std::unique_ptr<ui::AXActionTarget> input_checkbox_action_target =
      AXActionTargetFactory::CreateFromNodeIdOrRole(document, nullptr,
                                                    input_checkbox.AxID());
  EXPECT_EQ(ui::AXActionTarget::Type::kBlink,
            input_checkbox_action_target->GetType());

  std::unique_ptr<ui::AXActionTarget> input_range_action_target =
      AXActionTargetFactory::CreateFromNodeIdOrRole(document, nullptr,
                                                    input_range.AxID());
  EXPECT_EQ(ui::AXActionTarget::Type::kBlink,
            input_range_action_target->GetType());

  std::unique_ptr<ui::AXActionTarget> input_text_action_target =
      AXActionTargetFactory::CreateFromNodeIdOrRole(document, nullptr,
                                                    input_text.AxID());
  EXPECT_EQ(ui::AXActionTarget::Type::kBlink,
            input_text_action_target->GetType());

  std::unique_ptr<ui::AXActionTarget> option_action_target =
      AXActionTargetFactory::CreateFromNodeIdOrRole(document, nullptr,
                                                    option.AxID());
  EXPECT_EQ(ui::AXActionTarget::Type::kBlink, option_action_target->GetType());

  std::unique_ptr<ui::AXActionTarget> scroller_action_target =
      AXActionTargetFactory::CreateFromNodeIdOrRole(document, nullptr,
                                                    scroller.AxID());
  EXPECT_EQ(ui::AXActionTarget::Type::kBlink,
            scroller_action_target->GetType());

  std::unique_ptr<ui::AXActionTarget> scroller_child_action_target =
      AXActionTargetFactory::CreateFromNodeIdOrRole(document, nullptr,
                                                    scroller_child.AxID());
  EXPECT_EQ(ui::AXActionTarget::Type::kBlink,
            scroller_child_action_target->GetType());

  std::unique_ptr<ui::AXActionTarget> text_one_action_target =
      AXActionTargetFactory::CreateFromNodeIdOrRole(document, nullptr,
                                                    text_one.AxID());
  EXPECT_EQ(ui::AXActionTarget::Type::kBlink,
            text_one_action_target->GetType());

  std::unique_ptr<ui::AXActionTarget> text_two_action_target =
      AXActionTargetFactory::CreateFromNodeIdOrRole(document, nullptr,
                                                    text_two.AxID());
  EXPECT_EQ(ui::AXActionTarget::Type::kBlink,
            text_two_action_target->GetType());

  EXPECT_EQ(ax::mojom::CheckedState::kFalse, input_checkbox.CheckedState());
  {
    ui::AXActionData action_data;
    action_data.action = ax::mojom::Action::kDoDefault;
    EXPECT_TRUE(input_checkbox_action_target->PerformAction(action_data));
  }
  EXPECT_EQ(ax::mojom::CheckedState::kTrue, input_checkbox.CheckedState());

  float value = 0.0f;
  EXPECT_TRUE(input_range.ValueForRange(&value));
  EXPECT_EQ(2.0f, value);
  {
    ui::AXActionData action_data;
    action_data.action = ax::mojom::Action::kDecrement;
    EXPECT_TRUE(input_range_action_target->PerformAction(action_data));
  }
  EXPECT_TRUE(input_range.ValueForRange(&value));
  EXPECT_EQ(1.0f, value);
  {
    ui::AXActionData action_data;
    action_data.action = ax::mojom::Action::kIncrement;
    EXPECT_TRUE(input_range_action_target->PerformAction(action_data));
  }
  EXPECT_TRUE(input_range.ValueForRange(&value));
  EXPECT_EQ(2.0f, value);

  EXPECT_FALSE(input_range.IsFocused());
  {
    ui::AXActionData action_data;
    action_data.action = ax::mojom::Action::kFocus;
    EXPECT_TRUE(input_range_action_target->PerformAction(action_data));
  }
  EXPECT_TRUE(input_range.IsFocused());

  {
    // Blurring an element requires layout to be clean.
    GetRenderAccessibilityImpl()->GetAXContext()->UpdateAXForAllDocuments();
    ui::AXActionData action_data;
    action_data.action = ax::mojom::Action::kBlur;
    EXPECT_TRUE(input_range_action_target->PerformAction(action_data));
  }
  EXPECT_FALSE(input_range.IsFocused());

  // Increment/decrement actions produce synthesized keydown and keyup events,
  // and the keyup event is delayed 100ms to look more natural. We need to wait
  // for them to happen to finish the test cleanly in the TearDown phase.
  task_environment_.FastForwardBy(base::Seconds(1));
  GetRenderAccessibilityImpl()->GetAXContext()->UpdateAXForAllDocuments();

  gfx::RectF expected_bounds;
  blink::WebAXObject offset_container;
  gfx::Transform container_transform;
  input_checkbox.GetRelativeBounds(offset_container, expected_bounds,
                                   container_transform);
  gfx::Rect actual_bounds = input_checkbox_action_target->GetRelativeBounds();
  EXPECT_EQ(static_cast<int>(expected_bounds.x()), actual_bounds.x());
  EXPECT_EQ(static_cast<int>(expected_bounds.y()), actual_bounds.y());
  EXPECT_EQ(static_cast<int>(expected_bounds.width()), actual_bounds.width());
  EXPECT_EQ(static_cast<int>(expected_bounds.height()), actual_bounds.height());

  gfx::Point offset_to_set(500, 500);
  scroller_action_target->SetScrollOffset(gfx::Point(500, 500));
  EXPECT_EQ(offset_to_set, scroller_action_target->GetScrollOffset());
  EXPECT_EQ(gfx::Point(0, 0), scroller_action_target->MinimumScrollOffset());
  EXPECT_GE(scroller_action_target->MaximumScrollOffset().y(), 900);

  std::string value_to_set("test-value");
  {
    ui::AXActionData action_data;
    action_data.action = ax::mojom::Action::kSetValue;
    action_data.value = value_to_set;
    EXPECT_TRUE(input_text_action_target->PerformAction(action_data));
  }
  EXPECT_EQ(value_to_set, input_text.GetValueForControl().Utf8());

  // Setting selection requires layout to be clean.
  GetRenderAccessibilityImpl()->GetAXContext()->UpdateAXForAllDocuments();

  EXPECT_TRUE(text_one_action_target->SetSelection(
      text_one_action_target.get(), 3, text_two_action_target.get(), 4));
  bool is_selection_backward;
  blink::WebAXObject anchor_object;
  int anchor_offset;
  ax::mojom::TextAffinity anchor_affinity;
  blink::WebAXObject focus_object;
  int focus_offset;
  ax::mojom::TextAffinity focus_affinity;
  root_obj.Selection(is_selection_backward, anchor_object, anchor_offset,
                     anchor_affinity, focus_object, focus_offset,
                     focus_affinity);
  EXPECT_EQ(text_one, anchor_object);
  EXPECT_EQ(3, anchor_offset);
  EXPECT_EQ(text_two, focus_object);
  EXPECT_EQ(4, focus_offset);

  scroller_action_target->SetScrollOffset(gfx::Point(0, 0));
  EXPECT_EQ(gfx::Point(0, 0), scroller_action_target->GetScrollOffset());
  EXPECT_TRUE(scroller_child_action_target->ScrollToMakeVisible());
  EXPECT_GE(scroller_action_target->GetScrollOffset().y(), 900);

  scroller_action_target->SetScrollOffset(gfx::Point(0, 0));
  EXPECT_EQ(gfx::Point(0, 0), scroller_action_target->GetScrollOffset());
  EXPECT_TRUE(scroller_child_action_target->ScrollToMakeVisibleWithSubFocus(
      gfx::Rect(0, 0, 50, 50), ax::mojom::ScrollAlignment::kScrollAlignmentLeft,
      ax::mojom::ScrollAlignment::kScrollAlignmentTop,
      ax::mojom::ScrollBehavior::kDoNotScrollIfVisible));
  EXPECT_GE(scroller_action_target->GetScrollOffset().y(), 900);

  scroller_action_target->SetScrollOffset(gfx::Point(0, 0));
  EXPECT_EQ(gfx::Point(0, 0), scroller_action_target->GetScrollOffset());
  {
    ui::AXActionData action_data;
    action_data.action = ax::mojom::Action::kScrollToPoint;
    action_data.target_point = gfx::Point(0, 0);
    EXPECT_TRUE(scroller_child_action_target->PerformAction(action_data));
  }
  EXPECT_GE(scroller_action_target->GetScrollOffset().y(), 900);
}

// URL-keyed metrics recorder implementation that just counts the number
// of times it's been called.
class MockUkmRecorder : public ukm::MojoUkmRecorder {
 public:
  MockUkmRecorder(ukm::mojom::UkmRecorderFactory& factory)
      : MojoUkmRecorder(factory) {}
  void AddEntry(ukm::mojom::UkmEntryPtr entry) override { calls_++; }

  int calls() const { return calls_; }

 private:
  int calls_ = 0;
};

// Tests for URL-keyed metrics.
class RenderAccessibilityImplUKMTest : public RenderAccessibilityImplTest {
 public:
  void SetUp() override {
    RenderAccessibilityImplTest::SetUp();
    mojo::Remote<ukm::mojom::UkmRecorderFactory> factory;
    std::ignore = factory.BindNewPipeAndPassReceiver();
    GetRenderAccessibilityImpl()->ukm_recorder_ =
        std::make_unique<MockUkmRecorder>(*factory);
  }

  void TearDown() override { RenderAccessibilityImplTest::TearDown(); }

  MockUkmRecorder* ukm_recorder() {
    return static_cast<MockUkmRecorder*>(
        GetRenderAccessibilityImpl()->ukm_recorder_.get());
  }

  void SetTimeDelayForNextSerialize(base::TimeDelta delta) {
    task_environment_.FastForwardBy(delta);
    GetRenderAccessibilityImpl()->slowest_serialization_time_ = delta;
  }
};

TEST_F(RenderAccessibilityImplUKMTest, TestFireUKMs) {
  LoadHTMLAndRefreshAccessibilityTree(R"HTML(
      <body>
        <input id="text" value="Hello, World">
      </body>
      )HTML");

  // No URL-keyed metrics should be fired initially.
  EXPECT_EQ(0, ukm_recorder()->calls());
  base::HistogramTester histogram_tester;
  histogram_tester.ExpectTotalCount(
      "Accessibility.Performance.SendPendingAccessibilityEvents2", 0);

  // No URL-keyed metrics should be fired after we send one event.
  WebDocument document = GetMainFrame()->GetDocument();
  WebAXObject root_obj = WebAXObject::FromWebDocument(document);
  GetRenderAccessibilityImpl()->MarkWebAXObjectDirty(root_obj);
  SendPendingAccessibilityEvents();
  EXPECT_EQ(0, ukm_recorder()->calls());
  histogram_tester.ExpectTotalCount(
      "Accessibility.Performance.SendPendingAccessibilityEvents2", 1);

  // No URL-keyed metrics should be fired even after an event that takes
  // 300 ms, but we should now have something to send.
  // This must be >= kMinSerializationTimeToSendInMS
  GetRenderAccessibilityImpl()->MarkWebAXObjectDirty(root_obj);
  SendPendingAccessibilityEvents();
  SetTimeDelayForNextSerialize(base::Milliseconds(300));
  EXPECT_EQ(0, ukm_recorder()->calls());
  histogram_tester.ExpectTotalCount(
      "Accessibility.Performance.SendPendingAccessibilityEvents2", 2);

  // After 1000 seconds have passed, the next time we send an event we should
  // send URL-keyed metrics.
  task_environment_.FastForwardBy(base::Seconds(1000));
  GetRenderAccessibilityImpl()->MarkWebAXObjectDirty(root_obj);
  SendPendingAccessibilityEvents();
  EXPECT_EQ(1, ukm_recorder()->calls());
  histogram_tester.ExpectTotalCount(
      "Accessibility.Performance.SendPendingAccessibilityEvents2", 3);

  // Send another event that takes a long (simulated) time to serialize.
  // This must be >= kMinSerializationTimeToSend
  SetTimeDelayForNextSerialize(base::Milliseconds(200));
  GetRenderAccessibilityImpl()->MarkWebAXObjectDirty(root_obj);
  SendPendingAccessibilityEvents();
  histogram_tester.ExpectTotalCount(
      "Accessibility.Performance.SendPendingAccessibilityEvents2", 4);

  // We shouldn't have a new call to the UKM recorder yet, not enough
  // time has elapsed.
  EXPECT_EQ(1, ukm_recorder()->calls());

  // Navigate to a new page.
  GetRenderAccessibilityImpl()->DidCommitProvisionalLoad(
      ui::PAGE_TRANSITION_LINK);

  // Now we should have yet another UKM recorded because of the page
  // transition.
  EXPECT_EQ(2, ukm_recorder()->calls());
}

}  // namespace content
