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

#include "chrome/browser/autofill/captured_sites_test_utils.h"

#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
#include <variant>
#include <vector>

#include "base/base_switches.h"
#include "base/check_deref.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback_forward.h"
#include "base/json/json_reader.h"
#include "base/json/json_string_value_serializer.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/process/launch.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/thread_pool.h"
#include "base/test/bind.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"
#include "base/time/time_override.h"
#include "base/uuid.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/autofill/autofill_uitest_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/interactive_test_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/autofill/core/browser/autofill_type.h"
#include "components/autofill/core/browser/data_model/addresses/autofill_profile.h"
#include "components/autofill/core/browser/data_model/payments/credit_card.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/test_utils/autofill_test_utils.h"
#include "components/autofill/core/browser/test_utils/test_autofill_clock.h"
#include "components/autofill/core/common/autofill_clock.h"
#include "components/javascript_dialogs/app_modal_dialog_controller.h"
#include "components/javascript_dialogs/app_modal_dialog_view.h"
#include "components/permissions/permission_request_manager.h"
#include "components/variations/variations_switches.h"
#include "content/public/browser/browsing_data_remover.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/browsing_data_remover_test_util.h"
#include "content/public/test/test_renderer_host.h"
#include "content/public/test/test_utils.h"
#include "net/base/address_list.h"
#include "net/socket/tcp_client_socket.h"
#include "third_party/zlib/google/compression_utils.h"
#include "ui/events/keycodes/dom/dom_key.h"
#include "ui/events/keycodes/keyboard_code_conversion.h"
#include "ui/events/keycodes/keyboard_codes.h"

using base::JSONParserOptions;
using base::JSONReader;

namespace {

// The command-line flag to specify the command file flag.
const char kCommandFileFlag[] = "command_file";

// The command line flag to turn on verbose WPR logging.
const char kWebPageReplayVerboseFlag[] = "wpr_verbose";

// The maximum amount of time to wait for Chrome to finish autofilling a form.
const base::TimeDelta kAutofillActionWaitForVisualUpdateTimeout =
    base::Seconds(3);

// The number of tries the TestRecipeReplayer should perform when executing an
// Chrome Autofill action.
// Chrome Autofill can be flaky on some real-world pages. The Captured Site
// Automation Framework will retry an autofill action a couple times before
// concluding that Chrome Autofill does not work.
const int kAutofillActionNumRetries = 5;

// The public key hash for the certificate Web Page Replay (WPR) uses to serve
// HTTPS content.
// The Captured Sites Test Framework relies on WPR to serve captured site
// traffic. If a machine does not have the WPR certificate installed, Chrome
// will detect a server certificate validation failure when WPR serves Chrome
// HTTPS content. In response Chrome will block the WPR HTTPS content.
// The test framework avoids this problem by launching Chrome with the
// ignore-certificate-errors-spki-list flag set to the WPR certificate's
// public key hash. Doing so tells Chrome to ignore server certificate
// validation errors from WPR.
const char kWebPageReplayCertSPKI[] =
    "PoNnQAwghMiLUPg1YNFtvTfGreNT8r9oeLEyzgNCJWc=";

const char kTimeClockOverrideNotSetMessage[] =
    "No TimeClock override set from wpr archive: ";

// A helper class to override the current time.
struct TimeOverrideHelper {
  static base::Time TimeNow() { return current_time; }

  // Used as the current time in captured sites tests.
  static base::Time current_time;
};

base::Time TimeOverrideHelper::current_time;

// Check and return that the caller wants verbose WPR output (off by default).
bool IsVerboseWprLoggingEnabled() {
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  return command_line && command_line->HasSwitch(kWebPageReplayVerboseFlag);
}

void PrintDebugInstructions(const base::FilePath& command_file_path) {
  const char msg[] = R"(

*** INTERACTIVE DEBUGGING MODE ***

To proceed, you should create a named pipe:
  $ mkfifo %1$s
and then write commands into it:
  $ echo run     >%1$s  # unpauses execution
  $ echo next 2  >%1$s  # executes the next 2 actions
  $ echo next -1 >%1$s  # executes until the last action
  $ echo skip -3 >%1$s  # jumps back 3 actions
  $ echo skip 4  >%1$s  # skips the next 4 actions
  $ echo where   >%1$s  # prints the current position
  $ echo show -1 >%1$s  # prints last 1 actions
  $ echo show 1  >%1$s  # prints next 1 actions
  $ echo failure >%1$s  # unpauses execution until failure
  $ echo help    >%1$s  # prints this text
)";
  VLOG(1) << base::StringPrintf(msg, command_file_path.AsUTF8Unsafe().c_str());
}

std::optional<autofill::FieldType> StringToFieldType(std::string_view str) {
  static auto map = [] {
    std::map<std::string_view, autofill::FieldType> map;
    for (autofill::FieldType field_type : autofill::FieldTypeSet::all()) {
      map[autofill::FieldTypeToStringView(field_type)] = field_type;
    }
    for (autofill::HtmlFieldType html_field_type :
         autofill::HtmlFieldTypeSet::all()) {
      map[autofill::FieldTypeToStringView(html_field_type)] =
          autofill::HtmlFieldTypeToBestCorrespondingFieldType(html_field_type);
    }
    return map;
  }();
  auto it = map.find(str);
  if (it == map.end()) {
    return std::nullopt;
  }
  return it->second;
}

// Command types to control and debug execution.
// * The `kAbsoluteLimit` and `kRelativeLimit` commands indicate that
//   execution shall not proceed if the next action's position is >= `param`
//   or >= current_index + `param`, respectively.
// * The `kSkipAction` command jumps `param` actions forward or backward.
// * The `kShowAction` command prints the `param` previous (if < 0) or
//   upcoming (if > 0) actions.
// * The `kWhereAmI` command prints the current execution position.
enum class ExecutionCommandType {
  kAbsoluteLimit,
  kRelativeLimit,
  kSkipAction,
  kShowAction,
  kWhereAmI,
  kRunUntilFailure
};

struct ExecutionCommand {
  ExecutionCommandType type = ExecutionCommandType::kAbsoluteLimit;
  int param = std::numeric_limits<int>::max();
};

// Blockingly reads the content of `command_file_path`, parses it into
// ExecutionCommands, and returns the result.
std::vector<ExecutionCommand> ReadExecutionCommands(
    const base::FilePath& command_file_path) {
  std::vector<ExecutionCommand> commands;
  std::string command_lines;
  if (base::ReadFileToString(command_file_path, &command_lines)) {
    for (const auto command :
         base::SplitStringPiece(command_lines, "\n", base::TRIM_WHITESPACE,
                                base::SPLIT_WANT_NONEMPTY)) {
      auto GetParamOr = [command](int default_value) {
        size_t space = command.find(' ');
        if (space == std::string_view::npos) {
          return default_value;
        }
        int value;
        if (!base::StringToInt(command.substr(space + 1), &value))
          return default_value;
        return value;
      };

      if (command.starts_with("run")) {
        commands.push_back({ExecutionCommandType::kAbsoluteLimit,
                            std::numeric_limits<int>::max()});
      } else if (command.starts_with("next")) {
        commands.push_back(
            {ExecutionCommandType::kRelativeLimit, GetParamOr(1)});
      } else if (command.starts_with("skip")) {
        commands.push_back({ExecutionCommandType::kSkipAction, GetParamOr(1)});
      } else if (command.starts_with("show")) {
        commands.push_back({ExecutionCommandType::kShowAction, GetParamOr(1)});
      } else if (command.starts_with("where")) {
        commands.push_back({ExecutionCommandType::kWhereAmI});
      } else if (command.starts_with("failure")) {
        commands.push_back({ExecutionCommandType::kRunUntilFailure});
        // Same commands as for "run":
        commands.push_back({ExecutionCommandType::kAbsoluteLimit,
                            std::numeric_limits<int>::max()});
      } else if (command.starts_with("help")) {
        PrintDebugInstructions(command_file_path);
      }
    }
  }
  return commands;
}

struct ExecutionState {
  // The position of the next action to be executed.
  int index = 0;
  // The current bound on the execution.
  int limit = std::numeric_limits<int>::max();
  // The number of actions to be executed.
  int length = 0;
  // Whether to stop at a step if a failure is detected.
  bool pause_on_failure = false;
};

// Blockingly reads the commands from `command_file_path` and executes them.
// Execution primarily means manipulation of the `execution_state`, particularly
// `execution_state.limit`.
ExecutionState ProcessCommands(ExecutionState execution_state,
                               const base::Value::List* action_list,
                               const base::FilePath& command_file_path) {
  while (execution_state.limit <= execution_state.index) {
    for (ExecutionCommand command : ReadExecutionCommands(command_file_path)) {
      switch (command.type) {
        case ExecutionCommandType::kAbsoluteLimit: {
          execution_state.limit = command.param;
          break;
        }
        case ExecutionCommandType::kRelativeLimit: {
          if (command.param >= 0) {
            execution_state.limit += command.param;
          } else {
            execution_state.limit = execution_state.length + command.param;
          }
          break;
        }
        case ExecutionCommandType::kSkipAction: {
          execution_state.index += command.param;
          execution_state.index = std::min(std::max(execution_state.index, 0),
                                           execution_state.length - 1);
          break;
        }
        case ExecutionCommandType::kShowAction: {
          int min_index = execution_state.index + std::min(command.param, 0);
          int max_index = execution_state.index + std::max(command.param, 0);
          min_index = std::max(min_index, 0);
          max_index = std::min(max_index, execution_state.length);
          for (int i = min_index; i < max_index; ++i) {
            VLOG(1) << "Action " << (i - execution_state.index) << ": "
                    << (*action_list)[i].DebugString();
          }
          break;
        }
        case ExecutionCommandType::kWhereAmI: {
          VLOG(1) << "Next action is at position " << execution_state.index
                  << ", limit (excl) is at " << execution_state.limit
                  << ", last (excl) is at " << execution_state.length;
          break;
        }
        case ExecutionCommandType::kRunUntilFailure: {
          VLOG(1) << "Will stop when a failure is found.";
          execution_state.pause_on_failure = true;
          break;
        }
      }
    }
  }
  return execution_state;
}

struct AllowNull {
  inline constexpr AllowNull() = default;
};

std::optional<std::string> FindPopulateString(
    const base::Value::Dict& container,
    std::string_view key_name,
    std::variant<std::string_view, AllowNull> key_descriptor) {
  const std::string* value = container.FindString(key_name);
  if (!value) {
    if (std::holds_alternative<std::string_view>(key_descriptor)) {
      ADD_FAILURE() << "Failed to extract '"
                    << std::get<std::string_view>(key_descriptor)
                    << "' string from container!";
    }
    return std::nullopt;
  }

  return *value;
}

std::optional<std::vector<std::string>> FindPopulateStringVector(
    const base::Value::Dict& container,
    std::string_view key_name,
    std::variant<std::string_view, AllowNull> key_descriptor) {
  const base::Value::List* list = container.FindList(key_name);
  if (!list) {
    if (std::holds_alternative<std::string_view>(key_descriptor)) {
      ADD_FAILURE() << "Failed to extract '"
                    << std::get<std::string_view>(key_descriptor)
                    << "' strings from container!";
    }
    return std::nullopt;
  }

  std::vector<std::string> strings;
  for (const base::Value& item : *list) {
    if (!item.is_string()) {
      if (std::holds_alternative<std::string_view>(key_descriptor)) {
        ADD_FAILURE() << "Failed to extract element of '"
                      << std::get<std::string_view>(key_descriptor)
                      << "' vector from container!";
      }
      return std::nullopt;
    }
    strings.push_back(item.GetString());
  }
  return strings;
}

}  // namespace

