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

#include "third_party/blink/renderer/core/content_capture/content_capture_manager.h"

#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/web/web_content_capture_client.h"
#include "third_party/blink/public/web/web_content_holder.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h"
#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/core/html/html_iframe_element.h"
#include "third_party/blink/renderer/core/html_element_type_helpers.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/layout/layout_text.h"
#include "third_party/blink/renderer/core/loader/empty_clients.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/core/testing/sim/sim_request.h"
#include "third_party/blink/renderer/core/testing/sim/sim_test.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"

namespace blink {

namespace {

gfx::Rect GetRect(LayoutObject* layout_object) {
  return gfx::Rect(EnclosingIntRect(layout_object->VisualRectInDocument()));
}

void FindNodeVectorsDiff(const Vector<Persistent<Node>>& a,
                         const Vector<Persistent<Node>>& b,
                         Vector<Persistent<Node>>& a_diff_b) {
  for (auto& i : a) {
    if (!b.Contains(i))
      a_diff_b.push_back(i);
  }
}

void FindNodeVectorsDiff(const Vector<Persistent<Node>>& a,
                         const Vector<Persistent<Node>>& b,
                         Vector<Persistent<Node>>& a_diff_b,
                         Vector<Persistent<Node>>& b_diff_a) {
  FindNodeVectorsDiff(a, b, a_diff_b);
  FindNodeVectorsDiff(b, a, b_diff_a);
}

void FindNodeVectorsUnion(const Vector<Persistent<Node>>& a,
                          const Vector<Persistent<Node>>& b,
                          HashSet<Persistent<Node>>& a_and_b) {
  for (auto& n : a) {
    a_and_b.insert(n);
  }
  for (auto& n : b) {
    a_and_b.insert(n);
  }
}

void ToNodeIds(const Vector<Persistent<Node>>& nodes,
               Vector<int64_t>& node_ids) {
  for (auto& v : nodes) {
    node_ids.push_back(reinterpret_cast<int64_t>(static_cast<Node*>(v)));
  }
}

void ToNodeTexts(const Vector<Persistent<Node>>& nodes,
                 Vector<std::string>& texts) {
  for (auto& n : nodes)
    texts.push_back(n->nodeValue().Utf8());
}

}  // namespace

class WebContentCaptureClientTestHelper : public WebContentCaptureClient {
 public:
  ~WebContentCaptureClientTestHelper() override = default;

  void GetTaskTimingParameters(base::TimeDelta& short_delay,
                               base::TimeDelta& long_delay) const override {
    short_delay = GetTaskShortDelay();
    long_delay = GetTaskLongDelay();
  }

  base::TimeDelta GetTaskLongDelay() const {
    return base::TimeDelta::FromMilliseconds(5000);
  }

  base::TimeDelta GetTaskShortDelay() const {
    return base::TimeDelta::FromMilliseconds(500);
  }

  void DidCaptureContent(const WebVector<WebContentHolder>& data,
                         bool first_data) override {
    data_ = data;
    first_data_ = first_data;
    for (auto& d : data) {
      auto text = d.GetValue().Utf8();
      all_text_.push_back(text);
      captured_text_.push_back(text);
    }
  }

  void DidUpdateContent(const WebVector<WebContentHolder>& data) override {
    updated_data_ = data;
    for (auto& d : data)
      updated_text_.push_back(d.GetValue().Utf8());
  }

  void DidRemoveContent(WebVector<int64_t> data) override {
    removed_data_ = data;
  }

  bool FirstData() const { return first_data_; }

  const WebVector<WebContentHolder>& Data() const { return data_; }

  const WebVector<WebContentHolder>& UpdatedData() const {
    return updated_data_;
  }

  const Vector<std::string>& AllText() const { return all_text_; }

  const Vector<std::string>& CapturedText() const { return captured_text_; }

  const Vector<std::string>& UpdatedText() const { return updated_text_; }

  const WebVector<int64_t>& RemovedData() const { return removed_data_; }

  void ResetResults() {
    first_data_ = false;
    data_.Clear();
    updated_data_.Clear();
    removed_data_.Clear();
    captured_text_.clear();
  }

 private:
  bool first_data_ = false;
  WebVector<WebContentHolder> data_;
  WebVector<WebContentHolder> updated_data_;
  WebVector<int64_t> removed_data_;
  Vector<std::string> all_text_;
  Vector<std::string> updated_text_;
  Vector<std::string> captured_text_;
};

class ContentCaptureTaskTestHelper : public ContentCaptureTask {
 public:
  ContentCaptureTaskTestHelper(LocalFrame& local_frame_root,
                               TaskSession& task_session,
                               WebContentCaptureClient& content_capture_client)
      : ContentCaptureTask(local_frame_root, task_session),
        content_capture_client_(&content_capture_client) {}
  void SetTaskStopState(TaskState state) { task_stop_state_ = state; }

 protected:
  WebContentCaptureClient* GetWebContentCaptureClient(
      const Document& document) override {
    return content_capture_client_;
  }

  bool ShouldPause() override {
    return GetTaskStateForTesting() == task_stop_state_;
  }

 private:
  WebContentCaptureClient* content_capture_client_;
  TaskState task_stop_state_ = TaskState::kStop;
};

class ContentCaptureManagerTestHelper : public ContentCaptureManager {
 public:
  ContentCaptureManagerTestHelper(
      LocalFrame& local_frame_root,
      WebContentCaptureClientTestHelper& content_capture_client)
      : ContentCaptureManager(local_frame_root) {
    content_capture_task_ = MakeGarbageCollected<ContentCaptureTaskTestHelper>(
        local_frame_root, GetTaskSessionForTesting(), content_capture_client);
  }

  ContentCaptureTaskTestHelper* GetContentCaptureTask() {
    return content_capture_task_;
  }

  void Trace(Visitor* visitor) const override {
    visitor->Trace(content_capture_task_);
    ContentCaptureManager::Trace(visitor);
  }

 protected:
  ContentCaptureTask* CreateContentCaptureTask() override {
    return content_capture_task_;
  }

 private:
  Member<ContentCaptureTaskTestHelper> content_capture_task_;
};

class ContentCaptureLocalFrameClientHelper : public EmptyLocalFrameClient {
 public:
  ContentCaptureLocalFrameClientHelper(WebContentCaptureClient& client)
      : client_(client) {}

  WebContentCaptureClient* GetWebContentCaptureClient() const override {
    return &client_;
  }

