// Copyright 2017 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 "headless/public/util/compositor_controller.h"

#include <memory>

#include "base/base64.h"
#include "base/bind.h"
#include "base/json/json_writer.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/test/test_simple_task_runner.h"
#include "headless/public/internal/headless_devtools_client_impl.h"
#include "headless/public/util/testing/mock_devtools_agent_host.h"
#include "headless/public/util/virtual_time_controller.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace headless {

namespace {
static constexpr base::TimeDelta kAnimationFrameInterval =
    base::TimeDelta::FromMilliseconds(16);
static constexpr base::TimeDelta kWaitForCompositorReadyFrameDelay =
    base::TimeDelta::FromMilliseconds(20);
} // namespace

using testing::Return;
using testing::_;

class TestVirtualTimeController : public VirtualTimeController {
 public:
  TestVirtualTimeController(HeadlessDevToolsClient* devtools_client)
      : VirtualTimeController(devtools_client) {}
  ~TestVirtualTimeController() override = default;

  MOCK_METHOD0(StartVirtualTime, void());
  MOCK_METHOD2(ScheduleRepeatingTask,
               void(RepeatingTask* task, base::TimeDelta interval));
  MOCK_METHOD1(CancelRepeatingTask, void(RepeatingTask* task));
  MOCK_METHOD1(AddObserver, void(Observer* observer));
  MOCK_METHOD1(RemoveObserver, void(Observer* observer));
  MOCK_METHOD1(SetStartDeferrer, void(StartDeferrer* deferrer));

  MOCK_CONST_METHOD0(GetVirtualTimeBase, base::Time());
  MOCK_CONST_METHOD0(GetCurrentVirtualTimeOffset, base::TimeDelta());
};

class CompositorControllerTest : public ::testing::Test {
 protected:
  CompositorControllerTest(bool update_display_for_animations = true) {
    task_runner_ = base::MakeRefCounted<base::TestSimpleTaskRunner>();
    client_.SetTaskRunnerForTests(task_runner_);
    mock_host_ = base::MakeRefCounted<MockDevToolsAgentHost>();

    EXPECT_CALL(*mock_host_, IsAttached()).WillOnce(Return(false));
    EXPECT_CALL(*mock_host_, AttachClient(&client_));
    client_.AttachToHost(mock_host_.get());
    virtual_time_controller_ =
        std::make_unique<TestVirtualTimeController>(&client_);
    EXPECT_CALL(*virtual_time_controller_,
                ScheduleRepeatingTask(_, kAnimationFrameInterval))
        .WillOnce(testing::SaveArg<0>(&task_));
    EXPECT_CALL(*virtual_time_controller_, AddObserver(_))
        .WillOnce(testing::SaveArg<0>(&observer_));
    EXPECT_CALL(*virtual_time_controller_, SetStartDeferrer(_))
        .WillOnce(testing::SaveArg<0>(&deferer_));
    ExpectHeadlessExperimentalEnable();
    controller_ = std::make_unique<CompositorController>(
        task_runner_, &client_, virtual_time_controller_.get(),
        kAnimationFrameInterval, kWaitForCompositorReadyFrameDelay,
        update_display_for_animations);
    EXPECT_NE(nullptr, task_);
  }

  ~CompositorControllerTest() override {
    EXPECT_CALL(*virtual_time_controller_, RemoveObserver(_));
    EXPECT_CALL(*virtual_time_controller_, CancelRepeatingTask(_));
    EXPECT_CALL(*virtual_time_controller_, SetStartDeferrer(_));
  }

  void ExpectHeadlessExperimentalEnable() {
    last_command_id_ += 2;
    EXPECT_CALL(*mock_host_,
                DispatchProtocolMessage(
                    &client_,
                    base::StringPrintf(
                        "{\"id\":%d,\"method\":\"HeadlessExperimental.enable\","
                        "\"params\":{}}",
                        last_command_id_)))
        .WillOnce(Return(true));
  }

  void ExpectVirtualTime(double base, double offset) {
    auto base_time = base::Time::FromJsTime(base);
    auto offset_delta = base::TimeDelta::FromMilliseconds(offset);
    EXPECT_CALL(*virtual_time_controller_, GetVirtualTimeBase())
        .WillOnce(Return(base_time));
    EXPECT_CALL(*virtual_time_controller_, GetCurrentVirtualTimeOffset())
        .WillOnce(Return(offset_delta));

    // Next BeginFrame's time should be the virtual time provided it has
    // progressed.
    base::Time virtual_time = base_time + offset_delta;
    if (virtual_time > next_begin_frame_time_)
      next_begin_frame_time_ = virtual_time;
  }