namespace captured_sites_test_utils {

CapturedSiteParams::CapturedSiteParams() = default;
CapturedSiteParams::~CapturedSiteParams() = default;
CapturedSiteParams::CapturedSiteParams(const CapturedSiteParams& other) =
    default;

std::ostream& operator<<(std::ostream& os, const CapturedSiteParams& param) {
  if (param.scenario_dir.empty())
    return os << "Site: " << param.site_name;
  return os << "Scenario: " << param.scenario_dir
            << ", Site: " << param.site_name;
}

// Iterate through Autofill's Web Page Replay capture file directory to look
// for captures sites and automation recipe files. Return a list of sites for
// which recipe-based testing is available.
std::vector<CapturedSiteParams> GetCapturedSites(
    const base::FilePath& replay_files_dir_path) {
  std::vector<CapturedSiteParams> sites;
  base::FilePath config_file_path =
      replay_files_dir_path.AppendASCII("testcases.json");

  std::string json_text;
  if (!base::ReadFileToString(config_file_path, &json_text)) {
    LOG(WARNING) << "Could not read json file: " << config_file_path;
    LOG(WARNING)
        << "Did you forget to set checkout_chromium_autofill_test_dependencies "
           "to True in .gclient and gclient sync?";
    return sites;
  }
  // Parse json text content to json value node.
  auto value_with_error = JSONReader::ReadAndReturnValueWithError(
      json_text, JSONParserOptions::JSON_PARSE_RFC);
  if (!value_with_error.has_value()) {
    LOG(WARNING) << "Could not load test config from json file: "
                 << "`testcases.json` because: "
                 << value_with_error.error().message;
    return sites;
  }
  base::Value::Dict root_node = std::move(*value_with_error).TakeDict();
  const base::Value::List* list_node = root_node.FindList("tests");
  if (!list_node) {
    LOG(WARNING) << "No tests found in `testcases.json` config";
    return sites;
  }

  bool also_run_disabled = GTEST_FLAG_GET(also_run_disabled_tests);

  for (auto& item_val : *list_node) {
    if (!item_val.is_dict()) {
      continue;
    }
    const base::Value::Dict& item = item_val.GetDict();
    CapturedSiteParams param;
    param.site_name = CHECK_DEREF(item.FindString("site_name"));

    if (const std::string* scenario_dir = item.FindString("scenario_dir")) {
      param.scenario_dir = *scenario_dir;
    }
    param.is_disabled = item.FindBool("disabled").value_or(false);

    const std::optional<int> bug_number = item.FindInt("bug_number");
    if (bug_number) {
      param.bug_number = bug_number.value();
    }
    if (param.is_disabled && !also_run_disabled)
      continue;

    const std::string* expectation_string = item.FindString("expectation");
    if (expectation_string && *expectation_string == "FAIL") {
      param.expectation = kFail;
    } else {
      param.expectation = kPass;
    }
    // Check that a pair of .test and .wpr files exist - otherwise skip
    base::FilePath file_name = replay_files_dir_path;
    base::FilePath refresh_file_path =
        replay_files_dir_path.AppendASCII("refresh");
    if (!param.scenario_dir.empty()) {
      file_name = file_name.AppendASCII(param.scenario_dir);
      refresh_file_path = refresh_file_path.AppendASCII(param.scenario_dir);
    }
    file_name = file_name.AppendASCII(param.site_name);
    refresh_file_path =
        refresh_file_path.AppendASCII(param.site_name).AddExtensionASCII("wpr");

    base::FilePath capture_file_path = file_name.AddExtensionASCII("wpr");
    if (!base::PathExists(capture_file_path)) {
      LOG(WARNING) << "Test `" << param.site_name
                   << "` had no matching .wpr file";
      continue;
    }
    base::FilePath recipe_file_path = file_name.AddExtensionASCII("test");
    if (!base::PathExists(recipe_file_path)) {
      LOG(WARNING) << "Test `" << param.site_name
                   << "` had no matching .test file";
      continue;
    }
    param.capture_file_path = capture_file_path;
    param.recipe_file_path = recipe_file_path;
    param.refresh_file_path = refresh_file_path;
    sites.push_back(param);
  }
  return sites;
}

std::optional<base::Value::Dict> ReadRecipeFile(
    const base::FilePath& recipe_file_path) {
  // Read the text of the recipe file.
  base::ScopedAllowBlockingForTesting for_testing;
  std::string json_text;
  if (!base::ReadFileToString(recipe_file_path, &json_text)) {
    ADD_FAILURE() << "Failed to read recipe file '" << recipe_file_path << "'!";
    return std::nullopt;
  }

  // Convert the file text into a json object.
  std::optional<base::Value> parsed_json =
      base::JSONReader::Read(json_text, base::JSON_PARSE_CHROMIUM_EXTENSIONS);
  if (!parsed_json) {
    ADD_FAILURE() << "Failed to deserialize json text!";
    return std::nullopt;
  }
  DCHECK(parsed_json->is_dict());
  return std::move(*parsed_json).TakeDict();
}

std::string FilePathToUTF8(const base::FilePath::StringType& str) {
#if BUILDFLAG(IS_WIN)
  return base::WideToUTF8(str);
#else
  return str;
#endif
}

std::optional<base::FilePath> GetCommandFilePath() {
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  if (command_line && command_line->HasSwitch(kCommandFileFlag)) {
    return std::make_optional(
        command_line->GetSwitchValuePath(kCommandFileFlag));
  }
  return std::nullopt;
}

void PrintInstructions(const char* test_file_name) {
  const char msg[] = R"(

*** README ***

A captured-site test replays an action recipe (*.test)
against recorded web traffic (*.wpr).
These files need to be downloaded separately.

Recommended flags are:
  --test-launcher-timeout=1000000
  --ui-test-action-max-timeout=1000000
  --enable-pixel-output-in-tests
  --vmodule=captured_sites_test_utils=1,%s=1:

For interactive debugging, specify a command file:
  --%s=/path/to/file
Commands to step through the test can be written into that file.
Further instructions will be printed then.
)";
  VLOG(1) << base::StringPrintf(msg, test_file_name, kCommandFileFlag);
}

// FrameObserver --------------------------------------------------------------
IFrameWaiter::IFrameWaiter(content::WebContents* web_contents)
    : content::WebContentsObserver(web_contents),
      query_type_(URL),
      target_frame_(nullptr) {}

IFrameWaiter::~IFrameWaiter() = default;

content::RenderFrameHost* IFrameWaiter::WaitForFrameMatchingName(
    const std::string& name,
    const base::TimeDelta timeout) {
  content::RenderFrameHost* frame = FrameMatchingPredicateOrNullptr(
      web_contents()->GetPrimaryPage(),
      base::BindRepeating(&content::FrameMatchesName, name));
  if (frame) {
    return frame;
  } else {
    query_type_ = NAME;
    frame_name_ = name;
    base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
        FROM_HERE, run_loop_.QuitClosure(), timeout);
    run_loop_.Run();
    return target_frame_;
  }
}

content::RenderFrameHost* IFrameWaiter::WaitForFrameMatchingOrigin(
    const GURL origin,
    const base::TimeDelta timeout) {
  content::RenderFrameHost* frame = FrameMatchingPredicateOrNullptr(
      web_contents()->GetPrimaryPage(),
      base::BindRepeating(&FrameHasOrigin, origin));
  if (frame) {
    return frame;
  } else {
    query_type_ = ORIGIN;
    origin_ = origin;
    base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
        FROM_HERE, run_loop_.QuitClosure(), timeout);
    run_loop_.Run();
    return target_frame_;
  }
}

content::RenderFrameHost* IFrameWaiter::WaitForFrameMatchingUrl(
    const GURL url,
    const base::TimeDelta timeout) {
  content::RenderFrameHost* frame = FrameMatchingPredicateOrNullptr(
      web_contents()->GetPrimaryPage(),
      base::BindRepeating(&content::FrameHasSourceUrl, url));
  if (frame) {
    return frame;
  } else {
    query_type_ = URL;
    url_ = url;
    base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
        FROM_HERE, run_loop_.QuitClosure(), timeout);
    run_loop_.Run();
    return target_frame_;
  }
}

void IFrameWaiter::RenderFrameCreated(
    content::RenderFrameHost* render_frame_host) {
  if (!run_loop_.running())
    return;
  switch (query_type_) {
    case NAME:
      if (FrameMatchesName(frame_name_, render_frame_host))
        run_loop_.Quit();
      break;
    case ORIGIN:
      if (render_frame_host->GetLastCommittedURL().DeprecatedGetOriginAsURL() ==
          origin_)
        run_loop_.Quit();
      break;
    case URL:
      if (FrameHasSourceUrl(url_, render_frame_host))
        run_loop_.Quit();
      break;
    default:
      break;
  }
}

void IFrameWaiter::DidFinishLoad(content::RenderFrameHost* render_frame_host,
                                 const GURL& validated_url) {
  if (!run_loop_.running())
    return;
  switch (query_type_) {
    case ORIGIN:
      if (validated_url.DeprecatedGetOriginAsURL() == origin_)
        run_loop_.Quit();
      break;
    case URL:
      if (FrameHasSourceUrl(validated_url, render_frame_host))
        run_loop_.Quit();
      break;
    default:
      break;
  }
}

void IFrameWaiter::FrameNameChanged(content::RenderFrameHost* render_frame_host,
                                    const std::string& name) {
  if (!run_loop_.running())
    return;
  switch (query_type_) {
    case NAME:
      if (FrameMatchesName(name, render_frame_host))
        run_loop_.Quit();
      break;
    default:
      break;
  }
}

bool IFrameWaiter::FrameHasOrigin(const GURL& origin,
                                  content::RenderFrameHost* frame) {
  GURL url = frame->GetLastCommittedURL();
  return (url.DeprecatedGetOriginAsURL() == origin.DeprecatedGetOriginAsURL());
}

// WebPageReplayServerWrapper -------------------------------------------------
WebPageReplayServerWrapper::WebPageReplayServerWrapper(
    const bool start_as_replay,
    int host_http_port,
    int host_https_port,
    std::vector<std::string> extra_args)
    : host_http_port_(host_http_port),
      host_https_port_(host_https_port),
      start_as_replay_(start_as_replay),
      extra_args_(std::move(extra_args)) {}

WebPageReplayServerWrapper::~WebPageReplayServerWrapper() = default;