 private:
  WebContentCaptureClient& client_;
};

class ContentCaptureTest
    : public PageTestBase,
      public ::testing::WithParamInterface<std::vector<base::Feature>> {
 public:
  ContentCaptureTest() {
    EnablePlatform();
    feature_list_.InitWithFeatures(
        GetParam(), /*disabled_features=*/std::vector<base::Feature>());
  }

  void SetUp() override {
    content_capture_client_ =
        std::make_unique<WebContentCaptureClientTestHelper>();
    local_frame_client_ =
        MakeGarbageCollected<ContentCaptureLocalFrameClientHelper>(
            *content_capture_client_);
    SetupPageWithClients(nullptr, local_frame_client_);
    SetHtmlInnerHTML(
        "<!DOCTYPE HTML>"
        "<p id='p1'>1</p>"
        "<p id='p2'>2</p>"
        "<p id='p3'>3</p>"
        "<p id='p4'>4</p>"
        "<p id='p5'>5</p>"
        "<p id='p6'>6</p>"
        "<p id='p7'>7</p>"
        "<p id='p8'>8</p>"
        "<div id='d1'></div>"
        "<p id='invisible'>invisible</p>");
    platform()->SetAutoAdvanceNowToPendingTasks(false);
    // TODO(michaelbai): ContentCaptureManager should be get from LocalFrame.
    content_capture_manager_ =
        MakeGarbageCollected<ContentCaptureManagerTestHelper>(
            GetFrame(), *content_capture_client_);

    InitNodeHolders();
    // Setup captured content to ContentCaptureTask, it isn't necessary once
    // ContentCaptureManager is created by LocalFrame.
    content_capture_manager_->GetContentCaptureTask()
        ->SetCapturedContentForTesting(node_ids_);
    InitScrollingTestData();
  }

  void SimulateScrolling(size_t step) {
    CHECK_LT(step, 4u);
    content_capture_manager_->GetContentCaptureTask()
        ->SetCapturedContentForTesting(scrolling_node_ids_[step]);
    content_capture_manager_->OnScrollPositionChanged();
  }

  void CreateTextNodeAndNotifyManager() {
    Document& doc = GetDocument();
    Node* node = doc.createTextNode("New Text");
    Element* element = MakeGarbageCollected<Element>(html_names::kPTag, &doc);
    element->appendChild(node);
    Element* div_element = GetElementById("d1");
    div_element->appendChild(element);
    UpdateAllLifecyclePhasesForTest();
    GetContentCaptureManager()->ScheduleTaskIfNeeded(*node);
    created_node_id_ = DOMNodeIds::IdForNode(node);
    Vector<cc::NodeInfo> captured_content{
        cc::NodeInfo(created_node_id_, GetRect(node->GetLayoutObject()))};
    content_capture_manager_->GetContentCaptureTask()
        ->SetCapturedContentForTesting(captured_content);
  }

  ContentCaptureManagerTestHelper* GetContentCaptureManager() const {
    return content_capture_manager_;
  }

  WebContentCaptureClientTestHelper* GetWebContentCaptureClient() const {
    return content_capture_client_.get();
  }

  ContentCaptureTaskTestHelper* GetContentCaptureTask() const {
    return GetContentCaptureManager()->GetContentCaptureTask();
  }

  void RunContentCaptureTask() {
    ResetResult();
    platform()->RunForPeriod(GetWebContentCaptureClient()->GetTaskShortDelay());
  }

  void RunLongDelayContentCaptureTask() {
    ResetResult();
    platform()->RunForPeriod(GetWebContentCaptureClient()->GetTaskLongDelay());
  }

  void RemoveNode(Node* node) {
    // Remove the node.
    node->remove();
    GetContentCaptureManager()->OnLayoutTextWillBeDestroyed(*node);
  }

  void RemoveUnsentNode(const WebVector<WebContentHolder>& sent_nodes) {
    // Find a node isn't in sent_nodes
    for (auto node : nodes_) {
      bool found_in_sent = false;
      for (auto& sent : sent_nodes) {
        found_in_sent = (node->nodeValue().Utf8().c_str() == sent.GetValue());
        if (found_in_sent)
          break;
      }
      if (!found_in_sent) {
        RemoveNode(node);
        return;
      }
    }
    // Didn't find unsent nodes.
    NOTREACHED();
  }

  size_t GetExpectedFirstResultSize() { return ContentCaptureTask::kBatchSize; }

  size_t GetExpectedSecondResultSize() {
    return node_ids_.size() - GetExpectedFirstResultSize();
  }

  const Vector<cc::NodeInfo>& NodeIds() const { return node_ids_; }
  const Vector<Persistent<Node>> Nodes() const { return nodes_; }

  Node& invisible_node() const { return *invisible_node_; }

  const Vector<Vector<std::string>>& scrolling_expected_captured_nodes() {
    return scrolling_expected_captured_nodes_;
  }

  const Vector<Vector<int64_t>>& scrolling_expected_removed_nodes() {
    return scrolling_expected_removed_nodes_;
  }

 private:
  void ResetResult() {
    GetWebContentCaptureClient()->ResetResults();
  }

  void BuildNodesInfo(const Vector<std::string>& ids,
                      Vector<Persistent<Node>>& nodes,
                      Vector<cc::NodeInfo>& node_ids) {
    for (auto id : ids) {
      Node* node = GetElementById(id.c_str())->firstChild();
      CHECK(node);
      LayoutObject* layout_object = node->GetLayoutObject();
      CHECK(layout_object);
      CHECK(layout_object->IsText());
      nodes.push_back(node);
      GetContentCaptureManager()->ScheduleTaskIfNeeded(*node);
      node_ids.push_back(
          cc::NodeInfo(DOMNodeIds::IdForNode(node), GetRect(layout_object)));
    }
  }

  // TODO(michaelbai): Remove this once integrate with LayoutText.
  void InitNodeHolders() {
    BuildNodesInfo(
        Vector<std::string>{"p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8"},
        nodes_, node_ids_);
    invisible_node_ = GetElementById("invisible")->firstChild();
    DCHECK(invisible_node_.Get());
  }

  void InitScrollingTestData() {
    Vector<Vector<Persistent<Node>>> nodes{4};
    BuildNodesInfo(Vector<std::string>{"p1", "p2", "p3"}, nodes[0],
                   scrolling_node_ids_[0]);
    BuildNodesInfo(Vector<std::string>{"p3", "p4", "p5"}, nodes[1],
                   scrolling_node_ids_[1]);
    BuildNodesInfo(Vector<std::string>{"p6", "p7", "p8"}, nodes[2],
                   scrolling_node_ids_[2]);
    BuildNodesInfo(Vector<std::string>{"p2", "p3"}, nodes[3],
                   scrolling_node_ids_[3]);
    // Build expected result.
    if (base::FeatureList::IsEnabled(
            features::kContentCaptureConstantStreaming)) {
      for (int i = 0; i < 4; ++i) {
        Vector<Persistent<Node>> a_diff_b;
        Vector<Persistent<Node>> b_diff_a;
        FindNodeVectorsDiff(nodes[i],
                            i == 0 ? Vector<Persistent<Node>>() : nodes[i - 1],
                            a_diff_b, b_diff_a);
        ToNodeTexts(a_diff_b, scrolling_expected_captured_nodes_[i]);
        ToNodeIds(b_diff_a, scrolling_expected_removed_nodes_[i]);
      }
    } else {
      HashSet<Persistent<Node>> sent;
      for (int i = 0; i < 4; ++i) {
        Vector<Persistent<Node>> a_diff_b;
        Vector<Persistent<Node>> b;
        CopyToVector(sent, b);
        FindNodeVectorsDiff(nodes[i], b, a_diff_b);
        ToNodeTexts(a_diff_b, scrolling_expected_captured_nodes_[i]);
        sent.clear();
        FindNodeVectorsUnion(b, nodes[i], sent);
      }
    }
  }

  Vector<Persistent<Node>> nodes_;
  Vector<cc::NodeInfo> node_ids_;
  Persistent<Node> invisible_node_;
  Vector<Vector<std::string>> scrolling_expected_captured_nodes_{4};
  Vector<Vector<int64_t>> scrolling_expected_removed_nodes_{4};
  Vector<Vector<cc::NodeInfo>> scrolling_node_ids_{4};
  std::unique_ptr<WebContentCaptureClientTestHelper> content_capture_client_;
  Persistent<ContentCaptureManagerTestHelper> content_capture_manager_;
  Persistent<ContentCaptureLocalFrameClientHelper> local_frame_client_;
  DOMNodeId created_node_id_ = kInvalidDOMNodeId;
  base::test::ScopedFeatureList feature_list_;
};

INSTANTIATE_TEST_SUITE_P(
    ,
    ContentCaptureTest,
    testing::Values(
        std::vector<base::Feature>{},
        std::vector<base::Feature>{features::kContentCaptureUserActivatedDelay},
        std::vector<base::Feature>{features::kContentCaptureConstantStreaming},
        std::vector<base::Feature>{
            features::kContentCaptureUserActivatedDelay,
            features::kContentCaptureConstantStreaming}));

TEST_P(ContentCaptureTest, Basic) {
  RunContentCaptureTask();
  EXPECT_EQ(ContentCaptureTask::TaskState::kStop,
            GetContentCaptureTask()->GetTaskStateForTesting());
  EXPECT_FALSE(GetWebContentCaptureClient()->Data().empty());
  EXPECT_EQ(GetExpectedSecondResultSize(),
            GetWebContentCaptureClient()->Data().size());
}

TEST_P(ContentCaptureTest, Scrolling) {
  for (size_t step = 0; step < 4; ++step) {
    SimulateScrolling(step);
    RunContentCaptureTask();
    EXPECT_EQ(ContentCaptureTask::TaskState::kStop,
              GetContentCaptureTask()->GetTaskStateForTesting());
    EXPECT_THAT(GetWebContentCaptureClient()->CapturedText(),
                testing::UnorderedElementsAreArray(
                    scrolling_expected_captured_nodes()[step]))
        << "at step " << step;
    EXPECT_THAT(GetWebContentCaptureClient()->RemovedData(),
                testing::UnorderedElementsAreArray(
                    scrolling_expected_removed_nodes()[step]))
        << "at step " << step;
  }
}

TEST_P(ContentCaptureTest, PauseAndResume) {
  // The task stops before captures content.
  GetContentCaptureTask()->SetTaskStopState(
      ContentCaptureTask::TaskState::kCaptureContent);
  RunContentCaptureTask();
  EXPECT_FALSE(GetWebContentCaptureClient()->FirstData());
  EXPECT_TRUE(GetWebContentCaptureClient()->Data().empty());
  EXPECT_TRUE(GetWebContentCaptureClient()->RemovedData().empty());

  // The task stops before sends the captured content out.
  GetContentCaptureTask()->SetTaskStopState(
      ContentCaptureTask::TaskState::kProcessCurrentSession);
  RunContentCaptureTask();
  EXPECT_FALSE(GetWebContentCaptureClient()->FirstData());
  EXPECT_TRUE(GetWebContentCaptureClient()->Data().empty());
  EXPECT_TRUE(GetWebContentCaptureClient()->RemovedData().empty());

  // The task should be stop at kProcessRetryTask because the captured content
  // needs to be sent with 2 batch.
  GetContentCaptureTask()->SetTaskStopState(
      ContentCaptureTask::TaskState::kProcessRetryTask);
  RunContentCaptureTask();
  EXPECT_TRUE(GetWebContentCaptureClient()->FirstData());
  EXPECT_FALSE(GetWebContentCaptureClient()->Data().empty());
  EXPECT_TRUE(GetWebContentCaptureClient()->RemovedData().empty());
  EXPECT_EQ(GetExpectedFirstResultSize(),
            GetWebContentCaptureClient()->Data().size());

  // Run task until it stops, task will not capture content, because there is no
  // content change, so we have 3 NodeHolders.
  GetContentCaptureTask()->SetTaskStopState(
      ContentCaptureTask::TaskState::kStop);
  RunContentCaptureTask();
  EXPECT_FALSE(GetWebContentCaptureClient()->FirstData());
  EXPECT_FALSE(GetWebContentCaptureClient()->Data().empty());
  EXPECT_TRUE(GetWebContentCaptureClient()->RemovedData().empty());
  EXPECT_EQ(GetExpectedSecondResultSize(),
            GetWebContentCaptureClient()->Data().size());
}

TEST_P(ContentCaptureTest, NodeOnlySendOnce) {
  // Send all nodes
  RunContentCaptureTask();
  EXPECT_FALSE(GetWebContentCaptureClient()->Data().empty());
  EXPECT_EQ(GetExpectedSecondResultSize(),
            GetWebContentCaptureClient()->Data().size());

  GetContentCaptureManager()->OnScrollPositionChanged();
  RunContentCaptureTask();
  EXPECT_TRUE(GetWebContentCaptureClient()->Data().empty());
  EXPECT_TRUE(GetWebContentCaptureClient()->RemovedData().empty());
}

TEST_P(ContentCaptureTest, UnsentNode) {
  // Send all nodes expect |invisible_node_|.
  RunContentCaptureTask();
  EXPECT_FALSE(GetWebContentCaptureClient()->Data().empty());
  EXPECT_EQ(GetExpectedSecondResultSize(),
            GetWebContentCaptureClient()->Data().size());

  // Simulates the |invisible_node_| being changed, and verifies no content
  // change because |invisible_node_| wasn't captured.
  GetContentCaptureManager()->OnNodeTextChanged(invisible_node());
  RunContentCaptureTask();
  EXPECT_TRUE(GetWebContentCaptureClient()->Data().empty());
  EXPECT_TRUE(GetWebContentCaptureClient()->UpdatedData().empty());
  EXPECT_TRUE(GetWebContentCaptureClient()->RemovedData().empty());

  // Simulates the |invisible_node_| being removed, and verifies no content
  // change because |invisible_node_| wasn't captured.
  GetContentCaptureManager()->OnLayoutTextWillBeDestroyed(invisible_node());
  RunContentCaptureTask();
  EXPECT_TRUE(GetWebContentCaptureClient()->Data().empty());
  EXPECT_TRUE(GetWebContentCaptureClient()->UpdatedData().empty());
  EXPECT_TRUE(GetWebContentCaptureClient()->RemovedData().empty());
}

TEST_P(ContentCaptureTest, RemoveNodeBeforeSendingOut) {
  // Capture the content, but didn't send them.
  GetContentCaptureTask()->SetTaskStopState(
      ContentCaptureTask::TaskState::kProcessCurrentSession);
  RunContentCaptureTask();
  EXPECT_TRUE(GetWebContentCaptureClient()->Data().empty());

  // Remove the node and sent the captured content out.
  RemoveNode(Nodes().at(0));
  GetContentCaptureTask()->SetTaskStopState(
      ContentCaptureTask::TaskState::kProcessRetryTask);
  RunContentCaptureTask();
  EXPECT_EQ(GetExpectedFirstResultSize(),
            GetWebContentCaptureClient()->Data().size());
  EXPECT_EQ(0u, GetWebContentCaptureClient()->RemovedData().size());
  RunContentCaptureTask();
  // Total 7 content returned instead of 8.
  EXPECT_EQ(GetExpectedSecondResultSize() - 1,
            GetWebContentCaptureClient()->Data().size());
  EXPECT_EQ(0u, GetWebContentCaptureClient()->RemovedData().size());
  RunContentCaptureTask();
  // No removed node because it hasn't been sent out.
  EXPECT_EQ(0u, GetWebContentCaptureClient()->Data().size());
  EXPECT_EQ(0u, GetWebContentCaptureClient()->RemovedData().size());
}

TEST_P(ContentCaptureTest, RemoveNodeInBetweenSendingOut) {
  // Capture the content, but didn't send them.
  GetContentCaptureTask()->SetTaskStopState(
      ContentCaptureTask::TaskState::kProcessCurrentSession);
  RunContentCaptureTask();
  EXPECT_TRUE(GetWebContentCaptureClient()->Data().empty());

  // Sends first batch.
  GetContentCaptureTask()->SetTaskStopState(
      ContentCaptureTask::TaskState::kProcessRetryTask);
  RunContentCaptureTask();
  EXPECT_EQ(GetExpectedFirstResultSize(),
            GetWebContentCaptureClient()->Data().size());
  EXPECT_EQ(0u, GetWebContentCaptureClient()->RemovedData().size());

  // This relies on each node to have different value.
  RemoveUnsentNode(GetWebContentCaptureClient()->Data());
  GetContentCaptureTask()->SetTaskStopState(
      ContentCaptureTask::TaskState::kProcessRetryTask);
  RunContentCaptureTask();
  // Total 7 content returned instead of 8.
  EXPECT_EQ(GetExpectedSecondResultSize() - 1,
            GetWebContentCaptureClient()->Data().size());
  EXPECT_EQ(0u, GetWebContentCaptureClient()->RemovedData().size());
  RunContentCaptureTask();
  // No removed node because it hasn't been sent out.
  EXPECT_EQ(0u, GetWebContentCaptureClient()->Data().size());
  EXPECT_EQ(0u, GetWebContentCaptureClient()->RemovedData().size());
}

TEST_P(ContentCaptureTest, RemoveNodeAfterSendingOut) {
  // Captures the content, but didn't send them.
  GetContentCaptureTask()->SetTaskStopState(
      ContentCaptureTask::TaskState::kProcessCurrentSession);
  RunContentCaptureTask();
  EXPECT_TRUE(GetWebContentCaptureClient()->Data().empty());

  // Sends first batch.
  GetContentCaptureTask()->SetTaskStopState(
      ContentCaptureTask::TaskState::kProcessRetryTask);
  RunContentCaptureTask();
  EXPECT_EQ(GetExpectedFirstResultSize(),
            GetWebContentCaptureClient()->Data().size());
  EXPECT_EQ(0u, GetWebContentCaptureClient()->RemovedData().size());

  // Sends second batch.
  RunContentCaptureTask();
  EXPECT_EQ(GetExpectedSecondResultSize(),
            GetWebContentCaptureClient()->Data().size());
  EXPECT_EQ(0u, GetWebContentCaptureClient()->RemovedData().size());

  // Remove the node.
  RemoveNode(Nodes().at(0));
  RunLongDelayContentCaptureTask();
  EXPECT_EQ(0u, GetWebContentCaptureClient()->Data().size());
  EXPECT_EQ(1u, GetWebContentCaptureClient()->RemovedData().size());
}

TEST_P(ContentCaptureTest, TaskHistogramReporter) {
  // This performs gc for all DocumentSession, flushes the existing
  // SentContentCount and give a clean baseline for histograms.
  // We are not sure if it always work, maybe still be the source of flaky.
  ThreadState::Current()->CollectAllGarbageForTesting();
  base::HistogramTester histograms;

  // The task stops before captures content.
  GetContentCaptureTask()->SetTaskStopState(
      ContentCaptureTask::TaskState::kCaptureContent);
  RunContentCaptureTask();
  // Verify no histogram reported yet.
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kCaptureContentTime, 0u);
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kSendContentTime, 0u);
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kCaptureContentDelayTime, 0u);
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kSentContentCount, 0u);
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kTaskRunsPerCapture, 0u);
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kTaskDelayInMs, 1u);

  // The task stops before sends the captured content out.
  GetContentCaptureTask()->SetTaskStopState(
      ContentCaptureTask::TaskState::kProcessCurrentSession);
  RunContentCaptureTask();
  // Verify has one CaptureContentTime record.
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kCaptureContentTime, 1u);
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kSendContentTime, 0u);
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kCaptureContentDelayTime, 0u);
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kSentContentCount, 0u);

  // The task stops at kProcessRetryTask because the captured content
  // needs to be sent with 2 batch.
  GetContentCaptureTask()->SetTaskStopState(
      ContentCaptureTask::TaskState::kProcessRetryTask);
  RunContentCaptureTask();
  // Verify has one CaptureContentTime, one SendContentTime and one
  // CaptureContentDelayTime record.
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kCaptureContentTime, 1u);
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kSendContentTime, 1u);
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kCaptureContentDelayTime, 1u);
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kSentContentCount, 0u);

  // Run task until it stops, task will not capture content, because there is no
  // content change.
  GetContentCaptureTask()->SetTaskStopState(
      ContentCaptureTask::TaskState::kStop);
  RunContentCaptureTask();
  // Verify has two SendContentTime records.
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kCaptureContentTime, 1u);
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kSendContentTime, 2u);
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kCaptureContentDelayTime, 1u);
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kSentContentCount, 0u);

  // Verify retry task won't count to TaskDelay metrics.
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kTaskDelayInMs, 1u);

  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kTaskRunsPerCapture, 1u);
  // Verify the task ran 4 times, first run stopped before capturing content
  // and 2nd run captured content, 3rd and 4th run sent the content out.
  histograms.ExpectBucketCount(
      ContentCaptureTaskHistogramReporter::kTaskRunsPerCapture, 4u, 1u);

  // Create a node and run task until it stops.
  CreateTextNodeAndNotifyManager();
  GetContentCaptureTask()->SetTaskStopState(
      ContentCaptureTask::TaskState::kStop);
  RunLongDelayContentCaptureTask();
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kCaptureContentTime, 2u);
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kSendContentTime, 3u);
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kCaptureContentDelayTime, 2u);
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kSentContentCount, 0u);

  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kTaskRunsPerCapture, 2u);
  // Verify the task ran 1 times for this session because we didn't explicitly
  // stop it.
  histograms.ExpectBucketCount(
      ContentCaptureTaskHistogramReporter::kTaskRunsPerCapture, 1u, 1u);

  GetContentCaptureTask()->ClearDocumentSessionsForTesting();
  ThreadState::Current()->CollectAllGarbageForTesting();
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kCaptureContentTime, 2u);
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kSendContentTime, 3u);
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kCaptureContentDelayTime, 2u);
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kSentContentCount, 1u);
  // Verify total content has been sent.
  histograms.ExpectBucketCount(
      ContentCaptureTaskHistogramReporter::kSentContentCount, 9u, 1u);

  // Verify TaskDelay was recorded again for node change.
  histograms.ExpectTotalCount(
      ContentCaptureTaskHistogramReporter::kTaskDelayInMs, 2u);
}