  void ExpectBeginFrame(bool no_display_updates = false,
                        std::unique_ptr<headless_experimental::ScreenshotParams>
                            screenshot_params = nullptr) {
    last_command_id_ += 2;
    base::DictionaryValue params;
    auto builder =
        std::move(headless_experimental::BeginFrameParams::Builder()
                      .SetFrameTime(next_begin_frame_time_.ToJsTime())
                      .SetInterval(kAnimationFrameInterval.InMillisecondsF())
                      .SetNoDisplayUpdates(no_display_updates));
    if (screenshot_params)
      builder.SetScreenshot(std::move(screenshot_params));
    // Subsequent BeginFrames should have a later timestamp.
    next_begin_frame_time_ += base::TimeDelta::FromMicroseconds(1);

    std::string params_json;
    auto params_value = builder.Build()->Serialize();
    base::JSONWriter::Write(*params_value, &params_json);

    EXPECT_CALL(
        *mock_host_,
        DispatchProtocolMessage(
            &client_,
            base::StringPrintf(
                "{\"id\":%d,\"method\":\"HeadlessExperimental.beginFrame\","
                "\"params\":%s}",
                last_command_id_, params_json.c_str())))
        .WillOnce(Return(true));
  }

  void SendBeginFrameReply(bool has_damage,
                           bool main_frame_content_updated,
                           const std::string& screenshot_data) {
    auto result = headless_experimental::BeginFrameResult::Builder()
                      .SetHasDamage(has_damage)
                      .SetMainFrameContentUpdated(main_frame_content_updated)
                      .Build();
    if (screenshot_data.length())
      result->SetScreenshotData(screenshot_data);
    std::string result_json;
    auto result_value = result->Serialize();
    base::JSONWriter::Write(*result_value, &result_json);

    client_.DispatchProtocolMessage(
        mock_host_.get(),
        base::StringPrintf("{\"id\":%d,\"result\":%s}", last_command_id_,
                           result_json.c_str()));
  }

  void SendNeedsBeginFramesEvent(bool needs_begin_frames) {
    client_.DispatchProtocolMessage(
        mock_host_.get(),
        base::StringPrintf("{\"method\":\"HeadlessExperimental."
                           "needsBeginFramesChanged\",\"params\":{"
                           "\"needsBeginFrames\":%s}}",
                           needs_begin_frames ? "true" : "false"));
    // Events are dispatched asynchronously.
    task_runner_->RunPendingTasks();
  }

  void SendMainFrameReadyForScreenshotsEvent() {
    client_.DispatchProtocolMessage(mock_host_.get(),
                                    "{\"method\":\"HeadlessExperimental."
                                    "mainFrameReadyForScreenshots\",\"params\":"
                                    "{}}");
    // Events are dispatched asynchronously.
    task_runner_->RunPendingTasks();
  }

  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
  scoped_refptr<MockDevToolsAgentHost> mock_host_;
  HeadlessDevToolsClientImpl client_;
  std::unique_ptr<TestVirtualTimeController> virtual_time_controller_;
  std::unique_ptr<CompositorController> controller_;
  int last_command_id_ = -2;
  TestVirtualTimeController::RepeatingTask* task_ = nullptr;
  TestVirtualTimeController::Observer* observer_ = nullptr;
  TestVirtualTimeController::StartDeferrer* deferer_ = nullptr;
  base::Time next_begin_frame_time_ =
      base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(1);
};