bool WebPageReplayServerWrapper::Start(
    const base::FilePath& capture_file_path) {
  std::vector<std::string> args;
  base::FilePath src_dir;
  if (!base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &src_dir)) {
    ADD_FAILURE() << "Failed to extract the Chromium source directory!";
    return false;
  }

  args.push_back(base::StringPrintf("--http_port=%d", host_http_port_));
  args.push_back(base::StringPrintf("--https_port=%d", host_https_port_));
  if (start_as_replay_) {
    args.push_back("--serve_response_in_chronological_sequence");
    // Start WPR in quiet mode, removing the extra verbose ServeHTTP
    // interactions that are for the the overwhelming majority unhelpful, but
    // for extra debugging of a test case, include 'wpr_verbose' in command.
    if (!IsVerboseWprLoggingEnabled())
      args.push_back("--quiet_mode");
  }
  args.push_back(base::StringPrintf(
      "--inject_scripts=%s",
      FilePathToUTF8(src_dir.AppendASCII("chrome")
                         .AppendASCII("test")
                         .AppendASCII("data")
                         .AppendASCII("web_page_replay_go_helper_scripts")
                         .AppendASCII("automation_helper.js")
                         .value())
          .c_str()));

  // Specify the capture file.
  args.push_back(base::StringPrintf(
      "%s", FilePathToUTF8(capture_file_path.value()).c_str()));
  if (!RunWebPageReplayCmd(args))
    return false;

  base::RunLoop wpr_launch_waiter;
  // This socket is created and destroyed on the IO thread, but it's simplest to
  // declare it here, since its deleted by a callback that may be invoked
  // asynchronously by its connect method, or calls its Connect method,
  // depending on whether the connection attempt completes synchronously. Having
  // two deletion paths makes BindOnce() not work well with it.
  std::unique_ptr<net::TCPClientSocket> client_socket;

  size_t connect_attempts = 0;
  base::RepeatingCallback<void(int)> on_connect_complete;
  auto bind_new_socket = base::BindLambdaForTesting([&]() {
    net::AddressList addr(
        net::IPEndPoint(net::IPAddress(127, 0, 0, 1), host_http_port_));
    ++connect_attempts;
    client_socket = std::make_unique<net::TCPClientSocket>(
        addr, nullptr, nullptr, nullptr, net::NetLogSource());
    int connect_result = client_socket->Connect(on_connect_complete);
    // On ERR_IO_PENDING, `on_connect_complete` will be invoked
    // asynchronously, so need to let the message loop spin until that
    // happens.
    if (connect_result == net::ERR_IO_PENDING) {
      return;
    }
    // Otherwise, run `on_connect_complete` immediately.
    on_connect_complete.Run(connect_result);
  });

  // Called on the IO thread once connection has completed. Destroys the
  // `client_socket`, which may or may not be the object invoking the callback.
  on_connect_complete = base::BindLambdaForTesting([&](int connect_result) {
    client_socket.reset();
    if (connect_result == net::OK || connect_attempts > 30) {
      wpr_launch_waiter.Quit();
    } else {
      base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
          FROM_HERE, bind_new_socket, base::Seconds(1));
    }
  });

  content::GetIOThreadTaskRunner({})->PostTask(FROM_HERE, bind_new_socket);
  wpr_launch_waiter.Run();

  if (!web_page_replay_server_.IsValid()) {
    ADD_FAILURE() << "Failed to start the WPR replay server!";
    return false;
  }

  return true;
}

bool WebPageReplayServerWrapper::Stop() {
  if (web_page_replay_server_.IsValid()) {
    bool did_terminate = false;
    if (!start_as_replay_) {
#if BUILDFLAG(IS_POSIX)
      bool error_when_terminating_record_mode = false;
      // For Replay sessions, this function can terminate the WPR process
      // immediately as it doesn't need to write the archive file. In Record
      // sessions, this function will try to send a SIGINT and use
      // `WaitForExit()` to close and write the WPR archive file gracefully. If
      // this fails, the function will terminate via Process::Terminate which
      // will send SIGTERM and then SIGKILL.
      if (kill(web_page_replay_server_.Handle(), SIGINT) != 0) {
        ADD_FAILURE() << "Failed to send SIGINT to a recording WPR server!";
        error_when_terminating_record_mode = true;
      } else if (!web_page_replay_server_.WaitForExit(nullptr)) {
        ADD_FAILURE() << "Failed to wait for a recording WPR server to exit!";
        error_when_terminating_record_mode = true;
      }
      did_terminate = !error_when_terminating_record_mode;
#else
      ADD_FAILURE()
          << "Clean termination of recording WPR server is only supported on "
             "OS_POSIX. New archive may not be saved properly.";
#endif
    }
    if (start_as_replay_ || !did_terminate) {
      if (!web_page_replay_server_.Terminate(0, true)) {
        ADD_FAILURE() << "Failed to terminate the WPR replay server!";
        return false;
      }
    }
  }

  // The test server hasn't started, no op.
  return true;
}

bool WebPageReplayServerWrapper::RunWebPageReplayCmdAndWaitForExit(
    const std::vector<std::string>& args,
    const base::TimeDelta& timeout) {
  int exit_code;

  if (RunWebPageReplayCmd(args) && web_page_replay_server_.IsValid() &&
      web_page_replay_server_.WaitForExitWithTimeout(timeout, &exit_code) &&
      exit_code == 0) {
    return true;
  }

  ADD_FAILURE() << "Failed to run WPR command: '" << cmd_name() << "'!";
  return false;
}

bool WebPageReplayServerWrapper::RunWebPageReplayCmd(
    const std::vector<std::string>& args) {
  // Allow the function to block. Otherwise the subsequent call to
  // base::PathExists will fail. base::PathExists must be called from
  // a scope that allows blocking.
  base::ScopedAllowBlockingForTesting allow_blocking;

  base::LaunchOptions options = base::LaunchOptionsForTest();
  base::FilePath exe_dir;
  if (!base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &exe_dir)) {
    ADD_FAILURE() << "Failed to extract the Chromium source directory!";
    return false;
  }

  base::FilePath web_page_replay_binary_dir = exe_dir.AppendASCII("third_party")
                                                  .AppendASCII("catapult")
                                                  .AppendASCII("telemetry")
                                                  .AppendASCII("telemetry")
                                                  .AppendASCII("bin");
  options.current_directory = web_page_replay_binary_dir;

#if BUILDFLAG(IS_WIN)
  base::FilePath wpr_executable_binary =
      base::FilePath(FILE_PATH_LITERAL("win"))
          .AppendASCII("AMD64")
          .AppendASCII("wpr.exe");
#elif BUILDFLAG(IS_MAC)
  base::FilePath wpr_executable_binary =
      base::FilePath(FILE_PATH_LITERAL("mac"))
#if defined(ARCH_CPU_ARM64)
          .AppendASCII("arm64")
#elif defined(ARCH_CPU_X86_64)
          .AppendASCII("x86_64")
#else
#error Mac CPU arch is not supported.
#endif
          .AppendASCII("wpr");
#elif BUILDFLAG(IS_POSIX)
  base::FilePath wpr_executable_binary =
      base::FilePath(FILE_PATH_LITERAL("linux"))
          .AppendASCII("x86_64")
          .AppendASCII("wpr");
#else
#error Platform is not supported.
#endif
  base::CommandLine full_command(
      web_page_replay_binary_dir.Append(wpr_executable_binary));
  full_command.AppendArg(cmd_name());

  // Ask web page replay to use the custom certificate and key files used to
  // make the web page captures.
  // The capture files used in these browser tests are also used on iOS to
  // test autofill.
  // The custom cert and key files are different from those of the official
  // WPR releases. The custom files are made to work on iOS.
  base::FilePath src_dir;
  if (!base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &src_dir)) {
    ADD_FAILURE() << "Failed to extract the Chromium source directory!";
    return false;
  }

  base::FilePath web_page_replay_support_file_dir =
      src_dir.AppendASCII("components")
          .AppendASCII("test")
          .AppendASCII("data")
          .AppendASCII("autofill")
          .AppendASCII("web_page_replay_support_files");
  full_command.AppendArg(base::StringPrintf(
      "--https_cert_file=%s,%s",
      FilePathToUTF8(
          web_page_replay_support_file_dir.AppendASCII("wpr_cert.pem").value())
          .c_str(),
      FilePathToUTF8(
          web_page_replay_support_file_dir.AppendASCII("ecdsa_cert.pem")
              .value())
          .c_str()));
  full_command.AppendArg(base::StringPrintf(
      "--https_key_file=%s,%s",
      FilePathToUTF8(
          web_page_replay_support_file_dir.AppendASCII("wpr_key.pem").value())
          .c_str(),
      FilePathToUTF8(
          web_page_replay_support_file_dir.AppendASCII("ecdsa_key.pem").value())
          .c_str()));

  for (const auto& arg : extra_args_) {
    full_command.AppendArg(arg);
  }

  for (const auto& arg : args)
    full_command.AppendArg(arg);

  VLOG(1) << full_command.GetArgumentsString();

  web_page_replay_server_ = base::LaunchProcess(full_command, options);
  return true;
}

// ProfileDataController ------------------------------------------------------
ProfileDataController::ProfileDataController()
    : profile_(autofill::test::GetIncompleteProfile2()),
      card_(autofill::CreditCard(
          base::Uuid::GenerateRandomV4().AsLowercaseString(),
          "http://www.example.com")) {

  // Initialize the credit card with default values, in case the test recipe
  // file does not contain pre-saved credit card info.
  autofill::test::SetCreditCardInfo(&card_, "Buddy Holly", "5187654321098765",
                                    "10", "2998", "1");
}

ProfileDataController::~ProfileDataController() = default;

bool ProfileDataController::AddAutofillProfileInfo(
    const std::string& field_type,
    const std::string& field_value) {
  std::optional<autofill::FieldType> type = StringToFieldType(field_type);
  if (!type.has_value()) {
    ADD_FAILURE() << "Unable to recognize autofill field type '" << field_type
                  << "'!";
    return false;
  }

  // PhoneNumber only allows PHONE_HOME_WHOLE_NUMBER to be set directly, so if
  // any other phone type is set, convert it to PHONE_HOME_WHOLE_NUMBER.
  if (GroupTypeOfFieldType(type.value()) == autofill::FieldTypeGroup::kPhone &&
      type.value() != autofill::FieldType::PHONE_HOME_WHOLE_NUMBER) {
    type = autofill::FieldType::PHONE_HOME_WHOLE_NUMBER;
  }

  if (base::StartsWith(field_type, "HTML_TYPE_CREDIT_CARD_",
                       base::CompareCase::INSENSITIVE_ASCII) ||
      base::StartsWith(field_type, "CREDIT_CARD_",
                       base::CompareCase::INSENSITIVE_ASCII)) {
    if (type == autofill::CREDIT_CARD_VERIFICATION_CODE) {
      cvc_ = base::UTF8ToUTF16(field_value);
    }
    card_.SetRawInfo(type.value(), base::UTF8ToUTF16(field_value));
  } else {
    profile_.SetRawInfo(type.value(), base::UTF8ToUTF16(field_value));
  }

  return true;
}

// TestRecipeReplayer ---------------------------------------------------------
TestRecipeReplayer::TestRecipeReplayer(
    Browser* browser,
    TestRecipeReplayChromeFeatureActionExecutor* feature_action_executor)
    : browser_(browser), feature_action_executor_(feature_action_executor) {
  CleanupSiteData();
  // Bypass permission dialogs.
  permissions::PermissionRequestManager::FromWebContents(GetWebContents())
      ->set_auto_response_for_test(
          permissions::PermissionRequestManager::ACCEPT_ALL);
}

TestRecipeReplayer::~TestRecipeReplayer() {
  // If there are still cookies at the time the browser test shuts down,
  // Chrome's SQL lite persistent cookie store will crash.
  CleanupSiteData();
  EXPECT_TRUE(web_page_replay_server_wrapper()->Stop())
      << "Cannot stop the local Web Page Replay server.";
}

bool TestRecipeReplayer::ReplayTest(
    const base::FilePath& capture_file_path,
    const base::FilePath& recipe_file_path,
    const std::optional<base::FilePath>& command_file_path) {
  logging::SetMinLogLevel(logging::LOGGING_WARNING);
  if (!web_page_replay_server_wrapper()->Start(capture_file_path))
    return false;
  if (OverrideTimeClock(capture_file_path)) {
    VLOG(1) << "OverrideTimeClock was set to:" << base::Time::Now();
  }
  return ReplayRecordedActions(recipe_file_path, command_file_path);
}

const std::vector<testing::AssertionResult>
TestRecipeReplayer::GetValidationFailures() const {
  return validation_failures_;
}