TEST_P(ContentCaptureTest, RescheduleTask) {
  // This test assumes test runs much faster than task's long delay which is 5s.
  Persistent<ContentCaptureTaskTestHelper> task = GetContentCaptureTask();
  task->CancelTaskForTesting();
  EXPECT_TRUE(task->GetTaskNextFireIntervalForTesting().is_zero());
  task->Schedule(
      ContentCaptureTask::ScheduleReason::kNonUserActivatedContentChange);
  auto begin = base::TimeTicks::Now();
  base::TimeDelta interval1 = task->GetTaskNextFireIntervalForTesting();
  task->Schedule(ContentCaptureTask::ScheduleReason::kScrolling);
  base::TimeDelta interval2 = task->GetTaskNextFireIntervalForTesting();
  auto test_running_time = base::TimeTicks::Now() - begin;
  if (base::FeatureList::IsEnabled(
          features::kContentCaptureUserActivatedDelay)) {
    // The first scheduled task is always shortest even though caused by
    // NonUserTriggered.
    EXPECT_LE(interval1, GetWebContentCaptureClient()->GetTaskShortDelay());
    EXPECT_LE(interval2, interval1);
  } else {
    // The interval1 will be greater than interval2 even the task wasn't
    // rescheduled, removing the test_running_time from interval1 make sure
    // task rescheduled.
    EXPECT_GT(interval1 - test_running_time, interval2);
  }
}