TEST_F(CompositorControllerTest, WaitForCompositorReady) {
  // Shouldn't send any commands yet as no needsBeginFrames event was sent yet.
  bool ready = false;
  controller_->WaitForCompositorReady(
      base::BindRepeating([](bool* ready) { *ready = true; }, &ready));
  EXPECT_FALSE(ready);

  // Sends BeginFrames with delay while they are needed.
  SendNeedsBeginFramesEvent(true);
  EXPECT_TRUE(task_runner_->HasPendingTask());
  ExpectVirtualTime(0, 0);
  ExpectBeginFrame();
  task_runner_->RunPendingTasks();

  SendBeginFrameReply(true, false, std::string());

  EXPECT_TRUE(task_runner_->HasPendingTask());
  EXPECT_EQ(kWaitForCompositorReadyFrameDelay,
            task_runner_->NextPendingTaskDelay());
  ExpectVirtualTime(0, 0);
  ExpectBeginFrame();
  task_runner_->RunPendingTasks();

  EXPECT_FALSE(task_runner_->HasPendingTask());

  SendBeginFrameReply(false, false, std::string());

  EXPECT_TRUE(task_runner_->HasPendingTask());
  EXPECT_EQ(kWaitForCompositorReadyFrameDelay,
            task_runner_->NextPendingTaskDelay());
  ExpectVirtualTime(0, 0);
  ExpectBeginFrame();
  task_runner_->RunPendingTasks();

  // No new BeginFrames are scheduled when BeginFrames are not needed.
  SendNeedsBeginFramesEvent(false);
  EXPECT_FALSE(task_runner_->HasPendingTask());

  SendBeginFrameReply(false, false, std::string());
  EXPECT_FALSE(task_runner_->HasPendingTask());

  // Restarts sending BeginFrames when they are needed again.
  SendNeedsBeginFramesEvent(true);
  EXPECT_TRUE(task_runner_->HasPendingTask());
  ExpectVirtualTime(0, 0);
  ExpectBeginFrame();
  task_runner_->RunPendingTasks();

  // Stops sending BeginFrames when main frame becomes ready.
  SendMainFrameReadyForScreenshotsEvent();
  EXPECT_FALSE(task_runner_->HasPendingTask());

  EXPECT_FALSE(ready);
  SendBeginFrameReply(true, true, std::string());
  EXPECT_FALSE(task_runner_->HasPendingTask());
  EXPECT_TRUE(ready);
}

TEST_F(CompositorControllerTest, CaptureScreenshot) {
  SendMainFrameReadyForScreenshotsEvent();
  EXPECT_FALSE(task_runner_->HasPendingTask());

  bool done = false;
  controller_->CaptureScreenshot(
      headless_experimental::ScreenshotParamsFormat::PNG, 100,
      base::BindRepeating(
          [](bool* done, const std::string& screenshot_data) {
            *done = true;
            EXPECT_EQ("test", screenshot_data);
          },
          &done));

  EXPECT_TRUE(task_runner_->HasPendingTask());
  ExpectVirtualTime(0, 0);
  ExpectBeginFrame(
      false, headless_experimental::ScreenshotParams::Builder()
                 .SetFormat(headless_experimental::ScreenshotParamsFormat::PNG)
                 .SetQuality(100)
                 .Build());
  task_runner_->RunPendingTasks();

  std::string base64;
  base::Base64Encode("test", &base64);
  SendBeginFrameReply(true, true, base64);
  EXPECT_FALSE(task_runner_->HasPendingTask());
  EXPECT_TRUE(done);
}

TEST_F(CompositorControllerTest, WaitForMainFrameContentUpdate) {
  bool updated = false;
  controller_->WaitForMainFrameContentUpdate(
      base::BindRepeating([](bool* updated) { *updated = true; }, &updated));
  EXPECT_FALSE(updated);

  // Sends BeginFrames while they are needed.
  SendNeedsBeginFramesEvent(true);
  EXPECT_TRUE(task_runner_->HasPendingTask());
  ExpectVirtualTime(0, 0);
  ExpectBeginFrame();
  task_runner_->RunPendingTasks();

  SendBeginFrameReply(true, false, std::string());

  EXPECT_TRUE(task_runner_->HasPendingTask());
  EXPECT_EQ(base::TimeDelta(), task_runner_->NextPendingTaskDelay());
  ExpectVirtualTime(0, 0);
  ExpectBeginFrame();
  task_runner_->RunPendingTasks();

  EXPECT_FALSE(task_runner_->HasPendingTask());

  SendBeginFrameReply(false, false, std::string());

  EXPECT_TRUE(task_runner_->HasPendingTask());
  EXPECT_EQ(base::TimeDelta(), task_runner_->NextPendingTaskDelay());
  ExpectVirtualTime(0, 0);
  ExpectBeginFrame();
  task_runner_->RunPendingTasks();

  // No new BeginFrames are scheduled when BeginFrames are not needed.
  SendNeedsBeginFramesEvent(false);
  EXPECT_FALSE(task_runner_->HasPendingTask());

  SendBeginFrameReply(false, false, std::string());
  EXPECT_FALSE(task_runner_->HasPendingTask());

  // Restarts sending BeginFrames when they are needed again.
  SendNeedsBeginFramesEvent(true);
  EXPECT_TRUE(task_runner_->HasPendingTask());
  ExpectVirtualTime(0, 0);
  ExpectBeginFrame();
  task_runner_->RunPendingTasks();

  // Stops sending BeginFrames when an main frame update is included.
  SendMainFrameReadyForScreenshotsEvent();
  EXPECT_FALSE(task_runner_->HasPendingTask());

  EXPECT_FALSE(updated);
  SendBeginFrameReply(true, true, std::string());
  EXPECT_FALSE(task_runner_->HasPendingTask());
  EXPECT_TRUE(updated);
}