// Extracts the time of the wpr recording from the wpr archive file and
// overrides the base::Time::Now() to match that time.
bool TestRecipeReplayer::OverrideTimeClock(
    const base::FilePath capture_file_path) {
  std::string json_text;
  {
    base::ScopedAllowBlockingForTesting allow_blocking;
    if (!base::ReadFileToString(capture_file_path, &json_text)) {
      VLOG(1) << kTimeClockOverrideNotSetMessage << "Could not read file";
      return false;
    }
  }
  // Decompress the json text from gzip.
  std::string decompressed_json_text;
  if (!compression::GzipUncompress(json_text, &decompressed_json_text)) {
    VLOG(1) << kTimeClockOverrideNotSetMessage
            << "Could not gzip decompress file";
    return false;
  }
  // Convert the file text into a json object.
  std::optional<base::Value> parsed_json = base::JSONReader::Read(
      decompressed_json_text, base::JSON_PARSE_CHROMIUM_EXTENSIONS);
  if (!parsed_json) {
    VLOG(1) << kTimeClockOverrideNotSetMessage << "Failed to deserialize json";
    return false;
  }

  const std::optional<double> time_value =
      parsed_json->GetDict().FindDouble("DeterministicTimeSeedMs");
  if (!time_value) {
    VLOG(1) << kTimeClockOverrideNotSetMessage
            << "No DeterministicTimeSeedMs found";
    return false;
  }

  TimeOverrideHelper::current_time =
      base::Time::FromMillisecondsSinceUnixEpoch(*time_value);
  time_override_ = std::make_unique<base::subtle::ScopedTimeClockOverrides>(
      &TimeOverrideHelper::TimeNow,
      /*time_ticks_override=*/nullptr,
      /*thread_ticks_override=*/nullptr);
  return true;
}

// static
void TestRecipeReplayer::SetUpHostResolverRules(
    base::CommandLine* command_line) {
  // Direct traffic to the Web Page Replay server.
  command_line->AppendSwitchASCII(
      network::switches::kHostResolverRules,
      base::StringPrintf(
          "MAP *:80 127.0.0.1:%d,"
          "MAP *:443 127.0.0.1:%d,"
          // Set to always exclude, allows cache_replayer overwrite
          "EXCLUDE clients1.google.com,"
          "EXCLUDE content-autofill.googleapis.com,"
          "EXCLUDE localhost",
          kHostHttpPort, kHostHttpsPort));
}

// static
void TestRecipeReplayer::SetUpCommandLine(base::CommandLine* command_line) {
  command_line->AppendSwitchASCII(
      network::switches::kIgnoreCertificateErrorsSPKIList,
      kWebPageReplayCertSPKI);
  command_line->AppendSwitch(switches::kStartMaximized);
  // Since we are adding via ScopedFeatureList for test features required, we
  // need to explicitly also enable field trials.
  command_line->AppendSwitch(
      variations::switches::kEnableFieldTrialTestingConfig);
}

TestRecipeReplayChromeFeatureActionExecutor*
TestRecipeReplayer::feature_action_executor() {
  return feature_action_executor_;
}

Browser* TestRecipeReplayer::browser() {
  return browser_;
}

WebPageReplayServerWrapper*
TestRecipeReplayer::web_page_replay_server_wrapper() {
  return web_page_replay_server_wrapper_.get();
}

content::WebContents* TestRecipeReplayer::GetWebContents() {
  return browser_->tab_strip_model()->GetActiveWebContents();
}

namespace {
// Runs the given closure if the `WebContent`'s main frame changes.
class RenderFrameHostChangedObserver : public content::WebContentsObserver {
 public:
  RenderFrameHostChangedObserver(content::WebContents* wc,
                                 base::OnceClosure closure)
      : content::WebContentsObserver(wc), closure_(std::move(closure)) {}
  void RenderFrameHostChanged(content::RenderFrameHost* old_host,
                              content::RenderFrameHost* new_host) override {
    changed_ = true;
    std::move(closure_).Run();
  }
  bool changed() { return changed_; }

 private:
  base::OnceClosure closure_;
  bool changed_ = false;
};
}  // namespace

void TestRecipeReplayer::WaitTillPageIsIdle(
    base::TimeDelta continuous_paint_timeout) {
  // Loop continually while WebContents are waiting for response or loading.
  // page_is_loading is expectedWaitTillPageIsIdle to always got to False
  // eventually, but adding a timeout as a fallback.
  base::TimeTicks finished_load_time = base::TimeTicks::Now();
  while (true) {
    {
      base::RunLoop heart_beat;
      base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
          FROM_HERE, heart_beat.QuitClosure(), wait_for_idle_loop_length);
      heart_beat.Run();
    }
    bool page_is_loading = GetWebContents()->IsWaitingForResponse() ||
                           GetWebContents()->IsLoading();
    if (!page_is_loading)
      break;
    if ((base::TimeTicks::Now() - finished_load_time) >
        continuous_paint_timeout) {
      VLOG(1) << "Page is still loading after "
              << visual_update_timeout.InSeconds()
              << " seconds. Bailing because timeout was reached.";
      break;
    }
  }
  finished_load_time = base::TimeTicks::Now();
  bool frame_changed = false;
  while (true) {
    // Now, rely on the render frame count to be the indicator of page activity.
    // Once all the frames are drawn, we're free to continue.
    content::RenderFrameSubmissionObserver frame_submission_observer(
        GetWebContents());
    base::RunLoop heart_beat;
    base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
        FROM_HERE, heart_beat.QuitClosure(), wait_for_idle_loop_length);
    // `frame_submission_observer` holds a reference to metadata from a frame
    // that will be destroyed if a navigation occurs. We need to destroy the
    // observer before the frame is destroyed to avoid a dangling raw
    // pointer. See https://crbug.com/396232961.
    RenderFrameHostChangedObserver frame_observer(GetWebContents(),
                                                  heart_beat.QuitClosure());
    heart_beat.Run();
    if (frame_observer.changed()) {
      VLOG(1) << "The render frame has changed.";
      frame_changed = true;
      break;
    } else if (frame_submission_observer.render_frame_count() == 0) {
      // If the renderer has stopped submitting frames
      VLOG(1) << "The renderer has stopped submitting frames.";
      break;
    } else if ((base::TimeTicks::Now() - finished_load_time) >
               continuous_paint_timeout) {
      // `continuous_paint_timeout` has expired since Chrome loaded the page.
      // During this period of time, Chrome has been continuously painting
      // the page. In this case, the page is probably idle, but a bug, a
      // blinking caret or a persistent animation is keeping the
      // `render_frame_count` from reaching zero. Exit.
      VLOG(1) << "Wait for render frame count timed out after "
              << continuous_paint_timeout.InSeconds()
              << " seconds with the frame count still at: "
              << frame_submission_observer.render_frame_count();
      break;
    }
  }
  // Start waiting on the new frame.
  if (frame_changed) {
    WaitTillPageIsIdle(continuous_paint_timeout);
  }
}

bool TestRecipeReplayer::WaitForVisualUpdate(base::TimeDelta timeout) {
  base::TimeTicks start_time = base::TimeTicks::Now();
  content::RenderFrameSubmissionObserver frame_submission_observer(
      GetWebContents());
  while (frame_submission_observer.render_frame_count() == 0) {
    base::RunLoop heart_beat;
    base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
        FROM_HERE, heart_beat.QuitClosure(), wait_for_idle_loop_length);
    heart_beat.Run();
    if ((base::TimeTicks::Now() - start_time) > timeout) {
      return false;
    }
  }
  return true;
}

void TestRecipeReplayer::CleanupSiteData() {
  // Navigate to about:blank, then clear the browser cache.
  // Navigating to about:blank before clearing the cache ensures that
  // the cleanup is thorough and nothing is held.
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser_, GURL(url::kAboutBlankURL)));
  content::BrowsingDataRemover* remover =
      browser_->profile()->GetBrowsingDataRemover();
  content::BrowsingDataRemoverCompletionObserver completion_observer(remover);
  remover->RemoveAndReply(
      base::Time(), base::Time::Max(),
      content::BrowsingDataRemover::DATA_TYPE_COOKIES,
      content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
      &completion_observer);
  completion_observer.BlockUntilCompletion();
}

bool TestRecipeReplayer::ReplayRecordedActions(
    const base::FilePath& recipe_file_path,
    const std::optional<base::FilePath>& command_file_path) {
  std::optional<base::Value::Dict> recipe = ReadRecipeFile(recipe_file_path);
  if (!recipe) {
    return false;
  }
  if (!InitializeBrowserToExecuteRecipe(recipe.value())) {
    return false;
  }

  // Iterate through and execute each action in the recipe.
  base::Value::List* action_list = recipe.value().FindList("actions");
  if (!action_list) {
    ADD_FAILURE() << "Failed to extract action list from the recipe!";
    return false;
  }

  ExecutionState execution_state{.length =
                                     static_cast<int>(action_list->size())};
  if (command_file_path.has_value()) {
    execution_state.limit = 0;  // Stop execution initially in debug mode.
    PrintDebugInstructions(command_file_path.value());
  }

  while (execution_state.index < execution_state.length) {
    if (execution_state.pause_on_failure &&
        (testing::Test::HasNonfatalFailure() ||
         testing::Test::HasFatalFailure() || validation_failures_.size() > 0)) {
      // If set to pause on a failure, move limit to current, but then reset
      // `pause_on_failure` so it can continue if the user requests.
      execution_state.limit = execution_state.index;
      execution_state.pause_on_failure = false;
    }
    if (command_file_path.has_value()) {
      while (execution_state.limit <= execution_state.index) {
        bool thread_finished = false;
        base::ThreadPool::PostTaskAndReplyWithResult(
            FROM_HERE, {base::MayBlock()},
            base::BindOnce(&ProcessCommands, execution_state, action_list,
                           command_file_path.value()),
            base::BindOnce(
                [](ExecutionState* execution_state, bool* finished,
                   ExecutionState new_execution_state) {
                  *execution_state = new_execution_state;
                  *finished = true;
                },
                &execution_state, &thread_finished));
        while (!thread_finished) {
          base::RunLoop run_loop;
          base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
              FROM_HERE, run_loop.QuitClosure(), base::Seconds(1));
          run_loop.Run();
        }
      }
    }
    VLOG(1) << "Proceeding with execution with action " << execution_state.index
            << " of " << execution_state.length << ": "
            << (*action_list)[execution_state.index];

    if (!(*action_list)[execution_state.index].is_dict()) {
      ADD_FAILURE()
          << "Failed to extract an individual action from the recipe!";
      return false;
    }

    base::Value::Dict action =
        std::move((*action_list)[execution_state.index].GetDict());
    std::optional<std::string> type =
        FindPopulateString(action, "type", "action type");

    if (!type)
      return false;
    if (base::CompareCaseInsensitiveASCII(*type, "autofill") == 0) {
      if (!ExecuteAutofillAction(std::move(action)))
        return false;
    } else if (base::CompareCaseInsensitiveASCII(*type, "click") == 0) {
      if (!ExecuteClickAction(std::move(action)))
        return false;
    } else if (base::CompareCaseInsensitiveASCII(*type, "clickIfNotSeen") ==
               0) {
      if (!ExecuteClickIfNotSeenAction(std::move(action)))
        return false;
    } else if (base::CompareCaseInsensitiveASCII(*type, "closeTab") == 0) {
      if (!ExecuteCloseTabAction(std::move(action)))
        return false;
    } else if (base::CompareCaseInsensitiveASCII(*type, "coolOff") == 0) {
      if (!ExecuteCoolOffAction(std::move(action)))
        return false;
    } else if (base::CompareCaseInsensitiveASCII(*type, "executeScript") == 0) {
      if (!ExecuteRunCommandAction(std::move(action)))
        return false;
    } else if (base::CompareCaseInsensitiveASCII(*type, "hover") == 0) {
      if (!ExecuteHoverAction(std::move(action)))
        return false;
    } else if (base::CompareCaseInsensitiveASCII(*type, "loadPage") == 0) {
      if (!ExecuteForceLoadPage(std::move(action)))
        return false;
    } else if (base::CompareCaseInsensitiveASCII(*type, "pressEnter") == 0) {
      if (!ExecutePressEnterAction(std::move(action)))
        return false;
    } else if (base::CompareCaseInsensitiveASCII(*type, "pressEscape") == 0) {
      if (!ExecutePressEscapeAction(std::move(action)))
        return false;
    } else if (base::CompareCaseInsensitiveASCII(*type, "pressSpace") == 0) {
      if (!ExecutePressSpaceAction(std::move(action)))
        return false;
    } else if (base::CompareCaseInsensitiveASCII(*type, "savePassword") == 0) {
      if (!ExecuteSavePasswordAction(std::move(action)))
        return false;
    } else if (base::CompareCaseInsensitiveASCII(*type, "select") == 0) {
      if (!ExecuteSelectDropdownAction(std::move(action)))
        return false;
    } else if (base::CompareCaseInsensitiveASCII(*type, "type") == 0) {
      if (!ExecuteTypeAction(std::move(action)))
        return false;
    } else if (base::CompareCaseInsensitiveASCII(*type, "typePassword") == 0) {
      if (!ExecuteTypePasswordAction(std::move(action)))
        return false;
    } else if (base::CompareCaseInsensitiveASCII(*type, "updatePassword") ==
               0) {
      if (!ExecuteUpdatePasswordAction(std::move(action)))
        return false;
    } else if (base::CompareCaseInsensitiveASCII(*type, "validateField") == 0) {
      if (!ExecuteValidateFieldValueAction(std::move(action)))
        return false;
    } else if (base::CompareCaseInsensitiveASCII(
                   *type, "validatePasswordGenerationPrompt") == 0) {
      if (!ExecuteValidatePasswordGenerationPromptAction(std::move(action)))
        return false;
    } else if (base::CompareCaseInsensitiveASCII(
                   *type, "validateNoSavePasswordPrompt") == 0) {
      if (!ExecuteValidateNoSavePasswordPromptAction(std::move(action)))
        return false;
    } else if (base::CompareCaseInsensitiveASCII(
                   *type, "validatePasswordSaveFallback") == 0) {
      if (!ExecuteValidateSaveFallbackAction(std::move(action)))
        return false;
    } else if (base::CompareCaseInsensitiveASCII(*type, "waitFor") == 0) {
      if (!ExecuteWaitForStateAction(std::move(action)))
        return false;
    } else if (base::CompareCaseInsensitiveASCII(*type, "breakpoint") == 0) {
      execution_state.limit = execution_state.index + 1;
    } else {
      ADD_FAILURE() << "Unrecognized action type: " << *type;
    }

    ++execution_state.index;
  }

  return true;
}