TEST_P(ContentCaptureTest, NotRescheduleTask) {
  // This test assumes test runs much faster than task's long delay which is 5s.
  Persistent<ContentCaptureTaskTestHelper> task = GetContentCaptureTask();
  task->CancelTaskForTesting();
  EXPECT_TRUE(task->GetTaskNextFireIntervalForTesting().is_zero());
  task->Schedule(
      ContentCaptureTask::ScheduleReason::kNonUserActivatedContentChange);
  auto begin = base::TimeTicks::Now();
  base::TimeDelta interval1 = task->GetTaskNextFireIntervalForTesting();
  task->Schedule(
      ContentCaptureTask::ScheduleReason::kNonUserActivatedContentChange);
  base::TimeDelta interval2 = task->GetTaskNextFireIntervalForTesting();
  auto test_running_time = base::TimeTicks::Now() - begin;
  EXPECT_GE(interval1, interval2);
  EXPECT_LE(interval1 - test_running_time, interval2);
}

// TODO(michaelbai): use RenderingTest instead of PageTestBase for multiple
// frame test.
class ContentCaptureSimTest : public SimTest {
 public:
  static const char* kEditableContent;

  ContentCaptureSimTest() : client_(), child_client_() {}
  void SetUp() override {
    SimTest::SetUp();
    MainFrame().SetContentCaptureClient(&client_);
    SetupPage();
  }