TEST_F(CompositorControllerTest, SendsAnimationFrames) {
  base::Optional<VirtualTimeController::RepeatingTask::ContinuePolicy>
      continue_policy;
  auto continue_callback = base::BindRepeating(
      [](base::Optional<VirtualTimeController::RepeatingTask::ContinuePolicy>*
             continue_policy,
         VirtualTimeController::RepeatingTask::ContinuePolicy policy) {
        *continue_policy = policy;
      },
      &continue_policy);

  // Doesn't send BeginFrames before virtual time started.
  SendNeedsBeginFramesEvent(true);
  EXPECT_FALSE(task_runner_->HasPendingTask());

  // Sends a BeginFrame after interval elapsed.
  task_->IntervalElapsed(kAnimationFrameInterval, continue_callback);
  EXPECT_FALSE(continue_policy);
  continue_policy = base::nullopt;

  EXPECT_TRUE(task_runner_->HasPendingTask());
  ExpectVirtualTime(1000, kAnimationFrameInterval.InMillisecondsF());
  ExpectBeginFrame();
  task_runner_->RunPendingTasks();

  // Lets virtual time continue after BeginFrame was completed.
  SendBeginFrameReply(false, false, std::string());
  EXPECT_FALSE(task_runner_->HasPendingTask());
  EXPECT_EQ(VirtualTimeController::RepeatingTask::ContinuePolicy::NOT_REQUIRED,
            *continue_policy);
  continue_policy = base::nullopt;

  // Sends another BeginFrame after next interval elapsed.
  task_->IntervalElapsed(kAnimationFrameInterval, continue_callback);
  EXPECT_FALSE(continue_policy);

  EXPECT_TRUE(task_runner_->HasPendingTask());
  ExpectVirtualTime(1000, kAnimationFrameInterval.InMillisecondsF() * 2);
  ExpectBeginFrame();
  task_runner_->RunPendingTasks();

  // Lets virtual time continue after BeginFrame was completed.
  SendBeginFrameReply(false, false, std::string());
  EXPECT_FALSE(task_runner_->HasPendingTask());
  EXPECT_EQ(VirtualTimeController::RepeatingTask::ContinuePolicy::NOT_REQUIRED,
            *continue_policy);
}

TEST_F(CompositorControllerTest, SkipsAnimationFrameForScreenshots) {
  base::Optional<VirtualTimeController::RepeatingTask::ContinuePolicy>
      continue_policy;
  auto continue_callback = base::BindRepeating(
      [](base::Optional<VirtualTimeController::RepeatingTask::ContinuePolicy>*
             continue_policy,
         VirtualTimeController::RepeatingTask::ContinuePolicy policy) {
        *continue_policy = policy;
      },
      &continue_policy);

  SendMainFrameReadyForScreenshotsEvent();
  EXPECT_FALSE(task_runner_->HasPendingTask());
  SendNeedsBeginFramesEvent(true);
  EXPECT_FALSE(task_runner_->HasPendingTask());

  // Doesn't send a BeginFrame after interval elapsed if a screenshot is taken
  // instead.
  task_->IntervalElapsed(kAnimationFrameInterval, continue_callback);
  EXPECT_FALSE(continue_policy);

  controller_->CaptureScreenshot(
      headless_experimental::ScreenshotParamsFormat::PNG, 100,
      base::BindRepeating([](const std::string&) {}));

  EXPECT_TRUE(task_runner_->HasPendingTask());
  ExpectVirtualTime(0, 0);
  ExpectBeginFrame(
      false, headless_experimental::ScreenshotParams::Builder()
                 .SetFormat(headless_experimental::ScreenshotParamsFormat::PNG)
                 .SetQuality(100)
                 .Build());
  task_runner_->RunPendingTasks();

  EXPECT_EQ(VirtualTimeController::RepeatingTask::ContinuePolicy::NOT_REQUIRED,
            *continue_policy);
}