// Functions for deserializing and executing actions from the test recipe
// JSON object.
bool TestRecipeReplayer::InitializeBrowserToExecuteRecipe(
    base::Value::Dict& recipe) {
  // Setup any saved address and credit card at the start of the test.
  auto* autofill_profile_container = recipe.Find("autofillProfile");

  if (autofill_profile_container) {
    if (!autofill_profile_container->is_list()) {
      ADD_FAILURE() << "Save Autofill Profile is not a list!";
      return false;
    }

    if (!SetupSavedAutofillProfile(
            std::move(*autofill_profile_container).TakeList())) {
      return false;
    }
  }

  // Setup any saved passwords at the start of the test.
  auto* saved_password_container = recipe.Find("passwordManagerProfiles");

  if (saved_password_container) {
    if (!saved_password_container->is_list()) {
      ADD_FAILURE() << "Saved Password List is not a list!";
      return false;
    }

    if (!SetupSavedPasswords(std::move(*saved_password_container).TakeList())) {
      return false;
    }
  }

  // Extract the starting URL from the test recipe.
  auto* starting_url = recipe.FindString("startingURL");
  if (!starting_url) {
    ADD_FAILURE() << "Failed to extract the starting url from the recipe!";
    return false;
  }

  // Navigate to the starting URL, wait for the page to complete loading.
  if (!content::ExecJs(GetWebContents(),
                       base::StringPrintf("window.location.href = '%s';",
                                          starting_url->c_str()))) {
    ADD_FAILURE() << "Failed to navigate Chrome to '" << *starting_url << "!";
    return false;
  }

  WaitTillPageIsIdle();
  return true;
}

bool TestRecipeReplayer::ExecuteAutofillAction(base::Value::Dict action) {
  std::string xpath;
  content::RenderFrameHost* frame;
  if (!ExtractFrameAndVerifyElement(action, &xpath, &frame))
    return false;
  std::vector<std::string> frame_path;
  if (!GetIFramePathFromAction(action, &frame_path))
    return false;

  VLOG(1) << "Invoking Chrome Autofill on `" << xpath << "`.";
  // Clear the input box first, in case a previous value is there.
  // If the text input box is not clear, pressing the down key will not
  // bring up the autofill suggestion box.
  // This can happen on sites that requires the user to sign in. After
  // signing in, the site fills the form with the user's profile
  // information.
  if (!ExecuteJavaScriptOnElementByXpath(
          frame, xpath,
          "automation_helper.setInputElementValue(target, ``);")) {
    ADD_FAILURE() << "Failed to clear the input field value!";
    return false;
  }

  std::string autofill_triggered_field_type;
  if (GetElementProperty(frame, xpath,
                         "return target.getAttribute('autofill-prediction');",
                         &autofill_triggered_field_type)) {
    VLOG(1) << "The field's Chrome Autofill annotation: "
            << autofill_triggered_field_type << " during autofill form step.";
  } else {
    VLOG(1) << "Failed to obtain the field's Chrome Autofill annotation during "
               "autofill form step!";
  }
  if (!feature_action_executor()->AutofillForm(
          xpath, frame_path, kAutofillActionNumRetries, frame,
          StringToFieldType(autofill_triggered_field_type))) {
    return false;
  }
  WaitTillPageIsIdle(kAutofillActionWaitForVisualUpdateTimeout);
  return true;
}

bool TestRecipeReplayer::ExecuteClickAction(base::Value::Dict action) {
  std::string xpath;
  content::RenderFrameHost* frame;
  if (!ExtractFrameAndVerifyElement(action, &xpath, &frame)) {
    return false;
  }

  VLOG(1) << "Left mouse clicking `" << xpath << "`.";
  if (!ScrollElementIntoView(xpath, frame)) {
    return false;
  }
  WaitTillPageIsIdle(scroll_wait_timeout);
  if (!ExtractFrameAndVerifyElement(action, &xpath, &frame)) {
    return false;
  }

  gfx::Rect rect;
  if (!GetBoundingRectOfTargetElement(xpath, frame, &rect)) {
    return false;
  }
  if (!SimulateLeftMouseClickAt(rect.CenterPoint(), frame)) {
    return false;
  }

  WaitTillPageIsIdle();
  return true;
}

bool TestRecipeReplayer::ExecuteClickIfNotSeenAction(base::Value::Dict action) {
  std::string xpath;
  content::RenderFrameHost* frame;
  if (ExtractFrameAndVerifyElement(action, &xpath, &frame, false, false,
                                   true)) {
    return true;
  } else {
    // If the selector wasn't found, take the clickSelector and make it the
    // selector to attempt a click with that element instead.
    std::optional<std::string> click_xpath_text =
        FindPopulateString(action, "clickSelector", "click xpath selector");

    action.Set("selector", *click_xpath_text);

    return ExecuteClickAction(std::move(action));
  }
}

bool TestRecipeReplayer::ExecuteCloseTabAction(base::Value::Dict action) {
  VLOG(1) << "Closing Active Tab";
  browser_->tab_strip_model()->CloseSelectedTabs();
  return true;
}

bool TestRecipeReplayer::ExecuteCoolOffAction(base::Value::Dict action) {
  base::RunLoop heart_beat;
  base::TimeDelta cool_off_time = cool_off_action_timeout;
  base::Value* pause_time_container = action.Find("pauseTimeSec");
  if (pause_time_container) {
    if (!pause_time_container->is_int()) {
      ADD_FAILURE() << "Pause time is not an integer!";
      return false;
    }
    int seconds = pause_time_container->GetInt();
    cool_off_time = base::Seconds(seconds);
  }
  base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
      FROM_HERE, heart_beat.QuitClosure(), cool_off_time);
  VLOG(1) << "Pausing execution for '" << cool_off_time.InSeconds()
          << "' seconds";
  heart_beat.Run();

  return true;
}

bool TestRecipeReplayer::ExecuteHoverAction(base::Value::Dict action) {
  std::string xpath;
  content::RenderFrameHost* frame;
  if (!ExtractFrameAndVerifyElement(action, &xpath, &frame)) {
    return false;
  }

  VLOG(1) << "Hovering over `" << xpath << "`.";

  if (!ScrollElementIntoView(xpath, frame)) {
    return false;
  }
  WaitTillPageIsIdle(scroll_wait_timeout);
  if (!ExtractFrameAndVerifyElement(action, &xpath, &frame)) {
    return false;
  }

  gfx::Rect rect;
  if (!GetBoundingRectOfTargetElement(xpath, frame, &rect)) {
    return false;
  }

  if (!SimulateMouseHoverAt(frame, rect.CenterPoint())) {
    return false;
  }

  if (!WaitForVisualUpdate()) {
    ADD_FAILURE() << "The page did not respond to a mouse hover action!";
    return false;
  }

  return true;
}

bool TestRecipeReplayer::ExecuteForceLoadPage(base::Value::Dict action) {
  bool should_force = action.FindBool("force").value_or(false);
  if (!should_force) {
    return true;
  }

  std::optional<std::string> url =
      FindPopulateString(action, "url", "Force Load URL");
  if (!url)
    return false;
  VLOG(1) << "Making explicit URL redirect to '" << *url << "'";
  EXPECT_TRUE(ui_test_utils::NavigateToURL(browser_, GURL(*url)));

  WaitTillPageIsIdle();

  return true;
}

bool TestRecipeReplayer::ExecutePressEnterAction(base::Value::Dict action) {
  std::string xpath;
  content::RenderFrameHost* frame;
  if (!ExtractFrameAndVerifyElement(action, &xpath, &frame))
    return false;

  VLOG(1) << "Pressing 'Enter' on `" << xpath << "`.";
  SimulateKeyPressWrapper(content::WebContents::FromRenderFrameHost(frame),
                          ui::DomKey::ENTER);
  WaitTillPageIsIdle();
  return true;
}

bool TestRecipeReplayer::ExecutePressEscapeAction(base::Value::Dict action) {
  VLOG(1) << "Pressing 'Esc' in the current frame";
  SimulateKeyPressWrapper(GetWebContents(), ui::DomKey::ESCAPE);
  WaitTillPageIsIdle();
  return true;
}

bool TestRecipeReplayer::ExecutePressSpaceAction(base::Value::Dict action) {
  std::string xpath;
  content::RenderFrameHost* frame;
  if (!ExtractFrameAndVerifyElement(action, &xpath, &frame, true))
    return false;

  VLOG(1) << "Pressing 'Space' on `" << xpath << "`.";
  SimulateKeyPressWrapper(content::WebContents::FromRenderFrameHost(frame),
                          ui::DomKey::FromCharacter(' '));
  WaitTillPageIsIdle();
  return true;
}