  void RunContentCaptureTaskUntil(ContentCaptureTask::TaskState state) {
    Client().ResetResults();
    ChildClient().ResetResults();
    GetDocument()
        .GetFrame()
        ->LocalFrameRoot()
        .GetContentCaptureManager()
        ->GetContentCaptureTaskForTesting()
        ->RunTaskForTestingUntil(state);
    // Cancels the scheduled task to simulate that the task is running by
    // scheduler.
    GetContentCaptureManager()
        ->GetContentCaptureTaskForTesting()
        ->CancelTaskForTesting();
  }

  WebContentCaptureClientTestHelper& Client() { return client_; }
  WebContentCaptureClientTestHelper& ChildClient() { return child_client_; }

  enum class ContentType { kAll, kMainFrame, kChildFrame };
  void SetCapturedContent(ContentType type) {
    if (type == ContentType::kMainFrame) {
      SetCapturedContent(main_frame_content_);
    } else if (type == ContentType::kChildFrame) {
      SetCapturedContent(child_frame_content_);
    } else if (type == ContentType::kAll) {
      Vector<cc::NodeInfo> holders(main_frame_content_);
      holders.AppendRange(child_frame_content_.begin(),
                          child_frame_content_.end());
      SetCapturedContent(holders);
    }
  }

  void AddOneNodeToMainFrame() {
    AddNodeToDocument(GetDocument(), main_frame_content_);
    main_frame_expected_text_.push_back("New Text");
  }