TEST_F(CompositorControllerTest,
       PostponesAnimationFrameWhenVirtualTimeStopped) {
  base::Optional<VirtualTimeController::RepeatingTask::ContinuePolicy>
      continue_policy;
  auto continue_callback = base::BindRepeating(
      [](base::Optional<VirtualTimeController::RepeatingTask::ContinuePolicy>*
             continue_policy,
         VirtualTimeController::RepeatingTask::ContinuePolicy policy) {
        *continue_policy = policy;
      },
      &continue_policy);

  SendNeedsBeginFramesEvent(true);
  EXPECT_FALSE(task_runner_->HasPendingTask());

  // Doesn't send a BeginFrame after interval elapsed if the budget also
  // expired.
  task_->IntervalElapsed(kAnimationFrameInterval, continue_callback);
  EXPECT_FALSE(continue_policy);

  observer_->VirtualTimeStopped(kAnimationFrameInterval);
  EXPECT_EQ(VirtualTimeController::RepeatingTask::ContinuePolicy::NOT_REQUIRED,
            *continue_policy);
  continue_policy = base::nullopt;
  // Flush cancelled task.
  task_runner_->RunPendingTasks();

  bool can_continue = false;
  auto defer_callback = base::BindRepeating(
      [](bool* can_continue) { *can_continue = true; }, &can_continue);

  // Sends a BeginFrame when more virtual time budget is requested.
  ExpectVirtualTime(0, 0);
  ExpectBeginFrame();
  deferer_->DeferStart(defer_callback);
  EXPECT_FALSE(can_continue);

  SendBeginFrameReply(false, false, std::string());
  EXPECT_FALSE(task_runner_->HasPendingTask());
  EXPECT_TRUE(can_continue);
}

TEST_F(CompositorControllerTest,
       SkipsAnimationFrameWhenVirtualTimeStoppedAndScreenshotWasTaken) {
  base::Optional<VirtualTimeController::RepeatingTask::ContinuePolicy>
      continue_policy;
  auto continue_callback = base::BindRepeating(
      [](base::Optional<VirtualTimeController::RepeatingTask::ContinuePolicy>*
             continue_policy,
         VirtualTimeController::RepeatingTask::ContinuePolicy policy) {
        *continue_policy = policy;
      },
      &continue_policy);

  SendMainFrameReadyForScreenshotsEvent();
  EXPECT_FALSE(task_runner_->HasPendingTask());
  SendNeedsBeginFramesEvent(true);
  EXPECT_FALSE(task_runner_->HasPendingTask());

  // Doesn't send a BeginFrame after interval elapsed if the budget also
  // expired.
  task_->IntervalElapsed(kAnimationFrameInterval, continue_callback);
  EXPECT_FALSE(continue_policy);

  observer_->VirtualTimeStopped(kAnimationFrameInterval);
  EXPECT_EQ(VirtualTimeController::RepeatingTask::ContinuePolicy::NOT_REQUIRED,
            *continue_policy);
  continue_policy = base::nullopt;
  // Flush cancelled task.
  task_runner_->RunPendingTasks();

  controller_->CaptureScreenshot(
      headless_experimental::ScreenshotParamsFormat::PNG, 100,
      base::BindRepeating([](const std::string&) {}));

  EXPECT_TRUE(task_runner_->HasPendingTask());
  ExpectVirtualTime(0, 0);
  ExpectBeginFrame(
      false, headless_experimental::ScreenshotParams::Builder()
                 .SetFormat(headless_experimental::ScreenshotParamsFormat::PNG)
                 .SetQuality(100)
                 .Build());
  task_runner_->RunPendingTasks();

  bool can_continue = false;
  auto defer_callback = base::BindRepeating(
      [](bool* can_continue) { *can_continue = true; }, &can_continue);

  // Sends a BeginFrame when more virtual time budget is requested.
  deferer_->DeferStart(defer_callback);
  EXPECT_TRUE(can_continue);
}