bool TestRecipeReplayer::ExecuteRunCommandAction(base::Value::Dict action) {
  // Extract the list of JavaScript commands into a vector.
  std::vector<std::string> commands;

  base::Value::List* list = action.FindList("commands");
  if (!list) {
    ADD_FAILURE() << "Failed to extract commands list from action";
    return false;
  }

  for (const auto& command : *list) {
    if (!command.is_string()) {
      ADD_FAILURE() << "command is not a string: " << command;
      return false;
    }
    commands.push_back(command.GetString());
  }

  content::RenderFrameHost* frame;
  if (!GetTargetFrameFromAction(action, &frame)) {
    return false;
  }

  VLOG(1) << "Running JavaScript commands on the page.";

  // Execute the commands.
  for (const std::string& command : commands) {
    if (!content::ExecJs(frame, command)) {
      ADD_FAILURE() << "Failed to execute JavaScript command `" << command
                    << "`!";
      return false;
    }
    // Wait in case the JavaScript command triggers page load or layout
    // changes.
    WaitTillPageIsIdle();
  }

  return true;
}

bool TestRecipeReplayer::ExecuteSavePasswordAction(base::Value::Dict action) {
  VLOG(1) << "Save password.";

  if (!feature_action_executor()->SavePassword())
    return false;

  bool stored_cred;
  if (!HasChromeStoredCredential(action, &stored_cred))
    return false;

  if (!stored_cred) {
    ADD_FAILURE() << "Chrome did not save the credential!";
    return false;
  }

  return true;
}

bool TestRecipeReplayer::ExecuteSelectDropdownAction(base::Value::Dict action) {
  std::optional<int> index = action.FindInt("index");
  if (!index.has_value()) {
    ADD_FAILURE() << "Failed to extract Selection Index from action";
    return false;
  }

  std::string xpath;
  content::RenderFrameHost* frame;
  if (!ExtractFrameAndVerifyElement(action, &xpath, &frame))
    return false;

  VLOG(1) << "Select option '" << *index << "' from `" << xpath << "`.";
  if (!ExecuteJavaScriptOnElementByXpath(
          frame, xpath,
          base::StringPrintf(
              "automation_helper"
              "  .selectOptionFromDropDownElementByIndex(target, %d);",
              *index))) {
    ADD_FAILURE() << "Failed to select drop down option with JavaScript!";
    return false;
  }
  WaitTillPageIsIdle();
  return true;
}

bool TestRecipeReplayer::ExecuteTypeAction(base::Value::Dict action) {
  std::optional<std::string> value =
      FindPopulateString(action, "value", "typing value");
  if (!value)
    return false;

  std::string xpath;
  content::RenderFrameHost* frame;
  if (!ExtractFrameAndVerifyElement(action, &xpath, &frame))
    return false;

  VLOG(1) << "Typing '" << *value << "' inside `" << xpath << "`.";
  if (!ExecuteJavaScriptOnElementByXpath(
          frame, xpath,
          base::StringPrintf(
              "automation_helper.setInputElementValue(target, `%s`);",
              value->c_str()))) {
    ADD_FAILURE() << "Failed to type inside input element with JavaScript!";
    return false;
  }
  WaitTillPageIsIdle();
  return true;
}

bool TestRecipeReplayer::ExecuteTypePasswordAction(base::Value::Dict action) {
  std::string xpath;
  content::RenderFrameHost* frame;
  if (!ExtractFrameAndVerifyElement(action, &xpath, &frame, true))
    return false;

  std::optional<std::string> value =
      FindPopulateString(action, "value", "password text");
  if (!value)
    return false;

  // Clear the password field first, in case a previous value is there.
  if (!ExecuteJavaScriptOnElementByXpath(
          frame, xpath,
          "automation_helper.setInputElementValue(target, ``);")) {
    ADD_FAILURE() << "Failed to execute JavaScript to clear the input value!";
    return false;
  }

  VLOG(1) << "Typing '" << *value << "' inside `" << xpath << "`.";
  content::WebContents* web_contents =
      content::WebContents::FromRenderFrameHost(frame);
  for (size_t index = 0; index < value->size(); index++) {
    SimulateKeyPressWrapper(web_contents,
                            ui::DomKey::FromCharacter(value->at(index)));
  }
  WaitTillPageIsIdle();
  return true;
}

bool TestRecipeReplayer::ExecuteUpdatePasswordAction(base::Value::Dict action) {
  VLOG(1) << "Update password.";

  if (!feature_action_executor()->UpdatePassword())
    return false;

  bool stored_cred;
  if (!HasChromeStoredCredential(action, &stored_cred))
    return false;

  if (!stored_cred) {
    ADD_FAILURE() << "Chrome did not update the credential!";
    return false;
  }

  return true;
}

bool TestRecipeReplayer::ExecuteValidateFieldValueAction(
    base::Value::Dict action) {
  std::string xpath;
  content::RenderFrameHost* frame;
  if (!ExtractFrameAndVerifyElement(action, &xpath, &frame, false, true))
    return false;

  base::Value* autofill_prediction_container =
      action.Find("expectedAutofillType");
  if (autofill_prediction_container) {
    if (!autofill_prediction_container->is_string()) {
      ADD_FAILURE() << "Autofill prediction is not a string!";
      return false;
    }

    // If we are validating the value of a Chrome autofilled field, print the
    // Chrome Autofill's field annotation for debugging purpose.
    std::string autofill_information;
    if (GetElementProperty(
            frame, xpath, "return target.getAttribute('autofill-information');",
            &autofill_information)) {
      VLOG(1) << autofill_information;
    } else {
      // Only used for logging purposes, so don't ADD_FAILURE() if it fails.
      VLOG(1) << "Failed to obtain the field's Chrome Autofill annotation!";
    }

    std::string expected_autofill_prediction_type =
        autofill_prediction_container->GetString();
    VLOG(1) << "Checking the field `" << xpath << "` has the autofill type '"
            << expected_autofill_prediction_type << "'";
    ExpectElementPropertyEqualsAnyOf(
        frame, xpath, "return target.getAttribute('autofill-prediction');",
        {expected_autofill_prediction_type}, "autofill type mismatch",
        IgnoreCase(true));
  }

  std::optional<std::vector<std::string>> expected_values =
      FindPopulateStringVector(action, "expectedValues", AllowNull());
  std::optional<std::string> expected_value =
      FindPopulateString(action, "expectedValue", AllowNull());
  if (!!expected_values == !!expected_value) {
    ADD_FAILURE() << "Failed to extract 'expectedValue' xor 'expectedValues' "
                     "vector from container !";
    return false;
  }

  VLOG(1) << "Checking the field `" << xpath << "`.";
  if (expected_value) {
    ExpectElementPropertyEqualsAnyOf(frame, xpath, "return target.value;",
                                     {*expected_value}, "text value mismatch");
  }
  if (expected_values) {
    ExpectElementPropertyEqualsAnyOf(frame, xpath, "return target.value;",
                                     *expected_values, "text value mismatch");
  }
  return true;
}

bool TestRecipeReplayer::ExecuteValidateNoSavePasswordPromptAction(
    base::Value::Dict action) {
  VLOG(1) << "Verify that the page hasn't shown a save password prompt.";
  EXPECT_FALSE(feature_action_executor()->HasChromeShownSavePasswordPrompt());
  return true;
}

bool TestRecipeReplayer::ExecuteValidatePasswordGenerationPromptAction(
    base::Value::Dict action) {
  VLOG(1) << "Verify that an element is properly displaying or not displaying "
             "the password generation prompt";
  std::string xpath;
  content::RenderFrameHost* frame;
  if (!ExtractFrameAndVerifyElement(action, &xpath, &frame, true))
    return false;

  // Most common scenario is validating that the password generation prompt is
  // being shown, so if unspecified default to true.
  bool expect_to_be_shown = expect_to_be_shown =
      action.FindBool("shouldBeShown").value_or(true);

  // First, execute a click to focus on the field in question.
  ExecuteClickAction(std::move(action));

  // Validate that the password generation prompt is shown when expected.
  ValidatePasswordGenerationPromptState(frame, xpath, expect_to_be_shown);
  return true;
}

void TestRecipeReplayer::ValidatePasswordGenerationPromptState(
    const content::ToRenderFrameHost& frame,
    const std::string& element_xpath,
    bool expect_to_be_shown) {
  bool is_password_generation_prompt_showing =
      feature_action_executor()->IsChromeShowingPasswordGenerationPrompt();

  if (expect_to_be_shown != is_password_generation_prompt_showing) {
    std::string error_message =
        base::StrCat({"Field xpath: `", element_xpath, "` is",
                      is_password_generation_prompt_showing ? "" : " not",
                      " showing password generation prompt but it should",
                      expect_to_be_shown ? "" : " not", " be."});
    VLOG(1) << error_message;
    ADD_FAILURE() << error_message;
    validation_failures_.push_back(testing::AssertionFailure()
                                   << error_message);
  }
}

bool TestRecipeReplayer::ExecuteValidateSaveFallbackAction(
    base::Value::Dict action) {
  VLOG(1) << "Verify that Chrome shows the save fallback icon in the omnibox.";
  EXPECT_TRUE(feature_action_executor()->WaitForSaveFallback());
  return true;
}

bool TestRecipeReplayer::ExecuteWaitForStateAction(base::Value::Dict action) {
  // Extract the list of JavaScript assertions into a vector.
  std::vector<std::string> state_assertions;

  base::Value::List* list = action.FindList("assertions");
  if (!list) {
    ADD_FAILURE() << "Failed to extract wait assertions list from action";
    return false;
  }
  for (const base::Value& assertion : *list) {
    if (!assertion.is_string()) {
      ADD_FAILURE() << "Assertion is not a string: " << assertion;
      return false;
    }
    state_assertions.push_back(assertion.GetString());
  }

  content::RenderFrameHost* frame;
  VLOG(1) << "Waiting for page to reach a state.";

  // Wait for all of the assertions to become true on the current page.
  return WaitForStateChange(action, &frame, state_assertions,
                            default_action_timeout);
}

bool TestRecipeReplayer::GetTargetHTMLElementXpathFromAction(
    const base::Value::Dict& action,
    std::string* xpath) {
  xpath->clear();
  std::optional<std::string> xpath_text =
      FindPopulateString(action, "selector", "xpath selector");
  if (!xpath_text)
    return false;
  *xpath = *xpath_text;
  return true;
}

bool TestRecipeReplayer::GetTargetHTMLElementVisibilityEnumFromAction(
    const base::Value::Dict& action,
    int* visibility_enum_val) {
  const base::Value* visibility_container = action.Find("visibility");
  if (!visibility_container) {
    // By default, set the visibility to (visible | enabled | on_top), as
    // defined in
    // chrome/test/data/web_page_replay_go_helper_scripts/automation_helper.js
    *visibility_enum_val = 7;
    return true;
  }

  if (!visibility_container->is_int()) {
    ADD_FAILURE() << "visibility property is not an integer!";
    return false;
  }

  *visibility_enum_val = visibility_container->GetInt();
  return true;
}