  void AddOneNodeToChildFrame() {
    AddNodeToDocument(*child_document_, child_frame_content_);
    child_frame_expected_text_.push_back("New Text");
  }

  void InsertMainFrameEditableContent(const std::string& content,
                                      unsigned offset) {
    InsertNodeContent(GetDocument(), "editable_id", content, offset);
  }

  void DeleteMainFrameEditableContent(unsigned offset, unsigned length) {
    DeleteNodeContent(GetDocument(), "editable_id", offset, length);
  }

  const Vector<std::string>& MainFrameExpectedText() const {
    return main_frame_expected_text_;
  }

  const Vector<std::string>& ChildFrameExpectedText() const {
    return child_frame_expected_text_;
  }

  void ReplaceMainFrameExpectedText(const std::string& old_text,
                                    const std::string& new_text) {
    std::replace(main_frame_expected_text_.begin(),
                 main_frame_expected_text_.end(), old_text, new_text);
  }

  ContentCaptureManager* GetContentCaptureManager() {
    return DynamicTo<LocalFrame>(LocalFrameRoot().GetFrame())
        ->GetContentCaptureManager();
  }

  void SimulateUserInputOnMainFrame() {
    GetContentCaptureManager()->NotifyInputEvent(
        WebInputEvent::Type::kMouseDown,
        *DynamicTo<LocalFrame>(MainFrame().GetFrame()));
  }

  void SimulateUserInputOnChildFrame() {
    GetContentCaptureManager()->NotifyInputEvent(
        WebInputEvent::Type::kMouseDown, *child_document_->GetFrame());
  }

  base::TimeDelta GetNextTaskDelay() {
    return GetContentCaptureManager()
        ->GetContentCaptureTaskForTesting()
        ->GetTaskDelayForTesting()
        .GetNextTaskDelay();
  }

  base::TimeDelta GetTaskNextFireInterval() {
    return GetContentCaptureManager()
        ->GetContentCaptureTaskForTesting()
        ->GetTaskNextFireIntervalForTesting();
  }

 private:
  void SetupPage() {
    SimRequest main_resource("https://example.com/test.html", "text/html");
    SimRequest frame_resource("https://example.com/frame.html", "text/html");
    LoadURL("https://example.com/test.html");
    WebView().MainFrameViewWidget()->Resize(gfx::Size(800, 6000));
    main_resource.Complete(R"HTML(
      <!DOCTYPE html>
      <body style='background: white'>
      <iframe id=frame name='frame' src=frame.html></iframe>
      <p id='p1'>Hello World1</p>
      <p id='p2'>Hello World2</p>
      <p id='p3'>Hello World3</p>
      <p id='p4'>Hello World4</p>
      <p id='p5'>Hello World5</p>
      <p id='p6'>Hello World6</p>
      <p id='p7'>Hello World7</p>
      <div id='editable_id'>editable</div>
      <svg>
      <text id="s8">Hello World8</text>
      </svg>
      <div id='d1'></div>
      )HTML");
    auto frame1 = Compositor().BeginFrame();
    frame_resource.Complete(R"HTML(
      <!DOCTYPE html>
      <p id='c1'>Hello World11</p>
      <p id='c2'>Hello World12</p>
      <div id='d1'></div>
      )HTML");

    static_cast<WebLocalFrame*>(MainFrame().FindFrameByName("frame"))
        ->SetContentCaptureClient(&child_client_);
    auto* child_frame_element =
        To<HTMLIFrameElement>(GetDocument().getElementById("frame"));
    child_document_ = child_frame_element->contentDocument();
    child_document_->UpdateStyleAndLayout(DocumentUpdateReason::kTest);
    Compositor().BeginFrame();
    InitMainFrameNodeHolders();
    InitChildFrameNodeHolders(*child_document_);
  }

  void InitMainFrameNodeHolders() {
    Vector<std::string> ids = {"p1", "p2", "p3", "p4",         "p5",
                               "p6", "p7", "s8", "editable_id"};
    main_frame_expected_text_ = {
        "Hello World1", "Hello World2", "Hello World3",
        "Hello World4", "Hello World5", "Hello World6",
        "Hello World7", "Hello World8", kEditableContent};
    InitNodeHolders(main_frame_content_, ids, GetDocument());
    EXPECT_EQ(9u, main_frame_content_.size());
  }

  void InitChildFrameNodeHolders(const Document& doc) {
    Vector<std::string> ids = {"c1", "c2"};
    child_frame_expected_text_ = {"Hello World11", "Hello World12"};
    InitNodeHolders(child_frame_content_, ids, doc);
    EXPECT_EQ(2u, child_frame_content_.size());
  }

  void InitNodeHolders(Vector<cc::NodeInfo>& buffer,
                       const Vector<std::string>& ids,
                       const Document& document) {
    for (auto id : ids) {
      auto* layout_object =
          document.getElementById(id.c_str())->firstChild()->GetLayoutObject();
      auto* layout_text = To<LayoutText>(layout_object);
      EXPECT_TRUE(layout_text->HasNodeId());
      buffer.push_back(
          cc::NodeInfo(layout_text->EnsureNodeId(), GetRect(layout_object)));
    }
  }