TEST_F(CompositorControllerTest, WaitUntilIdle) {
  bool idle = false;
  auto idle_callback =
      base::BindRepeating([](bool* idle) { *idle = true; }, &idle);

  SendNeedsBeginFramesEvent(true);
  EXPECT_FALSE(task_runner_->HasPendingTask());

  // WaitUntilIdle executes callback immediately if no BeginFrame is active.
  controller_->WaitUntilIdle(idle_callback);
  EXPECT_TRUE(idle);
  idle = false;

  // Send a BeginFrame.
  task_->IntervalElapsed(
      kAnimationFrameInterval,
      base::BindRepeating(
          [](VirtualTimeController::RepeatingTask::ContinuePolicy) {}));

  EXPECT_TRUE(task_runner_->HasPendingTask());
  ExpectVirtualTime(0, 0);
  ExpectBeginFrame();
  task_runner_->RunPendingTasks();

  // WaitUntilIdle only executes callback after BeginFrame was completed.
  controller_->WaitUntilIdle(idle_callback);
  EXPECT_FALSE(idle);

  SendBeginFrameReply(false, false, std::string());
  EXPECT_FALSE(task_runner_->HasPendingTask());
  EXPECT_TRUE(idle);
  idle = false;
}

class CompositorControllerNoDisplayUpdateTest
    : public CompositorControllerTest {
 protected:
  CompositorControllerNoDisplayUpdateTest() : CompositorControllerTest(false) {}
};

TEST_F(CompositorControllerNoDisplayUpdateTest,
       SkipsDisplayUpdateOnlyForAnimationFrames) {
  base::Optional<VirtualTimeController::RepeatingTask::ContinuePolicy>
      continue_policy;
  auto continue_callback = base::BindRepeating(
      [](base::Optional<VirtualTimeController::RepeatingTask::ContinuePolicy>*
             continue_policy,
         VirtualTimeController::RepeatingTask::ContinuePolicy policy) {
        *continue_policy = policy;
      },
      &continue_policy);

  // Wait for update BeginFrames update display.
  SendNeedsBeginFramesEvent(true);
  controller_->WaitForMainFrameContentUpdate(base::BindRepeating([]() {}));
  EXPECT_TRUE(task_runner_->HasPendingTask());
  ExpectVirtualTime(1000, 0);
  ExpectBeginFrame();
  task_runner_->RunPendingTasks();

  SendMainFrameReadyForScreenshotsEvent();
  EXPECT_FALSE(task_runner_->HasPendingTask());

  SendBeginFrameReply(true, true, std::string());
  EXPECT_FALSE(task_runner_->HasPendingTask());

  // Sends an animation BeginFrame without display update after interval
  // elapsed.
  task_->IntervalElapsed(kAnimationFrameInterval, continue_callback);
  EXPECT_FALSE(continue_policy);

  EXPECT_TRUE(task_runner_->HasPendingTask());
  ExpectVirtualTime(1000, kAnimationFrameInterval.InMillisecondsF());
  ExpectBeginFrame(true);
  task_runner_->RunPendingTasks();

  // Lets virtual time continue after BeginFrame was completed.
  SendBeginFrameReply(false, false, std::string());
  EXPECT_FALSE(task_runner_->HasPendingTask());
  EXPECT_EQ(VirtualTimeController::RepeatingTask::ContinuePolicy::NOT_REQUIRED,
            *continue_policy);
  continue_policy = base::nullopt;

  // Screenshots update display.
  task_->IntervalElapsed(kAnimationFrameInterval, continue_callback);
  EXPECT_FALSE(continue_policy);

  controller_->CaptureScreenshot(
      headless_experimental::ScreenshotParamsFormat::PNG, 100,
      base::BindRepeating([](const std::string&) {}));

  EXPECT_TRUE(task_runner_->HasPendingTask());
  ExpectVirtualTime(1000, kAnimationFrameInterval.InMillisecondsF() * 2);
  ExpectBeginFrame(
      false, headless_experimental::ScreenshotParams::Builder()
                 .SetFormat(headless_experimental::ScreenshotParamsFormat::PNG)
                 .SetQuality(100)
                 .Build());
  task_runner_->RunPendingTasks();

  EXPECT_EQ(VirtualTimeController::RepeatingTask::ContinuePolicy::NOT_REQUIRED,
            *continue_policy);
}

}  // namespace headless