bool TestRecipeReplayer::GetTargetFrameFromAction(
    const base::Value::Dict& action,
    content::RenderFrameHost** frame) {
  const base::Value* iframe_container = action.Find("context");
  if (!iframe_container) {
    ADD_FAILURE() << "Failed to extract the iframe context from action!";
    return false;
  }

  if (!iframe_container->is_dict()) {
    ADD_FAILURE() << "Failed to extract the iframe context object!";
    return false;
  }

  std::optional<bool> is_iframe_container =
      iframe_container->GetDict().FindBool("isIframe");
  if (!is_iframe_container) {
    ADD_FAILURE() << "Failed to extract isIframe from the iframe context! ";
    return false;
  }
  if (!is_iframe_container.value_or(false)) {
    *frame = GetWebContents()->GetPrimaryMainFrame();
    return true;
  }

  const base::Value* frame_name_container =
      iframe_container->GetDict().FindByDottedPath("browserTest.name");
  const base::Value* frame_origin_container =
      iframe_container->GetDict().FindByDottedPath("browserTest.origin");
  const base::Value* frame_url_container =
      iframe_container->GetDict().FindByDottedPath("browserTest.url");
  IFrameWaiter iframe_waiter(GetWebContents());

  if (frame_name_container != nullptr && !frame_name_container->is_string()) {
    ADD_FAILURE() << "Iframe name is not a string!";
    return false;
  }

  if (frame_origin_container != nullptr &&
      !frame_origin_container->is_string()) {
    ADD_FAILURE() << "Iframe origin is not a string!";
    return false;
  }

  if (frame_url_container != nullptr && !frame_url_container->is_string()) {
    ADD_FAILURE() << "Iframe url is not a string!";
    return false;
  }

  if (frame_name_container != nullptr) {
    std::string frame_name = frame_name_container->GetString();
    *frame = iframe_waiter.WaitForFrameMatchingName(frame_name);
  } else if (frame_origin_container != nullptr) {
    std::string frame_origin = frame_origin_container->GetString();
    *frame = iframe_waiter.WaitForFrameMatchingOrigin(GURL(frame_origin));
  } else if (frame_url_container != nullptr) {
    std::string frame_url = frame_url_container->GetString();
    *frame = iframe_waiter.WaitForFrameMatchingUrl(GURL(frame_url));
  } else {
    ADD_FAILURE() << "The recipe does not specify a way to find the iframe!";
  }

  if (*frame == nullptr) {
    ADD_FAILURE() << "Failed to find iframe!";
    return false;
  }

  return true;
}

bool TestRecipeReplayer::ExtractFrameAndVerifyElement(
    const base::Value::Dict& action,
    std::string* xpath,
    content::RenderFrameHost** frame,
    bool set_focus,
    bool relaxed_visibility,
    bool ignore_failure) {
  if (!GetTargetHTMLElementXpathFromAction(action, xpath)) {
    return false;
  }

  int visibility_enum_val;
  if (!GetTargetHTMLElementVisibilityEnumFromAction(action,
                                                    &visibility_enum_val)) {
    return false;
  }

  // If we're just validating we don't care about on_top-ness, as copied from
  // chrome/test/data/web_page_replay_go_helper_scripts/automation_helper.js
  // to TestRecipeReplayer::DomElementReadyState enum
  // So remove (DomElementReadyState::kReadyStateOnTop)
  if (relaxed_visibility) {
    visibility_enum_val &= ~kReadyStateOnTop;
  }

  if (!WaitForElementToBeReady(*xpath, visibility_enum_val, action, frame,
                               ignore_failure)) {
    return false;
  }

  if (set_focus) {
    std::vector<std::string> frame_path;
    if (!GetIFramePathFromAction(action, &frame_path))
      return false;

    if (!PlaceFocusOnElement(*xpath, frame_path, *frame))
      return false;
  }
  return true;
}

bool TestRecipeReplayer::GetIFramePathFromAction(
    const base::Value::Dict& action,
    std::vector<std::string>* iframe_path) {
  *iframe_path = std::vector<std::string>();

  const base::Value* iframe_container = action.Find("context");
  if (!iframe_container) {
    ADD_FAILURE() << "Failed to extract the iframe context from action!";
    return false;
  }

  if (!iframe_container->is_dict()) {
    ADD_FAILURE() << "Failed to extract the iframe context object!";
    return false;
  }

  const base::Value* iframe_path_container =
      iframe_container->GetDict().Find("path");
  if (!iframe_path_container) {
    // If the action does not have a path container, it would mean that:
    // 1. The target frame is the top level frame.
    // 2. The target frame is an iframe, but it is the top-level frame in its
    //    rendering process.
    return true;
  }
  if (!iframe_path_container->is_list()) {
    ADD_FAILURE() << "The action's iframe path is not a list!";
    return false;
  }
  for (const auto& xpath : iframe_path_container->GetList()) {
    if (!xpath.is_string()) {
      ADD_FAILURE() << "Failed to extract the iframe xpath from action!";
      return false;
    }
    iframe_path->push_back(xpath.GetString());
  }
  return true;
}

bool TestRecipeReplayer::GetIFrameOffsetFromIFramePath(
    const std::vector<std::string>& iframe_path,
    content::RenderFrameHost* frame,
    gfx::Vector2d* offset) {
  *offset = gfx::Vector2d(0, 0);

  for (auto it_xpath = iframe_path.begin(); it_xpath != iframe_path.end();
       it_xpath++) {
    content::RenderFrameHost* parent_frame = frame->GetParent();
    if (parent_frame == nullptr) {
      ADD_FAILURE() << "Trying to iterate past the top level frame!";
      return false;
    }

    gfx::Rect rect;
    if (!GetBoundingRectOfTargetElement(*it_xpath, parent_frame, &rect)) {
      ADD_FAILURE() << "Failed to extract position of iframe with xpath `"
                    << *it_xpath << "`!";
      return false;
    }

    *offset += rect.OffsetFromOrigin();
    frame = parent_frame;
  }

  return true;
}

bool TestRecipeReplayer::WaitForElementToBeReady(
    const std::string& xpath,
    const int visibility_enum_val,
    const base::Value::Dict& action,
    content::RenderFrameHost** frame,
    bool ignore_failure) {
  std::vector<std::string> state_assertions;
  state_assertions.push_back(base::StringPrintf(
      "return automation_helper.isElementWithXpathReady(`%s`, %d);",
      xpath.c_str(), visibility_enum_val));
  return WaitForStateChange(
      action, frame, state_assertions,
      ignore_failure ? click_fallback_timeout : default_action_timeout,
      ignore_failure);
}

bool TestRecipeReplayer::WaitForStateChange(
    const base::Value::Dict& action,
    content::RenderFrameHost** frame,
    const std::vector<std::string>& state_assertions,
    const base::TimeDelta& timeout,
    bool ignore_failure) {
  base::TimeTicks start_time = base::TimeTicks::Now();
  while (true) {
    if (!GetTargetFrameFromAction(action, frame)) {
      return false;
    }
    if (AllAssertionsPassed(*frame, state_assertions)) {
      return true;
    }
    if (base::TimeTicks::Now() - start_time > timeout) {
      if (!ignore_failure) {
        ADD_FAILURE() << "State change hasn't completed within timeout.";
      }
      return false;
    }
    WaitTillPageIsIdle();
  }
}

bool TestRecipeReplayer::AllAssertionsPassed(
    const content::ToRenderFrameHost& frame,
    const std::vector<std::string>& assertions) {
  // We may be dealing with a frame that is mid-/post-navigation. `EvalJs`
  // will fail if the frame is e.g. unloading or in back/forward-cache. Don't
  // even try unless the frame is active.
  if (frame.render_frame_host()->GetLifecycleState() !=
      content::RenderFrameHost::LifecycleState::kActive) {
    VLOG(1) << "Frame not active, not testing assertions. "
            << (int)frame.render_frame_host()->GetLifecycleState();
    return false;
  }
  for (const std::string& assertion : assertions) {
    content::EvalJsResult result =
        EvalJs(frame, base::StringPrintf("(function() {"
                                         "  try {"
                                         "    %s"
                                         "  } catch (ex) {}"
                                         "  return false;"
                                         "})();",
                                         assertion.c_str()));
    if (!result.is_ok()) {
      VLOG(1) << "'" << assertion << "' failed: " << result.ExtractError();
      return false;
    }
    if (!result.is_bool()) {
      VLOG(1) << "'" << assertion << "' failed: Did not return boolean.";
      return false;
    }
    if (!result.ExtractBool()) {
      VLOG(1) << "'" << assertion << "' failed: Returned false.";
      return false;
    }
  }
  return true;
}

bool TestRecipeReplayer::ExecuteJavaScriptOnElementByXpath(
    const content::ToRenderFrameHost& frame,
    const std::string& element_xpath,
    const std::string& execute_function_body,
    const base::TimeDelta& time_to_wait_for_element) {
  std::string js(base::StringPrintf(
      "try {"
      "  var element = automation_helper.getElementByXpath(`%s`);"
      "  (function(target) { %s })(element);"
      "} catch(ex) {}",
      element_xpath.c_str(), execute_function_body.c_str()));
  return ExecJs(frame, js);
}

bool TestRecipeReplayer::GetElementProperty(
    const content::ToRenderFrameHost& frame,
    const std::string& element_xpath,
    const std::string& get_property_function_body,
    std::string* property) {
  content::EvalJsResult result = content::EvalJs(
      frame, base::StringPrintf(
                 "(function() {"
                 "    var element = function() {"
                 "      return automation_helper.getElementByXpath(`%s`);"
                 "    }();"
                 "    return function(target){%s}(element);})();",
                 element_xpath.c_str(), get_property_function_body.c_str()));
  if (result.is_string()) {
    *property = result.ExtractString();
    return true;
  }
  *property = result.is_ok() ? "" : result.ExtractError();
  return false;
}

bool TestRecipeReplayer::ExpectElementPropertyEqualsAnyOf(
    const content::ToRenderFrameHost& frame,
    const std::string& element_xpath,
    const std::string& get_property_function_body,
    const std::vector<std::string>& expected_values,
    const std::string& validation_field,
    IgnoreCase ignore_case) {
  std::string actual_value;
  if (!GetElementProperty(frame, element_xpath, get_property_function_body,
                          &actual_value)) {
    ADD_FAILURE() << "Failed to extract element property! " << element_xpath
                  << ", " << get_property_function_body;
    return false;
  }

  auto is_expected = [ignore_case,
                      &actual_value](std::string_view expected_value) {
    return ignore_case
               ? base::EqualsCaseInsensitiveASCII(expected_value, actual_value)
               : expected_value == actual_value;
  };

  if (std::ranges::none_of(expected_values, is_expected)) {
    std::string error_message = base::StrCat(
        {"Field xpath: `", element_xpath, "` ", validation_field, ", ",
         "Expected: '", base::JoinString(expected_values, " or "),
         "', actual: '", actual_value, "'"});
    VLOG(1) << error_message;
    validation_failures_.push_back(testing::AssertionFailure()
                                   << error_message);
  }
  return true;
}

bool TestRecipeReplayer::ScrollElementIntoView(
    const std::string& element_xpath,
    content::RenderFrameHost* frame) {
  const std::string scroll_target_js(base::StringPrintf(
      "try {"
      "  const element = automation_helper.getElementByXpath(`%s`);"
      "  element.scrollIntoView({"
      "    block: 'center', inline: 'center'});"
      "  true;"
      "} catch(ex) {"
      "  false;"
      "}",
      element_xpath.c_str()));

  return EvalJs(frame, scroll_target_js).ExtractBool();
}