  void AddNodeToDocument(Document& doc, Vector<cc::NodeInfo>& buffer) {
    Node* node = doc.createTextNode("New Text");
    auto* element = MakeGarbageCollected<Element>(html_names::kPTag, &doc);
    element->appendChild(node);
    Element* div_element = doc.getElementById("d1");
    div_element->appendChild(element);
    Compositor().BeginFrame();
    auto* layout_text = To<LayoutText>(node->GetLayoutObject());
    EXPECT_TRUE(layout_text->HasNodeId());
    buffer.push_back(cc::NodeInfo(layout_text->EnsureNodeId(),
                                  GetRect(node->GetLayoutObject())));
  }

  void InsertNodeContent(Document& doc,
                         const std::string& id,
                         const std::string& content,
                         unsigned offset) {
    To<Text>(doc.getElementById(id.c_str())->firstChild())
        ->insertData(offset, String(content.c_str()),
                     IGNORE_EXCEPTION_FOR_TESTING);
    Compositor().BeginFrame();
  }

  void DeleteNodeContent(Document& doc,
                         const std::string& id,
                         unsigned offset,
                         unsigned length) {
    To<Text>(doc.getElementById(id.c_str())->firstChild())
        ->deleteData(offset, length, IGNORE_EXCEPTION_FOR_TESTING);
    Compositor().BeginFrame();
  }

  void SetCapturedContent(const Vector<cc::NodeInfo>& captured_content) {
    GetDocument()
        .GetFrame()
        ->LocalFrameRoot()
        .GetContentCaptureManager()
        ->GetContentCaptureTaskForTesting()
        ->SetCapturedContentForTesting(captured_content);
  }

  Vector<std::string> main_frame_expected_text_;
  Vector<std::string> child_frame_expected_text_;
  Vector<cc::NodeInfo> main_frame_content_;
  Vector<cc::NodeInfo> child_frame_content_;
  WebContentCaptureClientTestHelper client_;
  WebContentCaptureClientTestHelper child_client_;
  Persistent<Document> child_document_;
};

const char* ContentCaptureSimTest::kEditableContent = "editable";

TEST_F(ContentCaptureSimTest, MultiFrame) {
  SetCapturedContent(ContentType::kAll);
  RunContentCaptureTaskUntil(ContentCaptureTask::TaskState::kStop);
  EXPECT_EQ(4u, Client().Data().size());
  EXPECT_EQ(2u, ChildClient().Data().size());
  EXPECT_THAT(Client().AllText(),
              testing::UnorderedElementsAreArray(MainFrameExpectedText()));
  EXPECT_THAT(ChildClient().AllText(),
              testing::UnorderedElementsAreArray(ChildFrameExpectedText()));
}

TEST_F(ContentCaptureSimTest, AddNodeToMultiFrame) {
  SetCapturedContent(ContentType::kMainFrame);
  // Stops after capturing content.
  RunContentCaptureTaskUntil(
      ContentCaptureTask::TaskState::kProcessCurrentSession);
  EXPECT_TRUE(Client().Data().empty());
  EXPECT_FALSE(Client().FirstData());
  EXPECT_TRUE(ChildClient().Data().empty());

  // Sends the first batch data.
  RunContentCaptureTaskUntil(ContentCaptureTask::TaskState::kProcessRetryTask);
  EXPECT_EQ(5u, Client().Data().size());
  EXPECT_TRUE(Client().FirstData());
  EXPECT_TRUE(ChildClient().Data().empty());

  // Sends the reset of data
  RunContentCaptureTaskUntil(ContentCaptureTask::TaskState::kProcessRetryTask);
  EXPECT_EQ(4u, Client().Data().size());
  EXPECT_FALSE(Client().FirstData());
  EXPECT_TRUE(ChildClient().Data().empty());
  EXPECT_THAT(Client().AllText(),
              testing::UnorderedElementsAreArray(MainFrameExpectedText()));

  AddOneNodeToMainFrame();
  SetCapturedContent(ContentType::kMainFrame);
  RunContentCaptureTaskUntil(ContentCaptureTask::TaskState::kStop);
  // Though returns all main frame content, only new added node is unsent.
  EXPECT_EQ(1u, Client().Data().size());
  EXPECT_FALSE(Client().FirstData());
  EXPECT_TRUE(ChildClient().Data().empty());
  EXPECT_THAT(Client().AllText(),
              testing::UnorderedElementsAreArray(MainFrameExpectedText()));

  AddOneNodeToChildFrame();
  SetCapturedContent(ContentType::kChildFrame);
  RunContentCaptureTaskUntil(ContentCaptureTask::TaskState::kStop);
  EXPECT_EQ(3u, ChildClient().Data().size());
  EXPECT_THAT(ChildClient().AllText(),
              testing::UnorderedElementsAreArray(ChildFrameExpectedText()));
  EXPECT_TRUE(ChildClient().FirstData());
}

TEST_F(ContentCaptureSimTest, ChangeNode) {
  SetCapturedContent(ContentType::kMainFrame);
  RunContentCaptureTaskUntil(ContentCaptureTask::TaskState::kStop);
  EXPECT_EQ(4u, Client().Data().size());
  EXPECT_FALSE(Client().FirstData());
  EXPECT_TRUE(ChildClient().Data().empty());
  EXPECT_THAT(Client().AllText(),
              testing::UnorderedElementsAreArray(MainFrameExpectedText()));
  Vector<std::string> expected_text_update;
  std::string insert_text = "content ";

  // Changed content to 'content editable'.
  InsertMainFrameEditableContent(insert_text, 0);
  SetCapturedContent(ContentType::kMainFrame);
  RunContentCaptureTaskUntil(ContentCaptureTask::TaskState::kStop);
  EXPECT_EQ(1u, Client().UpdatedData().size());
  EXPECT_FALSE(Client().FirstData());
  EXPECT_TRUE(ChildClient().Data().empty());
  expected_text_update.push_back(insert_text + kEditableContent);
  EXPECT_THAT(Client().UpdatedText(),
              testing::UnorderedElementsAreArray(expected_text_update));

  // Changing content multiple times before capturing.
  std::string insert_text1 = "i";
  // Changed content to 'content ieditable'.
  InsertMainFrameEditableContent(insert_text1, insert_text.size());
  std::string insert_text2 = "s ";
  // Changed content to 'content is editable'.
  InsertMainFrameEditableContent(insert_text2,
                                 insert_text.size() + insert_text1.size());

  SetCapturedContent(ContentType::kMainFrame);
  RunContentCaptureTaskUntil(ContentCaptureTask::TaskState::kStop);
  EXPECT_EQ(1u, Client().UpdatedData().size());
  EXPECT_FALSE(Client().FirstData());
  EXPECT_TRUE(ChildClient().Data().empty());
  expected_text_update.push_back(insert_text + insert_text1 + insert_text2 +
                                 kEditableContent);
  EXPECT_THAT(Client().UpdatedText(),
              testing::UnorderedElementsAreArray(expected_text_update));
}