bool TestRecipeReplayer::PlaceFocusOnElement(
    const std::string& element_xpath,
    const std::vector<std::string>& iframe_path,
    content::RenderFrameHost* frame) {
  if (!ScrollElementIntoView(element_xpath, frame))
    return false;

  const std::string focus_on_target_field_js(
      base::StringPrintf("(function() {const element = "
                         "automation_helper.getElementByXpath(`%s`);"
                         "    if (document.activeElement !== element) {"
                         "      element.focus();"
                         "    }"
                         "    return document.activeElement === element;})();",
                         element_xpath.c_str()));

  content::EvalJsResult result =
      content::EvalJs(frame, focus_on_target_field_js);
  if (result.is_ok() && result.is_bool() && result.ExtractBool()) {
    return true;
  } else {
    VLOG(1) << "Failed to focus element through script:"
            << (result.is_ok()
                    ? (result.is_bool() ? "Returned false" : "Not a valid bool")
                    : result.ExtractError());

    // Failing focusing on an element through script, use the less preferred
    // method of left mouse clicking the element.
    gfx::Rect rect;
    if (!GetBoundingRectOfTargetElement(element_xpath, iframe_path, frame,
                                        &rect))
      return false;

    return SimulateLeftMouseClickAt(rect.CenterPoint(), frame);
  }
}

bool TestRecipeReplayer::GetBoundingRectOfTargetElement(
    const std::string& target_element_xpath,
    content::RenderFrameHost* frame,
    gfx::Rect* output_rect) {
  const std::string get_element_bounding_rect_js(base::StringPrintf(
      "(function() {"
      "   try {"
      "     const element = automation_helper.getElementByXpath(`%s`);"
      "     const rect = element.getBoundingClientRect();"
      "     return Math.round(rect.left) + ',' + "
      "            Math.round(rect.top) + ',' + "
      "            Math.round(rect.width) + ',' + "
      "            Math.round(rect.height);"
      "   } catch(ex) {}"
      "   return '';"
      "})();",
      target_element_xpath.c_str()));

  std::string rect_str =
      content::EvalJs(frame, get_element_bounding_rect_js).ExtractString();

  if (rect_str.empty()) {
    ADD_FAILURE() << "Failed to extract target element's bounding rect!";
    return false;
  }

  // Parse the bounding rect string to extract the element coordinates.
  std::vector<std::string_view> rect_components = base::SplitStringPiece(
      rect_str, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
  if (rect_components.size() != 4) {
    ADD_FAILURE() << "Wrong number of components in `" << rect_str << "`!";
    return false;
  }

  int x = 0;
  if (!base::StringToInt(rect_components[0], &x)) {
    ADD_FAILURE() << "Failed to extract target element's x coordinate from "
                  << "the string `" << rect_str[0] << "`!";
    return false;
  }
  int y = 0;
  if (!base::StringToInt(rect_components[1], &y)) {
    ADD_FAILURE() << "Failed to extract target element's y coordinate from "
                  << "the string `" << rect_str[1] << "`!";
    return false;
  }
  int width = 0;
  if (!base::StringToInt(rect_components[2], &width)) {
    ADD_FAILURE() << "Failed to extract target element's width from "
                  << "the string `" << rect_str[2] << "`!";
    return false;
  }
  int height = 0;
  if (!base::StringToInt(rect_components[3], &height)) {
    ADD_FAILURE() << "Failed to extract target element's height from "
                  << "the string `" << rect_str[3] << "`!";
    return false;
  }

  output_rect->set_x(x);
  output_rect->set_y(y);
  output_rect->set_width(width);
  output_rect->set_height(height);

  return true;
}

bool TestRecipeReplayer::GetBoundingRectOfTargetElement(
    const std::string& target_element_xpath,
    const std::vector<std::string>& iframe_path,
    content::RenderFrameHost* frame,
    gfx::Rect* output_rect) {
  gfx::Vector2d offset;
  if (!GetIFrameOffsetFromIFramePath(iframe_path, frame, &offset))
    return false;
  if (!GetBoundingRectOfTargetElement(target_element_xpath, frame, output_rect))
    return false;

  *output_rect += offset;
  return true;
}

bool TestRecipeReplayer::SimulateLeftMouseClickAt(
    const gfx::Point& point,
    content::RenderFrameHost* render_frame_host) {
  content::RenderWidgetHostView* view = render_frame_host->GetView();
  if (!SimulateMouseHoverAt(render_frame_host, point))
    return false;

  blink::WebMouseEvent mouse_event(
      blink::WebInputEvent::Type::kMouseDown,
      blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  mouse_event.button = blink::WebMouseEvent::Button::kLeft;
  mouse_event.SetPositionInWidget(point.x(), point.y());

  // Mac needs positionInScreen for events to plugins.
  gfx::Rect offset =
      content::WebContents::FromRenderFrameHost(render_frame_host)
          ->GetContainerBounds();
  mouse_event.SetPositionInScreen(point.x() + offset.x(),
                                  point.y() + offset.y());
  mouse_event.click_count = 1;
  content::RenderWidgetHost* widget = view->GetRenderWidgetHost();

  widget->ForwardMouseEvent(mouse_event);
  mouse_event.SetType(blink::WebInputEvent::Type::kMouseUp);
  widget->ForwardMouseEvent(mouse_event);
  return true;
}

bool TestRecipeReplayer::SimulateMouseHoverAt(
    content::RenderFrameHost* render_frame_host,
    const gfx::Point& point) {
  gfx::Rect offset =
      content::WebContents::FromRenderFrameHost(render_frame_host)
          ->GetContainerBounds();
  gfx::Point reset_mouse =
      gfx::Point(offset.x() + point.x(), offset.y() + point.y());
  if (!ui_test_utils::SendMouseMoveSync(reset_mouse)) {
    ADD_FAILURE() << "Failed to position the mouse!";
    return false;
  }
  return true;
}

void TestRecipeReplayer::SimulateKeyPressWrapper(
    content::WebContents* web_contents,
    ui::DomKey key) {
  ui::KeyboardCode key_code = ui::NonPrintableDomKeyToKeyboardCode(key);
  ui::DomCode code = ui::UsLayoutKeyboardCodeToDomCode(key_code);
  SimulateKeyPress(web_contents, key, code, key_code, false, false, false,
                   false);
}

bool TestRecipeReplayer::HasChromeStoredCredential(
    const base::Value::Dict& action,
    bool* stored_cred) {
  std::optional<std::string> origin =
      FindPopulateString(action, "origin", "Origin");
  std::optional<std::string> username =
      FindPopulateString(action, "userName", "Username");
  std::optional<std::string> password =
      FindPopulateString(action, "password", "Password");
  if (!origin || !username || !password)
    return false;
  *stored_cred = feature_action_executor()->HasChromeStoredCredential(
      *origin, *username, *password);

  return true;
}

bool TestRecipeReplayer::SetupSavedAutofillProfile(
    base::Value::List saved_autofill_profile_container) {
  for (auto& list_entry : saved_autofill_profile_container) {
    if (!list_entry.is_dict()) {
      ADD_FAILURE() << "Failed to extract an entry!";
      return false;
    }

    const base::Value::Dict list_entry_dict = std::move(list_entry).TakeDict();
    std::optional<std::string> type =
        FindPopulateString(list_entry_dict, "type", "profile field type");
    std::optional<std::string> value =
        FindPopulateString(list_entry_dict, "value", "profile field value");

    if (!type || !value)
      return false;

    if (!feature_action_executor()->AddAutofillProfileInfo(*type, *value)) {
      return false;
    }
  }

  // Skip this step if autofill profile is empty.
  // Only Autofill Captured Sites test recipes will have non-empty autofill
  // profiles. Recipes for other captured sites tests will have empty autofill
  // profiles. This block prevents these other tests from failing because
  // the test feature action executor does not know how to setup the autofill
  // profile.
  if (saved_autofill_profile_container.empty()) {
    return true;
  }

  return feature_action_executor()->SetupAutofillProfile();
}

bool TestRecipeReplayer::SetupSavedPasswords(
    base::Value::List saved_password_list_container) {
  for (auto& entry : saved_password_list_container) {
    if (!entry.is_dict()) {
      ADD_FAILURE() << "Failed to extract a saved password!";
      return false;
    }

    const base::Value::Dict entry_dict = std::move(entry.GetDict());

    std::optional<std::string> origin =
        FindPopulateString(entry_dict, "website", "Website");
    std::optional<std::string> username =
        FindPopulateString(entry_dict, "username", "Username");
    std::optional<std::string> password =
        FindPopulateString(entry_dict, "password", "Password");
    if (!origin || !username || !password)
      return false;

    if (!feature_action_executor()->AddCredential(*origin, *username,
          *password)) {
      return false;
    }
  }

  return true;
}

// TestRecipeReplayChromeFeatureActionExecutor --------------------------------
TestRecipeReplayChromeFeatureActionExecutor::
    TestRecipeReplayChromeFeatureActionExecutor() = default;
TestRecipeReplayChromeFeatureActionExecutor::
    ~TestRecipeReplayChromeFeatureActionExecutor() = default;

bool TestRecipeReplayChromeFeatureActionExecutor::AutofillForm(
    const std::string& focus_element_css_selector,
    const std::vector<std::string>& iframe_path,
    const int attempts,
    content::RenderFrameHost* frame,
    std::optional<autofill::FieldType> triggered_field_type) {
  ADD_FAILURE() << "TestRecipeReplayChromeFeatureActionExecutor::AutofillForm "
                   "is not implemented!";
  return false;
}

bool TestRecipeReplayChromeFeatureActionExecutor::AddAutofillProfileInfo(
    const std::string& field_type,
    const std::string& field_value) {
  ADD_FAILURE() << "TestRecipeReplayChromeFeatureActionExecutor"
                   "::AddAutofillProfileInfo is not implemented!";
  return false;
}

bool TestRecipeReplayChromeFeatureActionExecutor::SetupAutofillProfile() {
  ADD_FAILURE() << "TestRecipeReplayChromeFeatureActionExecutor"
                   "::SetupAutofillProfile is not implemented!";
  return false;
}

bool TestRecipeReplayChromeFeatureActionExecutor::AddCredential(
    const std::string& origin,
    const std::string& username,
    const std::string& password) {
  ADD_FAILURE() << "TestRecipeReplayChromeFeatureActionExecutor::AddCredential"
                   " is not implemented!";
  return false;
}

bool TestRecipeReplayChromeFeatureActionExecutor::SavePassword() {
  ADD_FAILURE() << "TestRecipeReplayChromeFeatureActionExecutor::SavePassword"
                   " is not implemented!";
  return false;
}

bool TestRecipeReplayChromeFeatureActionExecutor::UpdatePassword() {
  ADD_FAILURE() << "TestRecipeReplayChromeFeatureActionExecutor"
                   "::UpdatePassword is not implemented!";
  return false;
}

bool TestRecipeReplayChromeFeatureActionExecutor::WaitForSaveFallback() {
  ADD_FAILURE() << "TestRecipeReplayChromeFeatureActionExecutor"
                   "::WaitForSaveFallback is not implemented!";
  return false;
}

bool TestRecipeReplayChromeFeatureActionExecutor::
    IsChromeShowingPasswordGenerationPrompt() {
  ADD_FAILURE()
      << "TestRecipeReplayChromeFeatureActionExecutor"
         "::IsChromeShowingPasswordGenerationPrompt is not implemented!";
  return false;
}

bool TestRecipeReplayChromeFeatureActionExecutor::
    HasChromeShownSavePasswordPrompt() {
  ADD_FAILURE() << "TestRecipeReplayChromeFeatureActionExecutor"
                   "::HasChromeShownSavePasswordPrompt is not implemented!";
  return false;
}

bool TestRecipeReplayChromeFeatureActionExecutor::HasChromeStoredCredential(
    const std::string& origin,
    const std::string& username,
    const std::string& password) {
  ADD_FAILURE() << "TestRecipeReplayChromeFeatureActionExecutor"
                   "::HasChromeStoredCredential is not implemented!";
  return false;
}

}  // namespace captured_sites_test_utils