TEST_F(ContentCaptureSimTest, ChangeNodeBeforeCapture) {
  // Changed content to 'content editable' before capture.
  std::string insert_text = "content ";
  InsertMainFrameEditableContent(insert_text, 0);
  // Changing content multiple times before capturing.
  std::string insert_text1 = "i";
  // Changed content to 'content ieditable'.
  InsertMainFrameEditableContent(insert_text1, insert_text.size());
  std::string insert_text2 = "s ";
  // Changed content to 'content is editable'.
  InsertMainFrameEditableContent(insert_text2,
                                 insert_text.size() + insert_text1.size());

  // The changed content shall be captured as new content.
  ReplaceMainFrameExpectedText(
      kEditableContent,
      insert_text + insert_text1 + insert_text2 + kEditableContent);
  SetCapturedContent(ContentType::kMainFrame);
  RunContentCaptureTaskUntil(ContentCaptureTask::TaskState::kStop);
  EXPECT_EQ(4u, Client().Data().size());
  EXPECT_FALSE(Client().FirstData());
  EXPECT_TRUE(ChildClient().Data().empty());
  EXPECT_TRUE(ChildClient().UpdatedData().empty());
  EXPECT_THAT(Client().AllText(),
              testing::UnorderedElementsAreArray(MainFrameExpectedText()));
}

TEST_F(ContentCaptureSimTest, DeleteNodeContent) {
  SetCapturedContent(ContentType::kMainFrame);
  RunContentCaptureTaskUntil(ContentCaptureTask::TaskState::kStop);
  EXPECT_EQ(4u, Client().Data().size());
  EXPECT_FALSE(Client().FirstData());
  EXPECT_TRUE(ChildClient().Data().empty());
  EXPECT_THAT(Client().AllText(),
              testing::UnorderedElementsAreArray(MainFrameExpectedText()));

  // Deleted 4 char, changed content to 'edit'.
  DeleteMainFrameEditableContent(4, 4);
  SetCapturedContent(ContentType::kMainFrame);
  RunContentCaptureTaskUntil(ContentCaptureTask::TaskState::kStop);
  EXPECT_EQ(1u, Client().UpdatedData().size());
  EXPECT_FALSE(Client().FirstData());
  EXPECT_TRUE(ChildClient().Data().empty());
  Vector<std::string> expected_text_update;
  expected_text_update.push_back("edit");
  EXPECT_THAT(Client().UpdatedText(),
              testing::UnorderedElementsAreArray(expected_text_update));

  // Emptied content, the node shall be removed.
  DeleteMainFrameEditableContent(0, 4);
  SetCapturedContent(ContentType::kMainFrame);
  RunContentCaptureTaskUntil(ContentCaptureTask::TaskState::kStop);
  EXPECT_TRUE(Client().UpdatedData().empty());
  EXPECT_FALSE(Client().FirstData());
  EXPECT_TRUE(ChildClient().Data().empty());
  EXPECT_EQ(1u, Client().RemovedData().size());
}

TEST_F(ContentCaptureSimTest, UserActivatedDelay) {
  base::TimeDelta expected_delays[] = {
      base::TimeDelta::FromMilliseconds(500), base::TimeDelta::FromSeconds(1),
      base::TimeDelta::FromSeconds(2),        base::TimeDelta::FromSeconds(4),
      base::TimeDelta::FromSeconds(8),        base::TimeDelta::FromSeconds(16),
      base::TimeDelta::FromSeconds(32),       base::TimeDelta::FromSeconds(64),
      base::TimeDelta::FromSeconds(128)};
  size_t expected_delays_size = base::size(expected_delays);

  base::test::ScopedFeatureList user_activated_delay;
  user_activated_delay.InitAndEnableFeature(
      features::kContentCaptureUserActivatedDelay);
  // The first task has been scheduled but not run yet, the delay will be
  // increased until current task starts to run. Verifies the value is
  // unchanged.
  EXPECT_EQ(expected_delays[0], GetNextTaskDelay());
  // Settles the initial task.
  RunContentCaptureTaskUntil(ContentCaptureTask::TaskState::kStop);

  for (size_t i = 1; i < expected_delays_size; ++i) {
    EXPECT_EQ(expected_delays[i], GetNextTaskDelay());
    // Add a node to schedule the task.
    AddOneNodeToMainFrame();
    auto scheduled_interval = GetTaskNextFireInterval();
    EXPECT_GE(expected_delays[i], scheduled_interval);
    EXPECT_LT(expected_delays[i - 1], scheduled_interval);
    RunContentCaptureTaskUntil(ContentCaptureTask::TaskState::kStop);
  }

  // Verifies the delay is up to 128s.
  AddOneNodeToMainFrame();
  EXPECT_EQ(expected_delays[expected_delays_size - 1], GetNextTaskDelay());
  auto scheduled_interval = GetTaskNextFireInterval();
  EXPECT_GE(expected_delays[expected_delays_size - 1], scheduled_interval);
  EXPECT_LT(expected_delays[expected_delays_size - 2], scheduled_interval);
  RunContentCaptureTaskUntil(ContentCaptureTask::TaskState::kStop);

  // Verifies the user activated change will reset the delay.
  SimulateUserInputOnMainFrame();
  AddOneNodeToMainFrame();
  EXPECT_EQ(expected_delays[0], GetNextTaskDelay());
  scheduled_interval = GetTaskNextFireInterval();
  EXPECT_GE(expected_delays[0], scheduled_interval);

  // Verifies the multiple changes won't reschedule the task.
  AddOneNodeToMainFrame();
  EXPECT_GE(scheduled_interval, GetTaskNextFireInterval());

  RunContentCaptureTaskUntil(ContentCaptureTask::TaskState::kStop);

  // Overrides the main frame's user activation, and verify the child one won't
  // effect the main frame.
  SimulateUserInputOnChildFrame();
  AddOneNodeToMainFrame();
  // Verifies the delay time become one step longer since no user activation was
  // override by child frame's.
  EXPECT_EQ(expected_delays[1], GetNextTaskDelay());
  scheduled_interval = GetTaskNextFireInterval();
  EXPECT_GE(expected_delays[1], scheduled_interval);
  EXPECT_LT(expected_delays[0], scheduled_interval);
}

}  // namespace blink
