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

#include <algorithm>
#include <cstdint>
#include <optional>
#include <tuple>

#include "base/barrier_closure.h"
#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/feature_list.h"
#include "base/files/scoped_temp_dir.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/memory_pressure_listener_registry.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/metrics_hashes.h"
#include "base/run_loop.h"
#include "base/scoped_observation.h"
#include "base/strings/escape.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/to_string.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/lock.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/bind.h"
#include "base/test/gtest_util.h"
#include "base/test/run_until.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_mock_time_task_runner.h"
#include "base/test/test_timeouts.h"
#include "base/thread_annotations.h"
#include "base/time/time.h"
#include "base/values.h"
#include "build/build_config.h"
#include "components/input/render_widget_host_input_event_router.h"
#include "components/services/storage/public/mojom/storage_service.mojom.h"
#include "components/services/storage/public/mojom/test_api.test-mojom.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/browser/back_forward_cache_test_util.h"
#include "content/browser/preloading/prefetch/prefetch_features.h"
#include "content/browser/preloading/prefetch/prefetch_service.h"
#include "content/browser/preloading/prefetch/prefetch_test_util_internal.h"
#include "content/browser/preloading/preloading.h"
#include "content/browser/preloading/preloading_attempt_impl.h"
#include "content/browser/preloading/preloading_data_impl.h"
#include "content/browser/preloading/preloading_decider.h"
#include "content/browser/preloading/prerender/prerender_features.h"
#include "content/browser/preloading/prerender/prerender_final_status.h"
#include "content/browser/preloading/prerender/prerender_handle_impl.h"
#include "content/browser/preloading/prerender/prerender_host.h"
#include "content/browser/preloading/prerender/prerender_host_registry.h"
#include "content/browser/preloading/prerender/prerender_metrics.h"
#include "content/browser/preloading/prerender/prerender_no_vary_search_hint_commit_deferring_condition.h"
#include "content/browser/preloading/speculation_rules/speculation_rules_util.h"
#include "content/browser/renderer_host/back_forward_cache_impl.h"
#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/browser/renderer_host/navigation_request.h"
#include "content/browser/renderer_host/navigation_throttle_runner.h"
#include "content/browser/renderer_host/navigation_type.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/storage_partition_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/content_navigation_policy.h"
#include "content/common/features.h"
#include "content/common/input/synthetic_tap_gesture.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/disallow_activation_reason.h"
#include "content/public/browser/document_user_data.h"
#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/prerender_web_contents_delegate.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/site_isolation_policy.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/isolated_world_ids.h"
#include "content/public/test/back_forward_cache_util.h"
#include "content/public/test/background_color_change_waiter.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/browsing_data_remover_test_util.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_content_browser_client.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/file_system_chooser_test_helpers.h"
#include "content/public/test/mock_client_hints_controller_delegate.h"
#include "content/public/test/mock_web_contents_observer.h"
#include "content/public/test/mojo_capability_control_test_interfaces.mojom.h"
#include "content/public/test/mojo_capability_control_test_util.h"
#include "content/public/test/navigation_handle_observer.h"
#include "content/public/test/no_renderer_crashes_assertion.h"
#include "content/public/test/prefetch_test_util.h"
#include "content/public/test/preloading_test_util.h"
#include "content/public/test/prerender_test_util.h"
#include "content/public/test/scoped_accessibility_mode_override.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_navigation_throttle.h"
#include "content/public/test/test_utils.h"
#include "content/public/test/theme_change_waiter.h"
#include "content/public/test/url_loader_interceptor.h"
#include "content/shell/browser/shell.h"
#include "content/shell/browser/shell_browser_context.h"
#include "content/test/content_browser_test_utils_internal.h"
#include "content/test/mock_commit_deferring_condition.h"
#include "content/test/render_document_feature.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "mojo/public/cpp/bindings/remote_set.h"
#include "mojo/public/cpp/system/functions.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_request_headers.h"
#include "net/test/embedded_test_server/controllable_http_response.h"
#include "net/test/embedded_test_server/default_handlers.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "net/test/embedded_test_server/request_handler_util.h"
#include "services/metrics/public/cpp/metrics_utils.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/network/public/cpp/web_sandbox_flags.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/loader/loader_constants.h"
#include "third_party/blink/public/common/navigation/preloading_headers.h"
#include "third_party/blink/public/mojom/browser_interface_broker.mojom.h"
#include "third_party/blink/public/mojom/frame/fullscreen.mojom.h"
#include "third_party/blink/public/mojom/page/display_cutout.mojom.h"
#include "ui/color/color_id.h"
#include "ui/events/base_event_utils.h"
#include "ui/shell_dialogs/select_file_dialog.h"
#include "ui/shell_dialogs/select_file_dialog_factory.h"
#include "url/gurl.h"
#include "url/url_constants.h"

#if BUILDFLAG(IS_MAC)
#include "base/mac/mac_util.h"
#endif

using ::testing::Exactly;

namespace content {
namespace {

PreloadingPredictor kPreloadingPredictorEmbedderForTest(100, "EmbedderForTest");

enum class BackForwardCacheType {
  kDisabled,
  kEnabled,
};

constexpr char kPagehideEventPath[] = "/pagehideFired";

std::string ToString(const testing::TestParamInfo<BackForwardCacheType>& info) {
  switch (info.param) {
    case BackForwardCacheType::kDisabled:
      return "Disabled";
    case BackForwardCacheType::kEnabled:
      return "Enabled";
  }
}

int32_t InterfaceNameHasher(const std::string& interface_name) {
  return static_cast<int32_t>(base::HashMetricNameAs32Bits(interface_name));
}

RenderFrameHost* FindRenderFrameHost(Page& page, const GURL& url) {
  return FrameMatchingPredicate(page,
                                base::BindRepeating(&FrameHasSourceUrl, url));
}

ukm::SourceId ToSourceId(int64_t navigation_id) {
  return ukm::ConvertToSourceId(navigation_id,
                                ukm::SourceIdType::NAVIGATION_ID);
}

// Example class which inherits the DocumentUserData, all the data is
// associated to the lifetime of the document.
class DocumentData : public DocumentUserData<DocumentData> {
 public:
  ~DocumentData() override = default;

  base::WeakPtr<DocumentData> GetWeakPtr() {
    return weak_ptr_factory_.GetWeakPtr();
  }

 private:
  explicit DocumentData(RenderFrameHost* render_frame_host)
      : DocumentUserData<DocumentData>(render_frame_host) {}

  friend class DocumentUserData<DocumentData>;

  base::WeakPtrFactory<DocumentData> weak_ptr_factory_{this};

  DOCUMENT_USER_DATA_KEY_DECL();
};

DOCUMENT_USER_DATA_KEY_IMPL(DocumentData);

using UkmEntry = ukm::TestUkmRecorder::HumanReadableUkmEntry;
using ukm::builders::Preloading_Attempt;
using ukm::builders::Preloading_Attempt_PreviousPrimaryPage;
using ukm::builders::Preloading_Prediction;
using ukm::builders::Preloading_Prediction_PreviousPrimaryPage;

static const auto kMockElapsedTime =
    base::ScopedMockElapsedTimersForTest::kMockElapsedTime;

// Utility class to make building expected
// TestUkmRecorder::HumanReadableUkmEntry for EXPECT_EQ for
// PreloadingAttemptPreviousPrimaryPage.
class PreloadingAttemptPreviousPrimaryPageUkmEntryBuilder {
 public:
  explicit PreloadingAttemptPreviousPrimaryPageUkmEntryBuilder(
      PreloadingPredictor predictor)
      : predictor_(predictor) {}

  // Unlike PreloadingAttemptUkmEntryBuilder, this method assumes a navigation
  // has not occurred thus `TimeToNextNavigation` is not set.
  //
  // Optional `ready_time` should be set by the caller, if this attempt ever
  // reaches `PreloadingTriggeringOutcome::kReady` state, at the time of
  // reporting. Install `base::ScopedMockElapsedTimersForTest` into the test
  // fixture to assert the entry's latency values' correctness.
  ukm::TestUkmRecorder::HumanReadableUkmEntry BuildEntry(
      ukm::SourceId source_id,
      PreloadingType preloading_type,
      PreloadingEligibility eligibility,
      PreloadingHoldbackStatus holdback_status,
      PreloadingTriggeringOutcome triggering_outcome,
      PreloadingFailureReason failure_reason,
      bool accurate,
      std::optional<base::TimeDelta> ready_time = std::nullopt,
      std::optional<blink::mojom::SpeculationEagerness> eagerness =
          std::nullopt) const {
    std::map<std::string, int64_t> metrics = {
        {Preloading_Attempt::kPreloadingTypeName,
         static_cast<int64_t>(preloading_type)},
        {Preloading_Attempt::kPreloadingPredictorName, predictor_.ukm_value()},
        {Preloading_Attempt::kEligibilityName,
         static_cast<int64_t>(eligibility)},
        {Preloading_Attempt::kHoldbackStatusName,
         static_cast<int64_t>(holdback_status)},
        {Preloading_Attempt::kTriggeringOutcomeName,
         static_cast<int64_t>(triggering_outcome)},
        {Preloading_Attempt::kFailureReasonName,
         static_cast<int64_t>(failure_reason)},
        {Preloading_Attempt::kAccurateTriggeringName, accurate ? 1 : 0}};
    if (ready_time) {
      metrics.insert({Preloading_Attempt::kReadyTimeName,
                      ukm::GetExponentialBucketMinForCounts1000(
                          ready_time->InMilliseconds())});
    }
    if (eagerness) {
      metrics.insert({Preloading_Attempt::kSpeculationEagernessName,
                      static_cast<int64_t>(eagerness.value())});
    }
    return UkmEntry{source_id, std::move(metrics)};
  }

 private:
  PreloadingPredictor predictor_;
};

// Utility class to make building expected
// TestUkmRecorder::HumanReadableUkmEntry for EXPECT_EQ for
// PreloadingPredictionPreviousPrimaryPage.
class PreloadingPredictionPreviousPrimaryPageUkmEntryBuilder {
 public:
  explicit PreloadingPredictionPreviousPrimaryPageUkmEntryBuilder(
      PreloadingPredictor predictor)
      : predictor_(predictor) {}

  // Unlike PreloadingPredictionUkmEntryBuilder, this method assumes a
  // navigation has not occurred thus `TimeToNextNavigation` is not set.
  ukm::TestUkmRecorder::HumanReadableUkmEntry
  BuildEntry(ukm::SourceId source_id, int confidence, bool accurate) const {
    std::map<std::string, int64_t> metrics = {
        {Preloading_Prediction::kConfidenceName,
         static_cast<int64_t>(confidence)},
        {Preloading_Attempt::kPreloadingPredictorName,
         static_cast<int64_t>(predictor_.ukm_value())},
        {Preloading_Prediction::kAccuratePredictionName, accurate ? 1 : 0}};
    return UkmEntry{source_id, std::move(metrics)};
  }

 private:
  PreloadingPredictor predictor_;
};

// Tests the params of WebContentsImpl that contains a prerendered page for a
// new tab navigation.
void ExpectWebContentsIsForNewTabPrerendering(WebContents& web_contents) {
  auto& web_contents_impl = static_cast<WebContentsImpl&>(web_contents);

  // The primary page shows the initial blank page.
  EXPECT_TRUE(web_contents_impl.GetLastCommittedURL().is_empty());

  // The prerendering WebContents should not have an opener to avoid cross-page
  // scripting during prerendering.
  EXPECT_FALSE(web_contents_impl.HasOpener());

  // The prerendering WebContents should be hidden until prerender activation.
  EXPECT_TRUE(web_contents_impl.IsHidden());
}

// This is a fake implementation of WebContentsDelegate that allows
// prerendering.
class FakeWebContentsDelegate : public WebContentsDelegate {
 public:
  // WebContentsDelegate overrides.
  PreloadingEligibility IsPrerender2Supported(
      WebContents& web_contents,
      PreloadingTriggerType trigger_type) override {
    return PreloadingEligibility::kEligible;
  }
};

enum class TriggerType {
  kSpeculationRules,
  kEmbedderWithoutPrefetchAheadOfPrerender
};

class PrerenderBrowserTest : public ContentBrowserTest,
                             public WebContentsObserver {
 public:
  using LifecycleStateImpl = RenderFrameHostImpl::LifecycleStateImpl;

  enum class OriginType {
    kSameOrigin,
    kSameSiteCrossOrigin,
    kCrossSite,
  };

  PrerenderBrowserTest() {
    prerender_helper_ =
        std::make_unique<test::PrerenderTestHelper>(base::BindRepeating(
            &PrerenderBrowserTest::web_contents, base::Unretained(this)));

    // Input suppression during paintholding interferes with the input event
    // dispatches to top frames.  Disabling kDropInputEventsWhilePaintHolding
    // because the tests here are not about top frame paintholding.
    feature_list_.InitWithFeatures(
        {::features::kSuppressesPrerenderingOnSlowNetwork,
         blink::features::kFetchLaterAPI},
        {blink::features::kDropInputEventsWhilePaintHolding});
  }
  ~PrerenderBrowserTest() override = default;

  void SetUp() override {
    ssl_server_.RegisterRequestHandler(
        base::BindRepeating(&net::test_server::HandlePrefixedRequest,
                            "/server-redirect-credentialed-prerender",
                            base::BindRepeating(HandleCredentialedRequest)));
    prerender_helper_->RegisterServerRequestMonitor(&ssl_server_);
    ContentBrowserTest::SetUp();
  }

  void SetUpOnMainThread() override {
    DCHECK_CURRENTLY_ON(BrowserThread::UI);
    host_resolver()->AddRule("*", "127.0.0.1");
    attempt_ukm_entry_builder_ =
        std::make_unique<test::PreloadingAttemptUkmEntryBuilder>(
            PredictorToExpectInUkm());
    attempt_previous_ukm_entry_builder_ =
        std::make_unique<PreloadingAttemptPreviousPrimaryPageUkmEntryBuilder>(
            PredictorToExpectInUkm());
    prediction_ukm_entry_builder_ =
        std::make_unique<test::PreloadingPredictionUkmEntryBuilder>(
            PredictorToExpectInUkm());
    prediction_previous_ukm_entry_builder_ = std::make_unique<
        PreloadingPredictionPreviousPrimaryPageUkmEntryBuilder>(
        PredictorToExpectInUkm());
    ssl_server_.AddDefaultHandlers(GetTestDataFilePath());
    ssl_server_.SetSSLConfig(
        net::test_server::EmbeddedTestServer::CERT_TEST_NAMES);
    pagehide_event_receiver_ =
        std::make_unique<net::test_server::ControllableHttpResponse>(
            &ssl_server_, kPagehideEventPath);
    ASSERT_TRUE(ssl_server_.Start(port_));
    WebContentsObserver::Observe(shell()->web_contents());

    ukm_recorder_ = std::make_unique<ukm::TestAutoSetUkmRecorder>();
  }

  void TearDownOnMainThread() override {
    DCHECK_CURRENTLY_ON(BrowserThread::UI);
    EXPECT_TRUE(ssl_server_.ShutdownAndWaitUntilComplete());
  }

  static std::unique_ptr<net::test_server::HttpResponse>
  HandleCredentialedRequest(const net::test_server::HttpRequest& request) {
    GURL request_url = request.GetURL();
    std::string dest = base::UnescapeBinaryURLComponent(request_url.query());

    auto http_response =
        std::make_unique<net::test_server::BasicHttpResponse>();
    http_response->set_code(net::HTTP_FOUND);
    http_response->AddCustomHeader("Location", dest);
    http_response->AddCustomHeader("Access-Control-Allow-Origin", "*");
    http_response->AddCustomHeader("Supports-Loading-Mode",
                                   "credentialed-prerender");
    http_response->set_content_type("text/html");
    http_response->set_content(base::StringPrintf(
        "<!doctype html><p>Redirecting to %s", dest.c_str()));
    return http_response;
  }

  // Waits until the request count for `url` reaches `count`.
  void WaitForRequest(const GURL& url, int count) {
    prerender_helper_->WaitForRequest(url, count);
  }

  PrerenderHostId AddPrerender(const GURL& prerendering_url,
                               int32_t world_id = ISOLATED_WORLD_ID_GLOBAL) {
    return prerender_helper_->AddPrerender(prerendering_url, world_id);
  }

  PrerenderHostId AddPrerenderWithTags(const GURL& prerendering_url,
                                       std::optional<std::string> tag) {
    return prerender_helper_->AddPrerender(
        prerendering_url, /*eagerness=*/std::nullopt,
        /*no_vary_search_hint=*/std::string(),
        /*target_hint=*/std::string(), tag);
  }

  PrerenderHostId AddPrerender(const GURL& prerendering_url,
                               std::string no_vary_search_hint,
                               int32_t world_id = ISOLATED_WORLD_ID_GLOBAL) {
    return prerender_helper_->AddPrerender(
        prerendering_url, /*eagerness=*/std::nullopt, no_vary_search_hint,
        /*target_hint=*/std::string(), /*ruleset_tag=*/std::nullopt, world_id);
  }

  void AddPrerenderAsync(const GURL& prerendering_url) {
    prerender_helper_->AddPrerenderAsync(prerendering_url);
  }

  void AddPrerenderAsync(const GURL& prerendering_url,
                         std::string no_vary_search_hint) {
    prerender_helper_->AddPrerendersAsync({prerendering_url},
                                          /*eagerness=*/std::nullopt,
                                          no_vary_search_hint,
                                          /*target_hint=*/std::string());
  }

  void AddPrefetchAsync(const GURL& prefetch_url) {
    prerender_helper_->AddPrefetchAsync(prefetch_url);
  }

  void AddPrerendersAsync(const std::vector<GURL>& prerendering_urls) {
    prerender_helper_->AddPrerendersAsync(prerendering_urls,
                                          /*eagerness=*/std::nullopt,
                                          /*target_hint=*/std::string());
  }

  void AddPrerendersAsync(
      const std::vector<GURL>& prerendering_urls,
      std::optional<blink::mojom::SpeculationEagerness> eagerness,
      const std::string& target_hint) {
    prerender_helper_->AddPrerendersAsync(prerendering_urls, eagerness,
                                          target_hint);
  }

  void AddPrerenderWithEagernessAsync(
      const GURL& prerendering_url,
      blink::mojom::SpeculationEagerness eagerness) {
    prerender_helper_->AddPrerendersAsync({prerendering_url}, eagerness,
                                          /*target_hint=*/std::string());
  }

  std::unique_ptr<PrerenderHandle> AddEmbedderTriggeredPrerender(
      const GURL& prerendering_url,
      PreloadingAttempt* preloading_attempt = nullptr,
      bool should_warm_up_compositor = false) {
    std::unique_ptr<PrerenderHandle> handle =
        AddEmbedderTriggeredPrerenderAsync(prerendering_url, preloading_attempt,
                                           should_warm_up_compositor);
    EXPECT_TRUE(handle);
    test::PrerenderTestHelper::WaitForPrerenderLoadCompletion(*web_contents(),
                                                              prerendering_url);
    return handle;
  }

  std::unique_ptr<PrerenderHandle> AddEmbedderTriggeredPrerenderAsync(
      const GURL& prerendering_url,
      PreloadingAttempt* preloading_attempt = nullptr,
      bool should_warm_up_compositor = false) {
    return web_contents_impl()->StartPrerendering(
        prerendering_url, PreloadingTriggerType::kEmbedder,
        "EmbedderSuffixForTest",
        /*additional_headers=*/net::HttpRequestHeaders(),
        /*no_vary_search_hint=*/std::nullopt,
        ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
                                  ui::PAGE_TRANSITION_FROM_ADDRESS_BAR),
        should_warm_up_compositor, /*should_prepare_paint_tree=*/true,
        PreloadingHoldbackStatus::kUnspecified,
        PreloadPipelineInfo::Create(
            /*planned_max_preloading_type=*/PreloadingType::kPrerender),
        preloading_attempt,
        /*url_match_predicate=*/{},
        /*prerender_navigation_handle_callback=*/{},
        /*allow_reuse=*/false);
  }

  bool AddTestUtilJS(RenderFrameHost* host) {
    std::string js = R"(
        const script = document.createElement("script");
        new Promise(resolve => {
          script.addEventListener('load', () => {
            resolve(true);
          });
          script.addEventListener('error', () => {
            resolve(false);
          });
          script.src = "/prerender/test_utils.js";
          document.body.appendChild(script);
        });
    )";
    return EvalJs(host, js).ExtractBool();
  }

  void RegisterServiceWorker(const std::string& service_worker_url) {
    const std::string_view script = R"(
      (async () => {
        if (await navigator.serviceWorker.getRegistration('/') !== undefined) {
          return 'FAIL';
        }
        await navigator.serviceWorker.register($1, {scope: '/'});
        await navigator.serviceWorker.ready;
        return 'DONE';
      })();
    )";
    EXPECT_EQ("DONE", EvalJs(web_contents_impl()->GetPrimaryMainFrame(),
                             JsReplace(script, service_worker_url)));
  }

  void NavigatePrimaryPage(const GURL& url) {
    prerender_helper_->NavigatePrimaryPage(url);
  }

  void NavigatePrimaryPageFromAddressBar(const GURL& url) {
    prerender_helper_->NavigatePrimaryPageAsync(
        url, ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
                                       ui::PAGE_TRANSITION_FROM_ADDRESS_BAR));
  }

  PrerenderHostId GetHostForUrl(const GURL& url) {
    return prerender_helper_->GetHostForUrl(url);
  }

  RenderFrameHostImpl* GetPrerenderedMainFrameHost(PrerenderHostId host_id) {
    return static_cast<RenderFrameHostImpl*>(
        prerender_helper_->GetPrerenderedMainFrameHost(host_id));
  }

  void NavigatePrerenderedPage(PrerenderHostId host_id, const GURL& url) {
    return prerender_helper_->NavigatePrerenderedPage(host_id, url);
  }

  void CancelPrerenderedPage(PrerenderHostId host_id) {
    return prerender_helper_->CancelPrerenderedPage(host_id);
  }

  bool HasHostForUrl(WebContents& web_contents, const GURL& url) {
    PrerenderHostId host_id =
        content::test::PrerenderTestHelper::GetHostForUrl(web_contents, url);
    return !host_id.is_null();
  }

  bool HasHostForUrl(const GURL& url) {
    PrerenderHostId host_id = GetHostForUrl(url);
    return !host_id.is_null();
  }

  void WaitForPrerenderLoadCompletion(PrerenderHostId host_id) {
    prerender_helper_->WaitForPrerenderLoadCompletion(host_id);
  }

  void WaitForPrerenderLoadCompletion(const GURL& url) {
    prerender_helper_->WaitForPrerenderLoadCompletion(url);
  }

  GURL GetUrl(const std::string& path) const {
    return ssl_server_.GetURL("a.test", path);
  }

  GURL GetSameSiteCrossOriginUrl(const std::string& path) {
    return ssl_server().GetURL("b.a.test", path);
  }

  GURL GetCrossSiteUrl(const std::string& path) {
    return ssl_server_.GetURL("b.test", path);
  }

  void ResetSSLConfig(
      net::test_server::EmbeddedTestServer::ServerCertificate cert,
      const net::SSLServerConfig& ssl_config) {
    ASSERT_TRUE(ssl_server_.ResetSSLConfig(cert, ssl_config));
  }

  int GetRequestCount(const GURL& url) {
    return prerender_helper_->GetRequestCount(url);
  }

  net::test_server::HttpRequest::HeaderMap GetRequestHeaders(const GURL& url) {
    return prerender_helper_->GetRequestHeaders(url);
  }

  WebContents* web_contents() const { return shell()->web_contents(); }

  WebContentsImpl* web_contents_impl() const {
    return static_cast<WebContentsImpl*>(web_contents());
  }

  RenderFrameHostImpl* current_frame_host() {
    return web_contents_impl()->GetPrimaryMainFrame();
  }

  ukm::TestAutoSetUkmRecorder* test_ukm_recorder() {
    return ukm_recorder_.get();
  }

  ukm::SourceId PrimaryPageSourceId() {
    return current_frame_host()->GetPageUkmSourceId();
  }

  const test::PreloadingAttemptUkmEntryBuilder& attempt_ukm_entry_builder() {
    return *attempt_ukm_entry_builder_;
  }

  const PreloadingAttemptPreviousPrimaryPageUkmEntryBuilder&
  attempt_previous_ukm_entry_builder() {
    return *attempt_previous_ukm_entry_builder_;
  }

  const test::PreloadingPredictionUkmEntryBuilder&
  prediction_ukm_entry_builder() {
    return *prediction_ukm_entry_builder_;
  }

  const PreloadingPredictionPreviousPrimaryPageUkmEntryBuilder&
  prediction_previous_ukm_entry_builder() {
    return *prediction_previous_ukm_entry_builder_;
  }

  void ExpectPreloadingAttemptUkm(
      const std::vector<UkmEntry>& expected_attempt_entries) {
    test::ExpectPreloadingAttemptUkm(*test_ukm_recorder(),
                                     expected_attempt_entries);
  }

  void ExpectPreloadingAttemptPreviousPrimaryPageUkm(
      const UkmEntry& expected_attempt_entry) {
    auto attempt_entries = test_ukm_recorder()->GetEntries(
        Preloading_Attempt_PreviousPrimaryPage::kEntryName,
        test::kPreloadingAttemptUkmMetrics);
    ASSERT_EQ(attempt_entries.size(), 1u);
    EXPECT_EQ(attempt_entries[0], expected_attempt_entry)
        << test::ActualVsExpectedUkmEntryToString(attempt_entries[0],
                                                  expected_attempt_entry);
  }

  void ExpectPreloadingPredictionUkm(
      const std::vector<UkmEntry>& expected_prediction_entries) {
    test::ExpectPreloadingPredictionUkm(*test_ukm_recorder(),
                                        expected_prediction_entries);
  }

  void ExpectPreloadingPredictioPreviousPrimaryPageUkm(
      const UkmEntry& expected_prediction_entry) {
    auto prediction_entries = test_ukm_recorder()->GetEntries(
        Preloading_Prediction_PreviousPrimaryPage::kEntryName,
        test::kPreloadingPredictionUkmMetrics);
    ASSERT_EQ(prediction_entries.size(), 1u);
    EXPECT_EQ(prediction_entries[0], expected_prediction_entry)
        << test::ActualVsExpectedUkmEntryToString(prediction_entries[0],
                                                  expected_prediction_entry);
  }

  void TestHostPrerenderingState(const GURL& prerender_url) {
    const GURL kInitialUrl = GetUrl("/empty.html");

    // Navigate to an initial page.
    ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

    // The initial page should not be in prerendered state.
    RenderFrameHostImpl* initiator_render_frame_host = current_frame_host();
    EXPECT_TRUE(initiator_render_frame_host->frame_tree()->is_primary());
    EXPECT_EQ(initiator_render_frame_host->lifecycle_state(),
              LifecycleStateImpl::kActive);

    // Start a prerender.
    AddPrerender(prerender_url);

    EXPECT_TRUE(prerender_helper_->VerifyPrerenderingState(prerender_url));

    // Activate the prerendered page.
    NavigatePrimaryPage(prerender_url);
    EXPECT_EQ(web_contents()->GetLastCommittedURL(), prerender_url);

    // The activated page should no longer be in the prerendering state.
    RenderFrameHostImpl* navigated_render_frame_host = current_frame_host();
    // The new page shouldn't be in the prerendering state.
    navigated_render_frame_host->ForEachRenderFrameHostImpl(
        [](RenderFrameHostImpl* rfhi) {
          // All the subframes should be transitioned to
          // LifecycleStateImpl::kActive state after activation.
          EXPECT_EQ(rfhi->lifecycle_state(),
                    RenderFrameHostImpl::LifecycleStateImpl::kActive);
          EXPECT_FALSE(rfhi->frame_tree()->is_prerendering());

          // Check that each document can use a deferred Mojo interface. Choose
          // WebLocks API as the feature is enabled by default and does not
          // require permission.
          const std::string kMojoScript = R"(
            navigator.locks.request('hi', {mode:'shared'}, () => {});
          )";
          EXPECT_TRUE(ExecJs(rfhi, kMojoScript));
        });
  }

  void TestPrerenderAllowedOnIframeWithStatusCode(OriginType origin_type,
                                                  std::string status_code);

  test::PrerenderTestHelper* prerender_helper() {
    return prerender_helper_.get();
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    // The viewport meta tag is only enabled on Android.
#if BUILDFLAG(IS_ANDROID)
    command_line->AppendSwitchASCII(switches::kEnableBlinkFeatures,
                                    "DisplayCutoutAPI");
#endif
  }

  void TestNavigationHistory(const GURL& expected_current_url,
                             int expected_history_index,
                             int expected_history_length) {
    ASSERT_EQ(expected_current_url, web_contents()->GetLastCommittedURL());
    EXPECT_EQ(expected_history_index,
              web_contents()->GetController().GetCurrentEntryIndex());
    EXPECT_EQ(expected_history_length,
              web_contents()->GetController().GetEntryCount());
    EXPECT_EQ(expected_history_length,
              EvalJs(web_contents(), "history.length"));
  }

  void AssertPrerenderHistoryLength(PrerenderHostId host_id,
                                    RenderFrameHost* prerender_frame_host) {
    FrameTreeNodeId frame_tree_node_id =
        PrerenderHost::GetFrameTreeNodeIdForId(host_id);
    EXPECT_EQ(1, FrameTreeNode::GloballyFindByID(frame_tree_node_id)
                     ->frame_tree()
                     .controller()
                     .GetEntryCount());
    ASSERT_EQ(1, EvalJs(prerender_frame_host, "history.length"));
  }

  void GoBack() {
    web_contents()->GetController().GoBack();
    EXPECT_TRUE(WaitForLoadStop(web_contents()));
  }

  void GoForward() {
    web_contents()->GetController().GoForward();
    EXPECT_TRUE(WaitForLoadStop(web_contents()));
  }

  void ExpectFinalStatus(const std::string& final_status_name,
                         PrerenderFinalStatus status) {
    // Check FinalStatus in UMA.
    histogram_tester().ExpectUniqueSample(final_status_name, status, 1);

    // Check all entries in UKM to make sure that the recorded FinalStatus is
    // equal to `status`. At least one entry should exist.
    bool final_status_entry_found = false;
    const auto entries = ukm_recorder_->GetEntriesByName(
        ukm::builders::PrerenderPageLoad::kEntryName);
    for (const ukm::mojom::UkmEntry* entry : entries) {
      if (ukm_recorder_->EntryHasMetric(
              entry, ukm::builders::PrerenderPageLoad::kFinalStatusName)) {
        final_status_entry_found = true;
        ukm_recorder_->ExpectEntryMetric(
            entry, ukm::builders::PrerenderPageLoad::kFinalStatusName,
            static_cast<int>(status));
      }
    }

    EXPECT_TRUE(final_status_entry_found);
  }

  void ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus status) {
    ExpectFinalStatus(
        "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
        status);
  }

  void ExpectFinalStatusForSpeculationRuleFromIsolatedWorld(
      PrerenderFinalStatus status) {
    ExpectFinalStatus(
        "Prerender.Experimental.PrerenderHostFinalStatus."
        "SpeculationRuleFromIsolatedWorld",
        status);
  }

  void ExpectFinalStatusForSpeculationRuleFromAutoSpeculationRules(
      PrerenderFinalStatus status) {
    ExpectFinalStatus(
        "Prerender.Experimental.PrerenderHostFinalStatus."
        "SpeculationRuleFromAutoSpeculationRules",
        status);
  }

  void ExpectFinalStatusForEmbedder(PrerenderFinalStatus status) {
    // UKM can be recorded in an initiator page and an activated page. Embedder
    // triggers don't have an initiator page, so UKM is not recorded anywhere
    // when prerendering is canceled.
    if (status != PrerenderFinalStatus::kActivated) {
      return;
    }

    ExpectFinalStatus(
        "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_"
        "EmbedderSuffixForTest",
        status);
  }

  const base::HistogramTester& histogram_tester() { return histogram_tester_; }

  std::string GetBodyTextContent() {
    base::RunLoop loop;
    base::Value result;
    web_contents()->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(
        base::UTF8ToUTF16(std::string("document.body.textContent.trim()")),
        base::BindOnce(
            [](base::RunLoop* loop, base::Value* result, base::Value value) {
              *result = std::move(value);
              loop->QuitClosure().Run();
            },
            &loop, &result),
        ISOLATED_WORLD_ID_GLOBAL);
    loop.Run();
    CHECK(result.is_string());
    return result.GetString();
  }

  void WaitForPageHide() { pagehide_event_receiver_->WaitForRequest(); }

  bool PageHideReceived() {
    return pagehide_event_receiver_->has_received_request();
  }

  // Returns the process host for a prerendered page.
  RenderProcessHost* GetProcessForPrerenderHost(
      PrerenderHostId prerender_host_id) {
    FrameTreeNodeId frame_tree_node_id =
        PrerenderHost::GetFrameTreeNodeIdForId(prerender_host_id);
    FrameTreeNode* frame_tree_node =
        FrameTreeNode::GloballyFindByID(frame_tree_node_id);
    return frame_tree_node->current_frame_host()->GetProcess();
  }

  // Stores all the navigation_ids for all navigations. This is used to check
  // that we record UKMs for correct SourceIds.
  std::vector<int64_t> navigation_ids_;

  [[nodiscard]]
  std::unique_ptr<PrerenderHandle> TriggerPrerender(const GURL& url,
                                                    TriggerType trigger_type) {
    switch (trigger_type) {
      case TriggerType::kSpeculationRules:
        prerender_helper()->AddPrerenderAsync(url);
        return nullptr;
      case TriggerType::kEmbedderWithoutPrefetchAheadOfPrerender:
        auto* preloading_data =
            PreloadingDataImpl::GetOrCreateForWebContents(web_contents());
        auto* attempt = preloading_data->AddPreloadingAttempt(
            kPreloadingPredictorEmbedderForTest,
            content::PreloadingType::kPrerender,
            PreloadingData::GetSameURLMatcher(url),
            /*triggering_primary_page_source_id=*/
            web_contents()->GetPrimaryMainFrame()->GetPageUkmSourceId());

        return AddEmbedderTriggeredPrerenderAsync(url, attempt);
    }
  }

  bool IsPrerender2FallbackPrefetchSpecRulesEnabled() const {
    return base::FeatureList::IsEnabled(
        features::kPrerender2FallbackPrefetchSpecRules);
  }

 protected:
  void TestCancelPrerendersWhenTimeout(
      std::vector<Visibility> visibility_transitions);
  void TestCancelOnlyEmbedderTriggeredPrerenderWhenTimeout(
      std::vector<Visibility> visibility_transitions);
  void TestTimerResetWhenPageGoBackToForeground(Visibility visibility);
  void TestCancelPrerenderWithTargetBlankWhenTimeout(Visibility visibility);
  void TestEmbedderTriggerWithUnsupportedScheme(const GURL& prerendering_url);
  void TestSequentialPrerenderingVisibilityStateTransition(
      Visibility initial_visibility,
      Visibility background_visibility);
  void TestCancelOnAuthRequested(TriggerType trigger_type);

  net::test_server::EmbeddedTestServer& ssl_server() { return ssl_server_; }

  // Override this in subclasses if you want the test_ukm_recorder() and friends
  // to expect a different predictor.
  virtual PreloadingPredictor PredictorToExpectInUkm() {
    return content_preloading_predictor::kSpeculationRules;
  }

  void ResetPointerPosition() {
#if !BUILDFLAG(IS_ANDROID)
    InputEventAckWaiter waiter(
        web_contents()->GetPrimaryMainFrame()->GetRenderWidgetHost(),
        blink::WebInputEvent::Type::kMouseMove);
    SimulateMouseEvent(web_contents(), blink::WebMouseEvent::Type::kMouseMove,
                       blink::WebMouseEvent::Button::kNoButton,
                       gfx::Point(0, 0));
    waiter.Wait();
#else
    // TODO(crbug.com/40269669): Simulate |WebGestureEvent| to make this
    // function work for Android.
#endif  // !BUILDFLAG(IS_ANDROID)
  }

  void PointerHoverToAnchor(
      const GURL& url,
      const std::optional<base::TimeDelta>& hover_time = std::nullopt) {
    ResetPointerPosition();

#if !BUILDFLAG(IS_ANDROID)
    const auto point = CalculateCenterPointOfAnchorElement(url);
    InputEventAckWaiter waiter(
        web_contents()->GetPrimaryMainFrame()->GetRenderWidgetHost(),
        blink::WebInputEvent::Type::kMouseMove);
    SimulateMouseEvent(web_contents(), blink::WebMouseEvent::Type::kMouseMove,
                       blink::WebMouseEvent::Button::kNoButton, point);
    waiter.Wait();
    if (hover_time) {
      base::RunLoop run_loop;
      base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
          FROM_HERE, run_loop.QuitClosure(), *hover_time);
      run_loop.Run();
      ResetPointerPosition();
    }
#else
    // TODO(crbug.com/40269669): Simulate |WebGestureEvent| to make this
    // function work for Android.
#endif  // !BUILDFLAG(IS_ANDROID)
  }

  void PointerDownToAnchor(const GURL& url) {
    ResetPointerPosition();

#if !BUILDFLAG(IS_ANDROID)
    const auto point = CalculateCenterPointOfAnchorElement(url);
    InputEventAckWaiter waiter(
        web_contents()->GetPrimaryMainFrame()->GetRenderWidgetHost(),
        blink::WebInputEvent::Type::kMouseDown);
    SimulateMouseEventForClick(blink::WebMouseEvent::Type::kMouseDown,
                               blink::WebMouseEvent::Button::kLeft, point);
    waiter.Wait();
#else
    // TODO(crbug.com/40269669): Simulate |WebGestureEvent| to make this
    // function work for Android.
#endif  // !BUILDFLAG(IS_ANDROID)
  }

  void PointerUpToAnchor(const GURL& url) {
#if !BUILDFLAG(IS_ANDROID)
    const auto point = CalculateCenterPointOfAnchorElement(url);
    InputEventAckWaiter waiter(
        web_contents()->GetPrimaryMainFrame()->GetRenderWidgetHost(),
        blink::WebInputEvent::Type::kMouseUp);
    SimulateMouseEventForClick(blink::WebMouseEvent::Type::kMouseUp,
                               blink::WebMouseEvent::Button::kLeft, point);
    waiter.Wait();
#else
    // TODO(crbug.com/40269669): Simulate |WebGestureEvent| to make this
    // function work for Android.
#endif  // !BUILDFLAG(IS_ANDROID)
  }

  void InsertAnchor(const GURL url) {
    // Give them large margins so that ResetPointerPosition() does not
    // accidentally hover over the first-inserted link.
    const std::string script = R"(
      const anchor = document.createElement('a');
      anchor.href = $1;
      anchor.text = $1;
      anchor.style = "margin: 100px; display: block;";
      document.body.appendChild(anchor);
    )";
    ASSERT_TRUE(ExecJs(web_contents(), JsReplace(script, url.spec())));
  }

  void ClickAnchor(const GURL url) {
    PointerDownToAnchor(url);
    PointerUpToAnchor(url);
  }

  void set_port(int port) {
    ASSERT_FALSE(ssl_server_.Started());
    port_ = port;
  }

 private:
  void DidStartNavigation(NavigationHandle* handle) override {
    navigation_ids_.push_back(handle->GetNavigationId());
  }

  void SimulateMouseEventForClick(blink::WebInputEvent::Type type,
                                  blink::WebMouseEvent::Button button,
                                  const gfx::Point& point) {
    auto* web_contents_impl = static_cast<WebContentsImpl*>(web_contents());
    auto* rwhvb = static_cast<RenderWidgetHostViewBase*>(
        web_contents()->GetRenderWidgetHostView());
    blink::WebMouseEvent mouse_event(type, 0, ui::EventTimeForNow());
    mouse_event.button = button;
    mouse_event.SetPositionInWidget(point.x(), point.y());
    // Mac needs positionInScreen for events to plugins.
    gfx::Rect offset = web_contents()->GetContainerBounds();
    mouse_event.SetPositionInScreen(point.x() + offset.x(),
                                    point.y() + offset.y());
    mouse_event.click_count = 1;

    web_contents_impl->GetInputEventRouter()->RouteMouseEvent(
        rwhvb, &mouse_event, ui::LatencyInfo());
  }

  gfx::Point CalculateCenterPointOfAnchorElement(const GURL& url) {
    const std::string script_get_x = R"(
      const anchor = document.querySelector('a[href=$1]');
      const bounds = anchor.getBoundingClientRect();
      Math.floor(bounds.left + bounds.width / 2);
    )";

    const std::string script_get_y = R"(
      const anchor = document.querySelector('a[href=$1]');
      const bounds = anchor.getBoundingClientRect();
      Math.floor(bounds.top + bounds.height / 2);
    )";

    const float x = EvalJs(web_contents(), JsReplace(script_get_x, url.spec()))
                        .ExtractDouble();
    const float y = EvalJs(web_contents(), JsReplace(script_get_y, url.spec()))
                        .ExtractDouble();

    return gfx::ToFlooredPoint(gfx::PointF(x, y));
  }

  // Allows tests to specify port for the test server.
  int port_ = 0;

  base::ScopedMockElapsedTimersForTest scoped_test_timer_;

  net::test_server::EmbeddedTestServer ssl_server_{
      net::test_server::EmbeddedTestServer::TYPE_HTTPS};

  std::unique_ptr<test::PrerenderTestHelper> prerender_helper_;

  base::HistogramTester histogram_tester_;
  std::unique_ptr<ukm::TestAutoSetUkmRecorder> ukm_recorder_;
  std::unique_ptr<test::PreloadingAttemptUkmEntryBuilder>
      attempt_ukm_entry_builder_;
  std::unique_ptr<PreloadingAttemptPreviousPrimaryPageUkmEntryBuilder>
      attempt_previous_ukm_entry_builder_;
  std::unique_ptr<test::PreloadingPredictionUkmEntryBuilder>
      prediction_ukm_entry_builder_;
  std::unique_ptr<PreloadingPredictionPreviousPrimaryPageUkmEntryBuilder>
      prediction_previous_ukm_entry_builder_;
  std::unique_ptr<net::test_server::ControllableHttpResponse>
      pagehide_event_receiver_;
  base::test::ScopedFeatureList feature_list_;
};

// Test with Prerender2FallbackPrefetchSpecRules enabled/disabled.
class PrerenderBrowserTestFallbackEnabledDisabled
    : public PrerenderBrowserTest,
      public ::testing::WithParamInterface<bool> {
 public:
  PrerenderBrowserTestFallbackEnabledDisabled() {
    if (GetParam()) {
      scoped_feature_list_prerender2_fallback_.InitWithFeaturesAndParameters(
          {
              {
                  features::kPrerender2FallbackPrefetchSpecRules,
                  {
                      {
                          features::
                              kPrerender2FallbackPrefetchUseBlockUntilHeadTimetout
                                  .name,
                          "false",
                      },
                      {
                          features::kPrerender2FallbackPrefetchSchedulerPolicy
                              .name,
                          "NotUse",
                      },
                  },
              },
          },
          {});
    } else {
      scoped_feature_list_prerender2_fallback_.InitWithFeaturesAndParameters(
          {}, {
                  features::kPrerender2FallbackPrefetchSpecRules,
              });
    }
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_prerender2_fallback_;
};

INSTANTIATE_TEST_SUITE_P(
    /* no prefix */,
    PrerenderBrowserTestFallbackEnabledDisabled,
    ::testing::Bool());

// Test with Prerender2FallbackPrefetchSpecRules disabled.
//
// It is for tests that prefetch ahead of prerender makes untestable. List of
// such tests:
//
// - `PrerenderBrowserTestFallbackEnabledDisabled`: If
//    `kPreneder2FallbackPrefetchSpecRules` is enabled, prefetch ahead of
//    prerender is triggered and it blocks prerender. Prefetch in a background
//    tab is not scheduled. So, the prerender is never unblocked. Skip the test
//    as it is not testable.
// - `PrerenderInBackground_*`: Ditto.
// - `PreloadingTriggeringOutcomeForStartingPrerenderBeforeDestruction`: See the
//   test.
// - `CancelAllPrerenderUponActivationRequestArrival`: See the test.
// - `PrerenderWhenInitiatorInBackground_Queue_Processing`: See the test.
class PrerenderBrowserTestFallbackDisabled : public PrerenderBrowserTest {
 public:
  PrerenderBrowserTestFallbackDisabled() {
    // TODO(crbug.com/342089123): Add yet another feature flag to disable
    // prefetch ahead of prerender for SpeculationRules before removing
    // `kPrerender2FallbackPrefetchSpecRules`.
    scoped_feature_list_prerender2_fallback_.InitWithFeaturesAndParameters(
        {}, {
                features::kPrerender2FallbackPrefetchSpecRules,
            });
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_prerender2_fallback_;
};

class NoVarySearchPrerenderBrowserTest
    : public PrerenderBrowserTestFallbackEnabledDisabled {
 public:
  using StartedReason = PrerenderHost::WaitingForHeadersStartedReason;
  using FinishedReason = PrerenderHost::WaitingForHeadersFinishedReason;

  NoVarySearchPrerenderBrowserTest() {
    feature_list_.InitAndEnableFeatureWithParameters(
        features::kPrerender2NoVarySearch,
        {{"wait_for_headers_timeout_eager_prerender", "500"}});
  }

  ~NoVarySearchPrerenderBrowserTest() override = default;

 protected:
  void TestNoVarySearchHeaderFailure(const std::string& no_vary_search_header,
                                     FinishedReason expected_finished_reason);

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

INSTANTIATE_TEST_SUITE_P(
    /* no prefix */,
    NoVarySearchPrerenderBrowserTest,
    ::testing::Bool());

class NoVarySearchHintPrerenderHostObserver : public PrerenderHost::Observer {
 public:
  explicit NoVarySearchHintPrerenderHostObserver(
      PrerenderHost& prerender_host) {
    observation_.Observe(&prerender_host);
  }

  void OnWaitingForHeadersStarted(
      NavigationHandle& navigation_handle,
      PrerenderHost::WaitingForHeadersStartedReason reason) override {
    DCHECK(static_cast<NavigationRequest*>(&navigation_handle));
    ASSERT_FALSE(static_cast<NavigationRequest*>(&navigation_handle)
                     ->IsCommitDeferringConditionDeferredForTesting());
    ASSERT_FALSE(wait_for_headers_start_reason_.has_value());
    ASSERT_FALSE(wait_for_headers_finish_reason_.has_value());
    wait_for_headers_start_reason_ = reason;
  }

  void OnWaitingForHeadersFinished(
      PrerenderHost::WaitingForHeadersFinishedReason reason) override {
    ASSERT_FALSE(wait_for_headers_finish_reason_.has_value());
    wait_for_headers_finish_reason_ = reason;

    // Reset the observation here, not in Observer::OnHostDestroyed(), as
    // OnWaitingForHeadersFinished() is supposed to be called after that.
    observation_.Reset();
  }

  std::optional<PrerenderHost::WaitingForHeadersStartedReason>
  wait_for_headers_start_reason() const {
    return wait_for_headers_start_reason_;
  }

  std::optional<PrerenderHost::WaitingForHeadersFinishedReason>
  wait_for_headers_finish_reason() const {
    return wait_for_headers_finish_reason_;
  }

 private:
  std::optional<PrerenderHost::WaitingForHeadersStartedReason>
      wait_for_headers_start_reason_;
  std::optional<PrerenderHost::WaitingForHeadersFinishedReason>
      wait_for_headers_finish_reason_;

  base::ScopedObservation<PrerenderHost, PrerenderHost::Observer> observation_{
      this};
};

}  // namespace

// Test that the timer is enabled and cleared appropriately when navigating to
// a No-Vary-Search hint matched prerender successfully.
IN_PROC_BROWSER_TEST_P(
    NoVarySearchPrerenderBrowserTest,
    EagerTimerWorksCorrectlyForHeadersThatArriveBeforeTimeout) {
  const std::string kTestingRelativeUrl =
      "/delayed_with_no_vary_search?prerender";
  const std::string kPrerenderingRelativeUrl = kTestingRelativeUrl + "&a=5";
  // Create a HTTP response to control prerendering main-frame navigation.
  net::test_server::ControllableHttpResponse main_prerender_response(
      embedded_test_server(), kPrerenderingRelativeUrl);

  ASSERT_TRUE(embedded_test_server()->Start());

  const GURL kInitialUrl = embedded_test_server()->GetURL("/empty.html");
  const GURL kPrerenderingUrl =
      embedded_test_server()->GetURL(kPrerenderingRelativeUrl);
  const GURL kNavigationUrl =
      embedded_test_server()->GetURL(kTestingRelativeUrl + "&a=3");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Inject mock time task runner.
  auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
  PrerenderNoVarySearchHintCommitDeferringCondition::
      SetTimerTaskRunnerForTesting(task_runner);

  // Start prerendering `kPrerenderingUrl`.
  content::test::PrerenderHostCreationWaiter host_creation_waiter;
  AddPrerenderAsync(kPrerenderingUrl, R"(params=(\\\"a\\\"))");
  PrerenderHostId host_id = host_creation_waiter.Wait();
  auto* host =
      web_contents_impl()->GetPrerenderHostRegistry()->FindNonReservedHostById(
          host_id);
  ASSERT_TRUE(host);
  ASSERT_TRUE(host->no_vary_search_hint().has_value());

  // Add a testing PrerenderHost::Observer to the prerender host that we'd like
  // to activate.
  NoVarySearchHintPrerenderHostObserver observer(*host);

  // Start navigation in primary page to kNavigationUrl.
  TestActivationManager primary_page_manager(web_contents(), kNavigationUrl);
  // Start to navigate to kNavigationUrl
  std::unique_ptr<content::TestNavigationObserver> nav_observer =
      test::PrerenderTestHelper::NavigatePrimaryPageAsync(*web_contents_impl(),
                                                          kNavigationUrl);

  // Wait until the navigation is deferred by CommitDeferringCondition.
  ASSERT_TRUE(primary_page_manager.WaitForBeforeChecks());
  primary_page_manager.ResumeActivation();
  ASSERT_FALSE(host->were_headers_received());

  ASSERT_TRUE(host->WaitUntilHeadTimeout().is_positive());

  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  content::test::PrerenderHostObserver host_observer(*prerender_web_contents,
                                                     host_id);

  // Advance the prerender http response by sending headers.
  main_prerender_response.WaitForRequest();

  // Advance timer for half the wait until head timeout.
  task_runner->FastForwardBy(host->WaitUntilHeadTimeout() / 2);

  main_prerender_response.Send(
      net::HTTP_OK, /*content_type=*/"text/html", /*content=*/"",
      /*cookies=*/{}, /*extra_headers=*/{"No-Vary-Search: params=(\"a\")"});
  main_prerender_response.Send("Some Content");
  main_prerender_response.Done();

  ASSERT_TRUE(primary_page_manager.WaitForAfterChecks());
  primary_page_manager.ResumeActivation();

  // Wait for the navigation to finish.
  nav_observer->Wait();
  primary_page_manager.WaitForNavigationFinished();
  // Check that the prerender host was activated.
  ASSERT_TRUE(host_observer.was_activated());

  // Ensure the state has been propagated to renderer processes.
  ASSERT_EQ(false, EvalJs(web_contents(), "document.prerendering"));

  // The prerender host should be consumed.
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));

  ASSERT_TRUE(observer.wait_for_headers_start_reason().has_value());
  ASSERT_TRUE(observer.wait_for_headers_finish_reason().has_value());

  EXPECT_EQ(observer.wait_for_headers_start_reason().value(),
            StartedReason::kWithTimeout);
  EXPECT_EQ(observer.wait_for_headers_finish_reason().value(),
            FinishedReason::kNoVarySearchHeaderReceivedAndMatched);

  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.WaitingForHeadersFinishedReason.SpeculationRule",
      FinishedReason::kNoVarySearchHeaderReceivedAndMatched, 1);

  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.MatchableHostCountOnActivation", 1, 1);
}

// Tests the case where prerendering navigation fails while a potential
// activation navigation is waiting for the No-Vary-Search header.
// This is a regression test for crbug.com/420906968.
IN_PROC_BROWSER_TEST_P(NoVarySearchPrerenderBrowserTest,
                       FailureOnPrerenderNavigation) {
  const std::string kTestingRelativeUrl =
      "/delayed_with_no_vary_search?prerender";
  const std::string kPrerenderingRelativeUrl = kTestingRelativeUrl + "&a=5";
  // Create a HTTP response to control prerendering main-frame navigation.
  net::test_server::ControllableHttpResponse main_prerender_response(
      embedded_test_server(), kPrerenderingRelativeUrl);

  ASSERT_TRUE(embedded_test_server()->Start());

  const GURL initial_url = embedded_test_server()->GetURL("/empty.html");
  const GURL prerendering_url =
      embedded_test_server()->GetURL(kPrerenderingRelativeUrl);
  const GURL navigation_url =
      embedded_test_server()->GetURL(kTestingRelativeUrl + "&a=3");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), initial_url);

  // Start prerendering with the No-Vary-Search hint.
  content::test::PrerenderHostCreationWaiter host_creation_waiter;
  AddPrerenderAsync(prerendering_url, R"(params=(\\\"a\\\"))");
  PrerenderHostId host_id = host_creation_waiter.Wait();
  auto* host =
      web_contents_impl()->GetPrerenderHostRegistry()->FindNonReservedHostById(
          host_id);
  ASSERT_TRUE(host);
  ASSERT_TRUE(host->no_vary_search_hint().has_value());

  // Add a testing PrerenderHost::Observer to the prerender host that we'd like
  // to monitor.
  NoVarySearchHintPrerenderHostObserver observer(*host);

  // Start navigation in primary page.
  TestActivationManager primary_page_manager(web_contents(), navigation_url);
  std::unique_ptr<content::TestNavigationObserver> nav_observer =
      test::PrerenderTestHelper::NavigatePrimaryPageAsync(*web_contents_impl(),
                                                          navigation_url);

  // Wait until the navigation is deferred by CommitDeferringCondition.
  ASSERT_TRUE(primary_page_manager.WaitForBeforeChecks());
  primary_page_manager.ResumeActivation();
  ASSERT_FALSE(host->were_headers_received());

  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  content::test::PrerenderHostObserver host_observer(*prerender_web_contents,
                                                     host_id);

  // Abort the request. This fails the prerender navigation.
  main_prerender_response.WaitForRequest();
  main_prerender_response.Done();

  ASSERT_TRUE(primary_page_manager.WaitForAfterChecks());
  primary_page_manager.ResumeActivation();

  // Wait for the navigation to finish.
  nav_observer->Wait();
  primary_page_manager.WaitForNavigationFinished();

  // Check that the prerender host was not activated.
  ASSERT_FALSE(host_observer.was_activated());
  host_observer.WaitForDestroyed();

  ASSERT_TRUE(observer.wait_for_headers_start_reason().has_value());
  ASSERT_TRUE(observer.wait_for_headers_finish_reason().has_value());

  EXPECT_EQ(observer.wait_for_headers_start_reason().value(),
            StartedReason::kWithTimeout);

  if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
    ExpectFinalStatusForSpeculationRule(
        PrerenderFinalStatus::kPrerenderFailedDuringPrefetch);
    ExpectPreloadingAttemptUkm(
        {attempt_ukm_entry_builder().BuildEntry(
             PrimaryPageSourceId(), PreloadingType::kPrefetch,
             PreloadingEligibility::kEligible,
             PreloadingHoldbackStatus::kAllowed,
             PreloadingTriggeringOutcome::kFailure,
             ToPreloadingFailureReason(PrefetchStatus::kPrefetchFailedNetError),
             /*accurate=*/true,
             /*ready_time=*/std::nullopt,
             blink::mojom::SpeculationEagerness::kImmediate),
         attempt_ukm_entry_builder().BuildEntry(
             PrimaryPageSourceId(), PreloadingType::kPrerender,
             PreloadingEligibility::kEligible,
             PreloadingHoldbackStatus::kAllowed,
             PreloadingTriggeringOutcome::kFailure,
             ToPreloadingFailureReason(
                 PrerenderFinalStatus::kPrerenderFailedDuringPrefetch),
             /*accurate=*/false,
             /*ready_time=*/std::nullopt,
             blink::mojom::SpeculationEagerness::kImmediate)});
  } else {
    EXPECT_EQ(observer.wait_for_headers_finish_reason().value(),
              FinishedReason::kPrerenderNavigationFailed);
    histogram_tester().ExpectUniqueSample(
        "Prerender.Experimental.WaitingForHeadersFinishedReason."
        "SpeculationRule",
        FinishedReason::kPrerenderNavigationFailed, 1);
  }
}

// Test that the timer is enabled and cleared appropriately when navigating to
// a No-Vary-Search hint matched prerender with timeout waiting for headers.
// Flaky on android: crbug.com/395337644
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_EagerTimerWorksCorrectlyForHeadersThatArriveAfterTimeout \
  DISABLED_EagerTimerWorksCorrectlyForHeadersThatArriveAfterTimeout
#else
#define MAYBE_EagerTimerWorksCorrectlyForHeadersThatArriveAfterTimeout \
  EagerTimerWorksCorrectlyForHeadersThatArriveAfterTimeout
#endif
IN_PROC_BROWSER_TEST_P(
    NoVarySearchPrerenderBrowserTest,
    MAYBE_EagerTimerWorksCorrectlyForHeadersThatArriveAfterTimeout) {
  const std::string kTestingRelativeUrl =
      "/delayed_with_no_vary_search?prerender";
  const std::string kPrerenderingRelativeUrl = kTestingRelativeUrl + "&a=5";
  // Create a HTTP response to control prerendering main-frame navigation.
  net::test_server::ControllableHttpResponse main_prerender_response(
      embedded_test_server(), kPrerenderingRelativeUrl);
  const std::string kNavigationRelativeUrl = kTestingRelativeUrl + "&a=3";
  // Create a HTTP response to control the navigation in main-frame.
  net::test_server::ControllableHttpResponse main_navigation_response(
      embedded_test_server(), kNavigationRelativeUrl);

  ASSERT_TRUE(embedded_test_server()->Start());

  const GURL kInitialUrl = embedded_test_server()->GetURL("/empty.html");
  const GURL kPrerenderingUrl =
      embedded_test_server()->GetURL(kPrerenderingRelativeUrl);
  const GURL kNavigationUrl =
      embedded_test_server()->GetURL(kNavigationRelativeUrl);

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Inject mock time task runner.
  auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
  PrerenderNoVarySearchHintCommitDeferringCondition::
      SetTimerTaskRunnerForTesting(task_runner);

  // Start prerendering `kPrerenderingUrl`.
  content::test::PrerenderHostCreationWaiter host_creation_waiter;
  AddPrerenderAsync(kPrerenderingUrl, R"(params=(\\\"a\\\"))");
  PrerenderHostId host_id = host_creation_waiter.Wait();
  auto* host =
      web_contents_impl()->GetPrerenderHostRegistry()->FindNonReservedHostById(
          host_id);
  ASSERT_TRUE(host);
  ASSERT_TRUE(host->no_vary_search_hint().has_value());

  // Add a testing PrerenderHost::Observer to the prerender host that we'd like
  // to activate.
  NoVarySearchHintPrerenderHostObserver observer(*host);

  // Start navigation in primary page to kNavigationUrl.
  TestActivationManager primary_page_manager(web_contents(), kNavigationUrl);
  // Start to navigate to kNavigationUrl
  std::unique_ptr<content::TestNavigationObserver> nav_observer =
      test::PrerenderTestHelper::NavigatePrimaryPageAsync(*web_contents_impl(),
                                                          kNavigationUrl);

  // Wait until the navigation is deferred by CommitDeferringCondition.
  ASSERT_TRUE(primary_page_manager.WaitForBeforeChecks());
  primary_page_manager.ResumeActivation();
  ASSERT_FALSE(host->were_headers_received());

  ASSERT_TRUE(host->WaitUntilHeadTimeout().is_positive());

  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  content::test::PrerenderHostObserver host_observer(*prerender_web_contents,
                                                     host_id);

  // Advance the prerender http response by sending headers.
  main_prerender_response.WaitForRequest();

  // Advance timer for twice the wait until head timeout.
  task_runner->FastForwardBy(2 * host->WaitUntilHeadTimeout());

  main_prerender_response.Send(
      net::HTTP_OK, /*content_type=*/"text/html", /*content=*/"",
      /*cookies=*/{}, /*extra_headers=*/{"No-Vary-Search: params=(\"a\")"});
  main_prerender_response.Send("Some Content");
  main_prerender_response.Done();

  ASSERT_TRUE(primary_page_manager.WaitForAfterChecks());

  main_navigation_response.WaitForRequest();
  main_navigation_response.Send("Some Content");
  main_navigation_response.Done();

  // Wait for the navigation to finish.
  nav_observer->Wait();
  primary_page_manager.WaitForNavigationFinished();
  // Check that the prerender host was activated.
  ASSERT_FALSE(host_observer.was_activated());

  // Ensure the state has been propagated to renderer processes.
  ASSERT_EQ(false, EvalJs(web_contents(), "document.prerendering"));

  // The prerender host should be destroyed.
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));

  ASSERT_TRUE(observer.wait_for_headers_start_reason().has_value());
  ASSERT_TRUE(observer.wait_for_headers_finish_reason().has_value());

  EXPECT_EQ(observer.wait_for_headers_start_reason().value(),
            StartedReason::kWithTimeout);
  EXPECT_EQ(observer.wait_for_headers_finish_reason().value(),
            FinishedReason::kTimeoutElapsed);

  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.WaitingForHeadersFinishedReason.SpeculationRule",
      FinishedReason::kTimeoutElapsed, 1);

  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.MatchableHostCountOnActivation", 1, 1);
}

// Helper function to test cases where `no_vary_search_header` that does not
// match the No-Vary-Search hint is served and results in activation mismatch.
void NoVarySearchPrerenderBrowserTest::TestNoVarySearchHeaderFailure(
    const std::string& no_vary_search_header,
    FinishedReason expected_finished_reason) {
  const std::string kTestingRelativeUrl =
      "/delayed_with_no_vary_search?prerender";
  const std::string kPrerenderingRelativeUrl = kTestingRelativeUrl + "&a=5";
  // Create a HTTP response to control prerendering main-frame navigation.
  net::test_server::ControllableHttpResponse main_prerender_response(
      embedded_test_server(), kPrerenderingRelativeUrl);

  ASSERT_TRUE(embedded_test_server()->Start());

  const GURL kInitialUrl = embedded_test_server()->GetURL("/empty.html");
  const GURL kPrerenderingUrl =
      embedded_test_server()->GetURL(kPrerenderingRelativeUrl);
  const GURL kNavigationUrl =
      embedded_test_server()->GetURL(kTestingRelativeUrl + "&a=3");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Inject mock time task runner to avoid timeout.
  auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
  PrerenderNoVarySearchHintCommitDeferringCondition::
      SetTimerTaskRunnerForTesting(task_runner);

  // Start prerendering `kPrerenderingUrl`.
  content::test::PrerenderHostCreationWaiter host_creation_waiter;
  AddPrerenderAsync(kPrerenderingUrl, R"(params=(\\\"a\\\"))");
  PrerenderHostId host_id = host_creation_waiter.Wait();
  auto* host =
      web_contents_impl()->GetPrerenderHostRegistry()->FindNonReservedHostById(
          host_id);
  ASSERT_TRUE(host);
  ASSERT_TRUE(host->no_vary_search_hint().has_value());

  // Add a testing PrerenderHost::Observer to the prerender host that we'd like
  // to activate.
  NoVarySearchHintPrerenderHostObserver observer(*host);

  // Start navigation in primary page to kNavigationUrl.
  TestActivationManager primary_page_manager(web_contents(), kNavigationUrl);
  // Start to navigate to kNavigationUrl
  std::unique_ptr<content::TestNavigationObserver> nav_observer =
      test::PrerenderTestHelper::NavigatePrimaryPageAsync(*web_contents_impl(),
                                                          kNavigationUrl);

  // Wait until the navigation is deferred by CommitDeferringCondition.
  ASSERT_TRUE(primary_page_manager.WaitForBeforeChecks());
  primary_page_manager.ResumeActivation();
  ASSERT_FALSE(host->were_headers_received());

  ASSERT_TRUE(host->WaitUntilHeadTimeout().is_positive());

  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  content::test::PrerenderHostObserver host_observer(*prerender_web_contents,
                                                     host_id);

  // Advance the prerender http response by sending headers.
  main_prerender_response.WaitForRequest();

  main_prerender_response.Send(net::HTTP_OK, /*content_type=*/"text/html",
                               /*content=*/"",
                               /*cookies=*/{}, {no_vary_search_header});
  main_prerender_response.Send("Some Content");
  main_prerender_response.Done();

  // Wait for the navigation to finish.
  nav_observer->Wait();
  primary_page_manager.WaitForNavigationFinished();

  // Check that the prerender host was not activated as the header was not
  // valid.
  ASSERT_FALSE(host_observer.was_activated());

  ASSERT_TRUE(observer.wait_for_headers_start_reason().has_value());
  ASSERT_TRUE(observer.wait_for_headers_finish_reason().has_value());

  EXPECT_EQ(observer.wait_for_headers_start_reason().value(),
            StartedReason::kWithTimeout);
  EXPECT_EQ(observer.wait_for_headers_finish_reason().value(),
            expected_finished_reason);

  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.WaitingForHeadersFinishedReason.SpeculationRule",
      expected_finished_reason, 1);

  histogram_tester().ExpectTotalCount(
      "Prerender.Experimental.MatchableHostCountOnActivation", 1);
}

// Test that a No-Vary-Search header is malformed.
IN_PROC_BROWSER_TEST_P(NoVarySearchPrerenderBrowserTest,
                       MalformedNoVarySearchHeader) {
  TestNoVarySearchHeaderFailure("No-Vary-Search: malformed(\"a\")",
                                FinishedReason::kNoVarySearchHeaderParseFailed);
}

// Test that a No-Vary-Search header is default value.
IN_PROC_BROWSER_TEST_P(NoVarySearchPrerenderBrowserTest,
                       NoVarySearchHeaderWithDefaultValue) {
  TestNoVarySearchHeaderFailure(
      "No-Vary-Search: params=()",
      FinishedReason::kNoVarySearchHeaderReceivedButDefaultValue);
}

// Test that a No-Vary-Search header is not served.
IN_PROC_BROWSER_TEST_P(NoVarySearchPrerenderBrowserTest, NoNoVarySearchHeader) {
  TestNoVarySearchHeaderFailure("",
                                FinishedReason::kNoVarySearchHeaderNotReceived);
}

// Test that a No-Vary-Search header is received but does not match.
IN_PROC_BROWSER_TEST_P(NoVarySearchPrerenderBrowserTest,
                       UnmatchedNoVarySearchHeader) {
  TestNoVarySearchHeaderFailure(
      "No-Vary-Search: params=(\"different\")",
      FinishedReason::kNoVarySearchHeaderReceivedButNotMatched);
}

// Test that activation is successful when navigating to an inexact URL
// before No-Vary-Search header is back from the server, if the No-Vary-Search
// header is matching when it is received.
IN_PROC_BROWSER_TEST_P(NoVarySearchPrerenderBrowserTest,
                       HintActivationSuccessful) {
  const std::string kTestingRelativeUrl =
      "/delayed_with_no_vary_search?prerender";
  const std::string kPrerenderingRelativeUrl = kTestingRelativeUrl + "&a=5";
  // Create a HTTP response to control prerendering main-frame navigation.
  net::test_server::ControllableHttpResponse main_prerender_response(
      embedded_test_server(), kPrerenderingRelativeUrl);

  ASSERT_TRUE(embedded_test_server()->Start());

  const GURL kInitialUrl = embedded_test_server()->GetURL("/empty.html");
  const GURL kPrerenderingUrl =
      embedded_test_server()->GetURL(kPrerenderingRelativeUrl);
  const GURL kNavigationUrl =
      embedded_test_server()->GetURL(kTestingRelativeUrl + "&a=3");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Start prerendering `kPrerenderingUrl`.
  content::test::PrerenderHostCreationWaiter host_creation_waiter;
  AddPrerenderAsync(kPrerenderingUrl, R"(params=(\\\"a\\\"))");
  PrerenderHostId host_id = host_creation_waiter.Wait();
  auto* host =
      web_contents_impl()->GetPrerenderHostRegistry()->FindNonReservedHostById(
          host_id);
  ASSERT_TRUE(host);
  ASSERT_TRUE(host->no_vary_search_hint().has_value());

  // Add a PrerenderHost::Observer with default behaviour to increase
  // code coverage.
  PrerenderHost::Observer empty_observer;
  host->AddObserver(&empty_observer);

  NavigationHandleObserver activation_observer(web_contents(), kNavigationUrl);
  // Start navigation in primary page to kNavigationUrl.
  TestActivationManager primary_page_manager(shell()->web_contents(),
                                             kNavigationUrl);
  // Start to navigate to kNavigationUrl
  std::unique_ptr<content::TestNavigationObserver> nav_observer =
      test::PrerenderTestHelper::NavigatePrimaryPageAsync(*web_contents_impl(),
                                                          kNavigationUrl);

  // Wait until the navigation is deferred by CommitDeferringCondition.
  ASSERT_TRUE(primary_page_manager.WaitForBeforeChecks());
  primary_page_manager.ResumeActivation();
  ASSERT_FALSE(host->were_headers_received());

  // Make sure that the prerender host is not a match by IsUrlMatch.
  ASSERT_FALSE(host->IsUrlMatch(kNavigationUrl));
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  content::test::PrerenderHostObserver host_observer(*prerender_web_contents,
                                                     host_id);

  // Check that PrerenderNoVarySearchHintCommitDeferringCondition is deferring
  // the commit.
  NavigationRequest* nav_request =
      web_contents_impl()->GetPrimaryFrameTree().root()->navigation_request();
  EXPECT_TRUE(nav_request->IsCommitDeferringConditionDeferredForTesting());

  // The navigation should not have proceeded past NOT_STARTED because the
  // PrerenderCommitDeferringCondition is deferring it.
  EXPECT_EQ(nav_request->state(), NavigationRequest::NOT_STARTED);

  // Advance the prerender http response by sending headers.
  main_prerender_response.WaitForRequest();
  main_prerender_response.Send(
      net::HTTP_OK, /*content_type=*/"text/html", /*content=*/"",
      /*cookies=*/{}, /*extra_headers=*/{"No-Vary-Search: params=(\"a\")"});
  host_observer.WaitForHeaders();
  ASSERT_TRUE(host->were_headers_received());
  // Make sure that, after receiving headers the prerender host is a match by
  // IsUrlMatch.
  ASSERT_TRUE(host->IsUrlMatch(kNavigationUrl));
  EXPECT_TRUE(nav_request->IsCommitDeferringConditionDeferredForTesting());
  main_prerender_response.Send("Some Content");
  main_prerender_response.Done();

  ASSERT_TRUE(primary_page_manager.WaitForAfterChecks());
  primary_page_manager.ResumeActivation();

  // Wait for the navigation to finish.
  nav_observer->Wait();
  primary_page_manager.WaitForNavigationFinished();
  // Check that the prerender host was activated.
  ASSERT_TRUE(host_observer.was_activated());

  // Ensure the state has been propagated to renderer processes.
  ASSERT_EQ(false, EvalJs(web_contents(), "document.prerendering"));

  // The prerender host should be consumed.
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));

  // Activating the prerendered page should not issue a request.
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kActivated);
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kNavigationUrl);

  ukm::SourceId ukm_source_id = activation_observer.next_page_ukm_source_id();
  if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
    ExpectPreloadingAttemptUkm(
        {attempt_ukm_entry_builder().BuildEntry(
             ukm_source_id, PreloadingType::kPrefetch,
             PreloadingEligibility::kEligible,
             PreloadingHoldbackStatus::kAllowed,
             PreloadingTriggeringOutcome::kSuccess,
             PreloadingFailureReason::kUnspecified,
             /*accurate=*/true,
             /*ready_time=*/kMockElapsedTime,
             blink::mojom::SpeculationEagerness::kImmediate),
         attempt_ukm_entry_builder().BuildEntry(
             ukm_source_id, PreloadingType::kPrerender,
             PreloadingEligibility::kEligible,
             PreloadingHoldbackStatus::kAllowed,
             PreloadingTriggeringOutcome::kSuccess,
             PreloadingFailureReason::kUnspecified,
             /*accurate=*/true,
             /*ready_time=*/kMockElapsedTime,
             blink::mojom::SpeculationEagerness::kImmediate)});
  } else {
    ExpectPreloadingAttemptUkm({attempt_ukm_entry_builder().BuildEntry(
        ukm_source_id, PreloadingType::kPrerender,
        PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed,
        PreloadingTriggeringOutcome::kSuccess,
        PreloadingFailureReason::kUnspecified,
        /*accurate=*/true,
        /*ready_time=*/kMockElapsedTime,
        blink::mojom::SpeculationEagerness::kImmediate)});
  }

  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.MatchableHostCountOnActivation", 1, 1);
}

// Test that activation is not successful when navigating to an inexact URL
// before No-Vary-Search header is back from the server if the No-Vary-Search
// header is not matching when it is received.
IN_PROC_BROWSER_TEST_P(NoVarySearchPrerenderBrowserTest,
                       HintActivationUnsuccessful) {
  const std::string kTestingRelativeUrl =
      "/delayed_without_no_vary_search?prerender";
  const std::string kPrerenderingRelativeUrl = kTestingRelativeUrl + "&a=5";
  // Create a HTTP response to control prerendering main-frame navigation.
  net::test_server::ControllableHttpResponse main_prerender_response(
      embedded_test_server(), kPrerenderingRelativeUrl);

  const std::string kNavigationRelativeUrl = kTestingRelativeUrl + "&a=3";
  // Create a HTTP response to control main-frame navigation.
  net::test_server::ControllableHttpResponse main_navigation_response(
      embedded_test_server(), kNavigationRelativeUrl);

  ASSERT_TRUE(embedded_test_server()->Start());

  const GURL kInitialUrl = embedded_test_server()->GetURL("/empty.html");
  const GURL kPrerenderingUrl =
      embedded_test_server()->GetURL(kPrerenderingRelativeUrl);
  const GURL kNavigationUrl =
      embedded_test_server()->GetURL(kNavigationRelativeUrl);

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Start prerendering `kPrerenderingUrl`.
  content::test::PrerenderHostCreationWaiter host_creation_waiter;
  AddPrerenderAsync(kPrerenderingUrl, R"(params=(\\\"a\\\"))");
  PrerenderHostId host_id = host_creation_waiter.Wait();
  auto* host =
      web_contents_impl()->GetPrerenderHostRegistry()->FindNonReservedHostById(
          host_id);
  ASSERT_TRUE(host);
  ASSERT_TRUE(host->no_vary_search_hint().has_value());

  TestActivationManager primary_page_manager(shell()->web_contents(),
                                             kNavigationUrl);
  // Start navigation to kNavigationUrl.
  std::unique_ptr<content::TestNavigationObserver> nav_observer =
      test::PrerenderTestHelper::NavigatePrimaryPageAsync(*web_contents_impl(),
                                                          kNavigationUrl);
  // Wait until the navigation is deferred by CommitDeferringCondition.
  ASSERT_TRUE(primary_page_manager.WaitForBeforeChecks());
  primary_page_manager.ResumeActivation();

  ASSERT_FALSE(host->were_headers_received());
  NavigationRequest* nav_request =
      web_contents_impl()->GetPrimaryFrameTree().root()->navigation_request();
  // Make sure PrerenderHostRegistry selects this prerender as a potential
  // prerender host to activate.
  ASSERT_TRUE(host->IsNoVarySearchHintUrlMatch(kNavigationUrl));
  // Make sure that the prerender host is not a match by IsUrlMatch.
  ASSERT_FALSE(host->IsUrlMatch(kNavigationUrl));

  // Check that PrerenderNoVarySearchHintCommitDeferringCondition is deferring
  // the commit.
  EXPECT_TRUE(nav_request->IsCommitDeferringConditionDeferredForTesting());

  // The navigation should not have proceeded past NOT_STARTED because the
  // PrerenderCommitDeferringCondition is deferring it.
  EXPECT_EQ(nav_request->state(), NavigationRequest::NOT_STARTED);

  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  content::test::PrerenderHostObserver host_observer(*prerender_web_contents,
                                                     host_id);
  // Advance the prerender http response by sending headers.
  main_prerender_response.WaitForRequest();
  main_prerender_response.Send(net::HTTP_OK, /*content_type=*/"text/html",
                               /*content=*/"Some Content");
  host_observer.WaitForHeaders();
  ASSERT_TRUE(host->were_headers_received());
  // Make sure that, after receiving headers the prerender host is not a match
  // by IsUrlMatch.
  ASSERT_FALSE(host->IsUrlMatch(kNavigationUrl));
  main_prerender_response.Done();

  main_navigation_response.WaitForRequest();
  main_navigation_response.Send(net::HTTP_OK, /*content_type=*/"text/html",
                                /*content=*/"Other Content");
  main_navigation_response.Done();

  primary_page_manager.WaitForNavigationFinished();
  // Check that the prerender host was not activated.
  ASSERT_FALSE(host_observer.was_activated());

  // Wait for the navigation to finish.
  nav_observer->Wait();
  // The navigation should issue a request.
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kNavigationUrl);

  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.MatchableHostCountOnActivation", 1, 1);
}

// Test that activation is successful when navigating to an exact URL before
// No-Vary-Search header is back from the server.
IN_PROC_BROWSER_TEST_P(NoVarySearchPrerenderBrowserTest,
                       HintActivationSuccessful_ExactUrl) {
  const std::string testing_relative_url =
      "/delayed_with_no_vary_search?prerender";
  const std::string prerendering_relative_url = testing_relative_url + "&a=5";
  // Create a HTTP response to control prerendering main-frame navigation.
  net::test_server::ControllableHttpResponse main_prerender_response(
      embedded_test_server(), prerendering_relative_url);

  ASSERT_TRUE(embedded_test_server()->Start());

  const GURL initial_url = embedded_test_server()->GetURL("/empty.html");
  const GURL prerendering_url =
      embedded_test_server()->GetURL(prerendering_relative_url);
  const GURL navigation_url =
      embedded_test_server()->GetURL(prerendering_relative_url);

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), initial_url);

  // Start prerendering `kPrerenderingUrl`.
  content::test::PrerenderHostCreationWaiter host_creation_waiter;
  AddPrerenderAsync(prerendering_url, R"(params=(\\\"a\\\"))");
  PrerenderHostId host_id = host_creation_waiter.Wait();
  auto* host =
      web_contents_impl()->GetPrerenderHostRegistry()->FindNonReservedHostById(
          host_id);
  ASSERT_TRUE(host);
  ASSERT_TRUE(host->no_vary_search_hint().has_value());

  NavigationHandleObserver activation_observer(web_contents(), navigation_url);
  // Start navigation in primary page to kNavigationUrl.
  TestActivationManager primary_page_manager(shell()->web_contents(),
                                             navigation_url);
  // Start to navigate to kNavigationUrl
  std::unique_ptr<content::TestNavigationObserver> nav_observer =
      test::PrerenderTestHelper::NavigatePrimaryPageAsync(*web_contents_impl(),
                                                          navigation_url);

  // Wait until the navigation is deferred by CommitDeferringCondition.
  ASSERT_TRUE(primary_page_manager.WaitForBeforeChecks());
  primary_page_manager.ResumeActivation();
  ASSERT_FALSE(host->were_headers_received());

  // Make sure that the prerender host is a match by IsUrlMatch regardless of
  // the No-Vary-Search header.
  std::optional<UrlMatchType> match_type = host->IsUrlMatch(navigation_url);
  ASSERT_TRUE(match_type.has_value());
  ASSERT_EQ(match_type.value(), UrlMatchType::kExact);
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  content::test::PrerenderHostObserver host_observer(*prerender_web_contents,
                                                     host_id);

  // Check that PrerenderCommitDeferringCondition is deferring the commit.
  NavigationRequest* nav_request =
      web_contents_impl()->GetPrimaryFrameTree().root()->navigation_request();
  EXPECT_TRUE(nav_request->IsCommitDeferringConditionDeferredForTesting());

  // The navigation should not have proceeded past NOT_STARTED because the
  // PrerenderCommitDeferringCondition is deferring it.
  EXPECT_EQ(nav_request->state(), NavigationRequest::NOT_STARTED);

  // Advance the prerender http response by sending headers.
  main_prerender_response.WaitForRequest();
  main_prerender_response.Send(
      net::HTTP_OK, /*content_type=*/"text/html", /*content=*/"",
      /*cookies=*/{}, /*extra_headers=*/{"No-Vary-Search: params=(\"a\")"});
  host_observer.WaitForHeaders();
  ASSERT_TRUE(host->were_headers_received());
  // Make sure that, after receiving headers the prerender host is still a match
  // by IsUrlMatch.
  ASSERT_TRUE(host->IsUrlMatch(navigation_url));
  EXPECT_TRUE(nav_request->IsCommitDeferringConditionDeferredForTesting());
  main_prerender_response.Send("Some Content");
  main_prerender_response.Done();

  ASSERT_TRUE(primary_page_manager.WaitForAfterChecks());
  primary_page_manager.ResumeActivation();

  // Wait for the navigation to finish.
  nav_observer->Wait();
  primary_page_manager.WaitForNavigationFinished();
  // Check that the prerender host was activated.
  ASSERT_TRUE(host_observer.was_activated());
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kActivated);

  // PrerenderNoVarySearchHintCommitDeferringCondition was not be involved in
  // prerender activation, so the metric should not be recorded.
  histogram_tester().ExpectTotalCount(
      "Prerender.Experimental.WaitingForHeadersFinishedReason.SpeculationRule",
      0);

  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.MatchableHostCountOnActivation", 1, 1);
}

// Test that activation is successful when 2 matchable PrerenderHosts exist.
IN_PROC_BROWSER_TEST_P(NoVarySearchPrerenderBrowserTest,
                       MultipleMatchableHosts) {
  const std::string testing_relative_url =
      "/delayed_with_no_vary_search?prerender";
  const std::string prerendering_relative_url1 = testing_relative_url + "&a=5";
  const std::string prerendering_relative_url2 = testing_relative_url + "&a=7";
  // Create a HTTP response to control prerendering main-frame navigation.
  net::test_server::ControllableHttpResponse main_prerender_response1(
      embedded_test_server(), prerendering_relative_url1);
  const std::string navigation_relative_url = testing_relative_url + "&a=3";

  ASSERT_TRUE(embedded_test_server()->Start());

  const GURL initial_url = embedded_test_server()->GetURL("/empty.html");
  const GURL prerendering_url1 =
      embedded_test_server()->GetURL(prerendering_relative_url1);
  const GURL prerendering_url2 =
      embedded_test_server()->GetURL(prerendering_relative_url2);
  const GURL navigation_url =
      embedded_test_server()->GetURL(navigation_relative_url);

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), initial_url);

  // Start prerendering `prerendering_url1`.
  test::PrerenderHostCreationWaiter host_creation_waiter1;
  AddPrerenderAsync(prerendering_url1, R"(params=(\\\"a\\\"))");
  PrerenderHostId host_id1 = host_creation_waiter1.Wait();
  auto* host1 =
      web_contents_impl()->GetPrerenderHostRegistry()->FindNonReservedHostById(
          host_id1);
  ASSERT_TRUE(host1);
  ASSERT_TRUE(host1->no_vary_search_hint().has_value());
  test::PrerenderHostObserver host_observer1(*web_contents(), host_id1);

  // Start prerendering `prerendering_url2`.
  test::PrerenderHostCreationWaiter host_creation_waiter2;
  AddPrerenderAsync(prerendering_url2, R"(params=(\\\"a\\\"))");
  PrerenderHostId host_id2 = host_creation_waiter2.Wait();
  auto* host2 =
      web_contents_impl()->GetPrerenderHostRegistry()->FindNonReservedHostById(
          host_id2);
  ASSERT_TRUE(host2);
  ASSERT_TRUE(host2->no_vary_search_hint().has_value());
  test::PrerenderHostObserver host_observer2(*web_contents(), host_id2);

  NavigationHandleObserver activation_observer(web_contents(), navigation_url);
  // Start navigation in primary page to navigation_url.
  TestActivationManager primary_page_manager(shell()->web_contents(),
                                             navigation_url);
  // Start to navigate to navigation_url.
  std::unique_ptr<TestNavigationObserver> nav_observer =
      test::PrerenderTestHelper::NavigatePrimaryPageAsync(*web_contents(),
                                                          navigation_url);

  // Wait until the navigation is deferred by CommitDeferringCondition.
  ASSERT_TRUE(primary_page_manager.WaitForBeforeChecks());
  primary_page_manager.ResumeActivation();
  ASSERT_FALSE(host1->were_headers_received());

  // The prererender 2 should be destroyed as the prerender 1 is chosen for
  // activation.
  host_observer2.WaitForDestroyed();
  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::kOtherPrerenderedPageActivated);

  // Check that PrerenderCommitDeferringCondition is deferring the commit.
  NavigationRequest* nav_request =
      web_contents_impl()->GetPrimaryFrameTree().root()->navigation_request();
  EXPECT_TRUE(nav_request->IsCommitDeferringConditionDeferredForTesting());

  // The navigation should not have proceeded past NOT_STARTED because the
  // PrerenderCommitDeferringCondition is deferring it.
  EXPECT_EQ(nav_request->state(), NavigationRequest::NOT_STARTED);

  // Advance the prerender http response 1 by sending headers.
  main_prerender_response1.WaitForRequest();
  main_prerender_response1.Send(
      net::HTTP_OK, /*content_type=*/"text/html", /*content=*/"",
      /*cookies=*/{}, /*extra_headers=*/{"No-Vary-Search: params=(\"a\")"});
  host_observer1.WaitForHeaders();
  ASSERT_TRUE(host1->were_headers_received());
  // Make sure that, after receiving headers the prerender host is still a match
  // by IsUrlMatch.
  ASSERT_TRUE(host1->IsUrlMatch(navigation_url));
  main_prerender_response1.Send("Some Content");
  main_prerender_response1.Done();

  ASSERT_TRUE(primary_page_manager.WaitForAfterChecks());
  primary_page_manager.ResumeActivation();

  // Wait for the navigation to finish.
  nav_observer->Wait();
  primary_page_manager.WaitForNavigationFinished();
  // Check that the prerender host was activated.
  ASSERT_TRUE(host_observer1.was_activated());
  histogram_tester().ExpectBucketCount(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kActivated, 1);

  histogram_tester().ExpectTotalCount(
      "Prerender.Experimental.WaitingForHeadersFinishedReason.SpeculationRule",
      1);

  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.MatchableHostCountOnActivation", 2, 1);
}

// Tests that the speculationrules No-Vary-Search hint is populated for the
// PrerenderHost.
IN_PROC_BROWSER_TEST_P(NoVarySearchPrerenderBrowserTest, HintIsPopulated) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/no_vary_search_a.html?prerender");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Start prerendering `kPrerenderingUrl`.
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 0);
  PrerenderHostId host_id =
      AddPrerender(kPrerenderingUrl, R"(params=(\\\"a\\\"))");
  auto* host =
      web_contents_impl()->GetPrerenderHostRegistry()->FindNonReservedHostById(
          host_id);
  ASSERT_TRUE(host);
  ASSERT_TRUE(host->no_vary_search_hint().has_value());
}

// Tests that the speculationrules trigger works in the presence of
// No-Vary-Search for same URL.
IN_PROC_BROWSER_TEST_P(NoVarySearchPrerenderBrowserTest, ExactUrlMatch) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/no_vary_search_a.html?prerender");
  const GURL kNavigationUrl = kPrerenderingUrl;

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Start prerendering `kPrerenderingUrl`.
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 0);
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  ASSERT_TRUE(host_id);
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 1);

  NavigationHandleObserver activation_observer(web_contents(), kNavigationUrl);
  NavigatePrimaryPage(kNavigationUrl);
  // Ensure the state has been propagated to renderer processes.
  ASSERT_EQ(false, EvalJs(web_contents(), "document.prerendering"));

  // The prerender host should be consumed.
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));

  // Activating the prerendered page should not issue a request.
  EXPECT_EQ(GetRequestCount(kNavigationUrl), 1);
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kActivated);
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kNavigationUrl);
  histogram_tester().ExpectTotalCount(
      "Navigation.Prerender.NoVarySearchCommitDeferTime.SpeculationRule", 0);

  ukm::SourceId ukm_source_id = activation_observer.next_page_ukm_source_id();
  if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
    ExpectPreloadingAttemptUkm(
        {attempt_ukm_entry_builder().BuildEntry(
             ukm_source_id, PreloadingType::kPrefetch,
             PreloadingEligibility::kEligible,
             PreloadingHoldbackStatus::kAllowed,
             PreloadingTriggeringOutcome::kSuccess,
             PreloadingFailureReason::kUnspecified,
             /*accurate=*/true,
             /*ready_time=*/kMockElapsedTime,
             blink::mojom::SpeculationEagerness::kImmediate),
         attempt_ukm_entry_builder().BuildEntry(
             ukm_source_id, PreloadingType::kPrerender,
             PreloadingEligibility::kEligible,
             PreloadingHoldbackStatus::kAllowed,
             PreloadingTriggeringOutcome::kSuccess,
             PreloadingFailureReason::kUnspecified,
             /*accurate=*/true,
             /*ready_time=*/kMockElapsedTime,
             blink::mojom::SpeculationEagerness::kImmediate)});
  } else {
    ExpectPreloadingAttemptUkm({attempt_ukm_entry_builder().BuildEntry(
        ukm_source_id, PreloadingType::kPrerender,
        PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed,
        PreloadingTriggeringOutcome::kSuccess,
        PreloadingFailureReason::kUnspecified,
        /*accurate=*/true,
        /*ready_time=*/kMockElapsedTime,
        blink::mojom::SpeculationEagerness::kImmediate)});
  }
}

// Tests that the speculationrules trigger works in the presence of
// No-Vary-Search.
IN_PROC_BROWSER_TEST_P(NoVarySearchPrerenderBrowserTest, InexactUrlMatch) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/no_vary_search_a.html?prerender");
  const GURL kNavigationUrl = GetUrl("/no_vary_search_a.html?prerender&a=3");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Start prerendering `kPrerenderingUrl`.
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 0);
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  ASSERT_TRUE(host_id);
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 1);

  NavigationHandleObserver activation_observer(web_contents(), kNavigationUrl);
  NavigatePrimaryPage(kNavigationUrl);
  // Ensure the state has been propagated to renderer processes.
  ASSERT_EQ(false, EvalJs(web_contents(), "document.prerendering"));

  // The prerender host should be consumed.
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));
  EXPECT_FALSE(HasHostForUrl(kNavigationUrl));
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);

  // Activating the prerendered page should not issue a request.
  EXPECT_EQ(GetRequestCount(kNavigationUrl), 0);
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kActivated);
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kNavigationUrl);
  ASSERT_EQ(kNavigationUrl, EvalJs(web_contents(), "window.location.href"));
  histogram_tester().ExpectTotalCount(
      "Navigation.Prerender.NoVarySearchCommitDeferTime.SpeculationRule", 1);

  // URL match was inexact but should be recorded as accurate.
  ukm::SourceId ukm_source_id = activation_observer.next_page_ukm_source_id();
  if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
    ExpectPreloadingAttemptUkm(
        {attempt_ukm_entry_builder().BuildEntry(
             ukm_source_id, PreloadingType::kPrefetch,
             PreloadingEligibility::kEligible,
             PreloadingHoldbackStatus::kAllowed,
             PreloadingTriggeringOutcome::kSuccess,
             PreloadingFailureReason::kUnspecified,
             /*accurate=*/true,
             /*ready_time=*/kMockElapsedTime,
             blink::mojom::SpeculationEagerness::kImmediate),
         attempt_ukm_entry_builder().BuildEntry(
             ukm_source_id, PreloadingType::kPrerender,
             PreloadingEligibility::kEligible,
             PreloadingHoldbackStatus::kAllowed,
             PreloadingTriggeringOutcome::kSuccess,
             PreloadingFailureReason::kUnspecified,
             /*accurate=*/true,
             /*ready_time=*/kMockElapsedTime,
             blink::mojom::SpeculationEagerness::kImmediate)});
  } else {
    ExpectPreloadingAttemptUkm({attempt_ukm_entry_builder().BuildEntry(
        ukm_source_id, PreloadingType::kPrerender,
        PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed,
        PreloadingTriggeringOutcome::kSuccess,
        PreloadingFailureReason::kUnspecified,
        /*accurate=*/true,
        /*ready_time=*/kMockElapsedTime,
        blink::mojom::SpeculationEagerness::kImmediate)});
  }
}

// Tests that the speculationrules trigger works in the presence of
// No-Vary-Search for same URL in the presence of redirection.
IN_PROC_BROWSER_TEST_P(NoVarySearchPrerenderBrowserTest,
                       ExactMatchWithUrlRedirection) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering a URL that causes same-origin redirection.
  const GURL kRedirectedUrl = GetUrl("/no_vary_search_a.html?prerender");
  const GURL kPrerenderingUrl =
      GetUrl("/server-redirect?" + kRedirectedUrl.spec());

  AddPrerender(kPrerenderingUrl);
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  EXPECT_EQ(GetRequestCount(kRedirectedUrl), 1);

  // The prerender host should be registered for the initial request URL, not
  // the redirected URL.
  EXPECT_TRUE(HasHostForUrl(kPrerenderingUrl));
  EXPECT_FALSE(HasHostForUrl(kRedirectedUrl));

  NavigationHandleObserver activation_observer(web_contents(),
                                               kPrerenderingUrl);
  NavigatePrimaryPage(kPrerenderingUrl);
  // Ensure the state has been propagated to renderer processes.
  ASSERT_EQ(false, EvalJs(web_contents(), "document.prerendering"));

  // The prerender host should be consumed.
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));

  // Activating the prerendered page should not issue a request.
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  EXPECT_EQ(GetRequestCount(kRedirectedUrl), 1);

  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kActivated);
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kRedirectedUrl);
  histogram_tester().ExpectTotalCount(
      "Navigation.Prerender.NoVarySearchCommitDeferTime.SpeculationRule", 0);

  ukm::SourceId ukm_source_id = activation_observer.next_page_ukm_source_id();
  if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
    ExpectPreloadingAttemptUkm(
        {attempt_ukm_entry_builder().BuildEntry(
             ukm_source_id, PreloadingType::kPrefetch,
             PreloadingEligibility::kEligible,
             PreloadingHoldbackStatus::kAllowed,
             PreloadingTriggeringOutcome::kSuccess,
             PreloadingFailureReason::kUnspecified,
             /*accurate=*/true,
             /*ready_time=*/kMockElapsedTime,
             blink::mojom::SpeculationEagerness::kImmediate),
         attempt_ukm_entry_builder().BuildEntry(
             ukm_source_id, PreloadingType::kPrerender,
             PreloadingEligibility::kEligible,
             PreloadingHoldbackStatus::kAllowed,
             PreloadingTriggeringOutcome::kSuccess,
             PreloadingFailureReason::kUnspecified,
             /*accurate=*/true,
             /*ready_time=*/kMockElapsedTime,
             blink::mojom::SpeculationEagerness::kImmediate)});
  } else {
    ExpectPreloadingAttemptUkm({attempt_ukm_entry_builder().BuildEntry(
        ukm_source_id, PreloadingType::kPrerender,
        PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed,
        PreloadingTriggeringOutcome::kSuccess,
        PreloadingFailureReason::kUnspecified,
        /*accurate=*/true,
        /*ready_time=*/kMockElapsedTime,
        blink::mojom::SpeculationEagerness::kImmediate)});
  }
}

// Tests that the speculationrules trigger works in the presence of
// No-Vary-Search for inexact URL in the presence of redirection.
IN_PROC_BROWSER_TEST_P(NoVarySearchPrerenderBrowserTest,
                       InexactMatchWithUrlRedirection) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering a URL that causes same-origin redirection.
  const GURL kRedirectedUrl = GetUrl("/no_vary_search_a.html?prerender&a=2");
  const GURL kRedirectedUrlWithIgnoredQueryParam =
      GetUrl("/no_vary_search_a.html?prerender&a=3");
  const GURL kPrerenderingUrl =
      GetUrl("/server-redirect?" + kRedirectedUrl.spec());
  const GURL kNavigationUrl =
      GetUrl("/server-redirect?" + kRedirectedUrlWithIgnoredQueryParam.spec());

  AddPrerender(kPrerenderingUrl);
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  EXPECT_EQ(GetRequestCount(kRedirectedUrl), 1);

  // The prerender host should be registered for the initial request URL, not
  // the redirected URL.
  EXPECT_TRUE(HasHostForUrl(kPrerenderingUrl));
  EXPECT_FALSE(HasHostForUrl(kRedirectedUrl));

  NavigationHandleObserver activation_observer(web_contents(), kNavigationUrl);
  NavigatePrimaryPage(kNavigationUrl);
  // Ensure the state has been propagated to renderer processes.
  ASSERT_EQ(false, EvalJs(web_contents(), "document.prerendering"));

  // The prerender host should be consumed.
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));

  // Activating the prerendered page should not issue a request.
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  EXPECT_EQ(GetRequestCount(kRedirectedUrl), 1);
  EXPECT_EQ(GetRequestCount(kNavigationUrl), 0);
  EXPECT_EQ(GetRequestCount(kRedirectedUrlWithIgnoredQueryParam), 0);

  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kActivated);
  // Make sure the omnibox URL hasn't been updated to
  // kRedirectedUrlWithIgnoredQueryParam because we've used at navigation
  // the already redirected prerender renderer.
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kRedirectedUrl);
  ASSERT_EQ(kRedirectedUrl, EvalJs(web_contents(), "window.location.href"));
  histogram_tester().ExpectTotalCount(
      "Navigation.Prerender.NoVarySearchCommitDeferTime.SpeculationRule", 0);

  // URL match was inexact but should be recorded as accurate.
  ukm::SourceId ukm_source_id = activation_observer.next_page_ukm_source_id();
  if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
    ExpectPreloadingAttemptUkm(
        {attempt_ukm_entry_builder().BuildEntry(
             ukm_source_id, PreloadingType::kPrefetch,
             PreloadingEligibility::kEligible,
             PreloadingHoldbackStatus::kAllowed,
             PreloadingTriggeringOutcome::kSuccess,
             PreloadingFailureReason::kUnspecified,
             /*accurate=*/true,
             /*ready_time=*/kMockElapsedTime,
             blink::mojom::SpeculationEagerness::kImmediate),
         attempt_ukm_entry_builder().BuildEntry(
             ukm_source_id, PreloadingType::kPrerender,
             PreloadingEligibility::kEligible,
             PreloadingHoldbackStatus::kAllowed,
             PreloadingTriggeringOutcome::kSuccess,
             PreloadingFailureReason::kUnspecified,
             /*accurate=*/true,
             /*ready_time=*/kMockElapsedTime,
             blink::mojom::SpeculationEagerness::kImmediate)});
  } else {
    ExpectPreloadingAttemptUkm({attempt_ukm_entry_builder().BuildEntry(
        ukm_source_id, PreloadingType::kPrerender,
        PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed,
        PreloadingTriggeringOutcome::kSuccess,
        PreloadingFailureReason::kUnspecified,
        /*accurate=*/true,
        /*ready_time=*/kMockElapsedTime,
        blink::mojom::SpeculationEagerness::kImmediate)});
  }
}

// Tests that the speculationrules trigger works in the presence of
// No-Vary-Search for inexact URL in the presence of main frame navigation.
IN_PROC_BROWSER_TEST_P(NoVarySearchPrerenderBrowserTest,
                       InexactUrlMatchWithMainFrameNavigation) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/no_vary_search_a.html?prerender");
  const GURL kPrerenderingNextUrl = GetUrl("/empty.html?next");
  const GURL kNavigationUrl = GetUrl("/no_vary_search_a.html?prerender&a=3");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Start prerendering `kPrerenderingUrl`.
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 0);
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  ASSERT_TRUE(host_id);
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 1);

  // Navigate the prerendered page to `kPrerenderingNextUrl`.
  NavigatePrerenderedPage(host_id, kPrerenderingNextUrl);
  WaitForPrerenderLoadCompletion(host_id);

  NavigationHandleObserver activation_observer(web_contents(), kNavigationUrl);
  NavigatePrimaryPage(kNavigationUrl);
  // Ensure the state has been propagated to renderer processes.
  ASSERT_EQ(false, EvalJs(web_contents(), "document.prerendering"));

  // The prerender host should be consumed.
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));
  EXPECT_FALSE(HasHostForUrl(kNavigationUrl));
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  EXPECT_EQ(GetRequestCount(kPrerenderingNextUrl), 1);

  // Activating the prerendered page should not issue a request.
  EXPECT_EQ(GetRequestCount(kNavigationUrl), 0);
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kActivated);
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingNextUrl);
  ASSERT_EQ(kPrerenderingNextUrl,
            EvalJs(web_contents(), "window.location.href"));

  // URL match was inexact but should be recorded as accurate.
  ukm::SourceId ukm_source_id = activation_observer.next_page_ukm_source_id();
  if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
    ExpectPreloadingAttemptUkm(
        {attempt_ukm_entry_builder().BuildEntry(
             ukm_source_id, PreloadingType::kPrefetch,
             PreloadingEligibility::kEligible,
             PreloadingHoldbackStatus::kAllowed,
             PreloadingTriggeringOutcome::kSuccess,
             PreloadingFailureReason::kUnspecified,
             /*accurate=*/true,
             /*ready_time=*/kMockElapsedTime,
             blink::mojom::SpeculationEagerness::kImmediate),
         attempt_ukm_entry_builder().BuildEntry(
             ukm_source_id, PreloadingType::kPrerender,
             PreloadingEligibility::kEligible,
             PreloadingHoldbackStatus::kAllowed,
             PreloadingTriggeringOutcome::kSuccess,
             PreloadingFailureReason::kUnspecified,
             /*accurate=*/true,
             /*ready_time=*/kMockElapsedTime,
             blink::mojom::SpeculationEagerness::kImmediate)});
  } else {
    ExpectPreloadingAttemptUkm({attempt_ukm_entry_builder().BuildEntry(
        ukm_source_id, PreloadingType::kPrerender,
        PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed,
        PreloadingTriggeringOutcome::kSuccess,
        PreloadingFailureReason::kUnspecified,
        /*accurate=*/true,
        /*ready_time=*/kMockElapsedTime,
        blink::mojom::SpeculationEagerness::kImmediate)});
  }
}

// Tests that the speculationrules trigger works.
IN_PROC_BROWSER_TEST_P(PrerenderBrowserTestFallbackEnabledDisabled,
                       SpeculationRulesPrerender) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Start prerendering `kPrerenderingUrl`.
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 0);
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  ASSERT_TRUE(host_id);
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 1);

  NavigationHandleObserver activation_observer(web_contents(),
                                               kPrerenderingUrl);
  NavigatePrimaryPage(kPrerenderingUrl);
  // Ensure the state has been propagated to renderer processes.
  ASSERT_EQ(false, EvalJs(web_contents(), "document.prerendering"));

  // The prerender host should be consumed.
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));

  // Activating the prerendered page should not issue a request.
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kActivated);

  {
    // Cross-check that both Preloading_Prediction and Preloading_Attempt UKMs
    // are logged on successful activation for speculation rules prerender.
    ukm::SourceId ukm_source_id = activation_observer.next_page_ukm_source_id();
    auto attempt_ukm_entries = test_ukm_recorder()->GetEntries(
        Preloading_Attempt::kEntryName, test::kPreloadingAttemptUkmMetrics);
    auto prediction_ukm_entries =
        test_ukm_recorder()->GetEntries(Preloading_Prediction::kEntryName,
                                        test::kPreloadingPredictionUkmMetrics);
    EXPECT_EQ(prediction_ukm_entries.size(), 1u);
    if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
      EXPECT_EQ(attempt_ukm_entries.size(), 2u);
    } else {
      EXPECT_EQ(attempt_ukm_entries.size(), 1u);
    }

    auto prerender_page_load_ukm_entries =
        test_ukm_recorder()->GetEntriesByName(
            ukm::builders::PrerenderPageLoad::kEntryName);

    // Check that Preloading_Attempt, Preloading_Prediction and
    // PrerenderPageLoad are all associated with the same SourceId.
    // There are three navigations
    // 1) Navigation to initial Url
    // 2) Navigation inside prerender frame tree
    // 3) Prerender activation navigation => navigation_ids_[2].
    // activation_id represents the SourceId for activation navigation. Check
    // that all the UKM events are logged for this SourceId.
    ukm::SourceId activation_id = ToSourceId(navigation_ids_[2]);
    EXPECT_EQ(activation_id, prerender_page_load_ukm_entries.back()->source_id);
    EXPECT_EQ(activation_id, prediction_ukm_entries.back().source_id);
    EXPECT_EQ(activation_id, attempt_ukm_entries.back().source_id);

    if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
      ExpectPreloadingAttemptUkm(
          {attempt_ukm_entry_builder().BuildEntry(
               activation_id, PreloadingType::kPrefetch,
               PreloadingEligibility::kEligible,
               PreloadingHoldbackStatus::kAllowed,
               PreloadingTriggeringOutcome::kSuccess,
               PreloadingFailureReason::kUnspecified,
               /*accurate=*/true,
               /*ready_time=*/kMockElapsedTime,
               blink::mojom::SpeculationEagerness::kImmediate),
           attempt_ukm_entry_builder().BuildEntry(
               activation_id, PreloadingType::kPrerender,
               PreloadingEligibility::kEligible,
               PreloadingHoldbackStatus::kAllowed,
               PreloadingTriggeringOutcome::kSuccess,
               PreloadingFailureReason::kUnspecified,
               /*accurate=*/true,
               /*ready_time=*/kMockElapsedTime,
               blink::mojom::SpeculationEagerness::kImmediate)});
    } else {
      ExpectPreloadingAttemptUkm({attempt_ukm_entry_builder().BuildEntry(
          activation_id, PreloadingType::kPrerender,
          PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed,
          PreloadingTriggeringOutcome::kSuccess,
          PreloadingFailureReason::kUnspecified,
          /*accurate=*/true,
          /*ready_time=*/kMockElapsedTime,
          blink::mojom::SpeculationEagerness::kImmediate)});
    }

    ExpectPreloadingPredictionUkm({prediction_ukm_entry_builder().BuildEntry(
        ukm_source_id,
        /*confidence=*/100,
        /*accurate_prediction=*/true)});
  }

  // Collect metrics we recorded the renderer processes.
  FetchHistogramsFromChildProcesses();
  histogram_tester().ExpectTotalCount(
      "Prerender.Experimental.ActivationIPCDelay.SpeculationRule", 1u);
}

// Used for running tests that should commonly pass regardless of target hints.
class PrerenderTargetAgnosticBrowserTest
    : public PrerenderBrowserTest,
      public testing::WithParamInterface<std::tuple<std::string, bool>> {
 public:
  PrerenderTargetAgnosticBrowserTest() {
    if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
      scoped_feature_list_prerender2_fallback_.InitWithFeaturesAndParameters(
          {
              {
                  features::kPrerender2FallbackPrefetchSpecRules,
                  {
                      {
                          features::
                              kPrerender2FallbackPrefetchUseBlockUntilHeadTimetout
                                  .name,
                          "false",
                      },
                      {
                          features::kPrerender2FallbackPrefetchSchedulerPolicy
                              .name,
                          "NotUse",
                      },
                  },
              },
          },
          {});
    } else {
      scoped_feature_list_prerender2_fallback_.InitWithFeaturesAndParameters(
          {}, {
                  features::kPrerender2FallbackPrefetchSpecRules,
              });
    }
  }

  // Activates a prerendered page for `url` hosted on `prerender_web_contents`.
  void ActivatePrerenderedPage(WebContents& prerender_web_contents,
                               const GURL& url) {
    test::PrerenderHostObserver prerender_observer(prerender_web_contents, url);
    if (GetTargetHint() == "_blank") {
      TestNavigationObserver observer(&prerender_web_contents);
      test::PrerenderTestHelper::OpenNewWindowWithoutOpener(*web_contents(),
                                                            url);
      observer.WaitForNavigationFinished();
    } else {
      test::PrerenderTestHelper::NavigatePrimaryPage(*web_contents(), url);
    }
    ASSERT_TRUE(prerender_observer.was_activated());
  }

  std::string GetTargetHint() const { return std::get<0>(GetParam()); }
  bool IsPrerender2FallbackPrefetchSpecRulesEnabled() const {
    return std::get<1>(GetParam());
  }

  bool IsPrefetchAheadOfPrerenderTriggered() const {
    return GetTargetHint() == "_self" &&
           IsPrerender2FallbackPrefetchSpecRulesEnabled();
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_prerender2_fallback_;
};

INSTANTIATE_TEST_SUITE_P(
    /* no prefix */,
    PrerenderTargetAgnosticBrowserTest,
    testing::Combine(testing::Values("_self", "_blank"), testing::Bool()),
    [](const testing::TestParamInfo<std::tuple<std::string, bool>>& info) {
      return base::StringPrintf(
          "%s_%s", std::get<0>(info.param),
          std::get<1>(info.param) ? "FallbackEnabled" : "FallbackDisabled");
    });

class AutoSpeculationRulesPrerenderBrowserTest
    : public PrerenderBrowserTestFallbackEnabledDisabled {
 public:
  AutoSpeculationRulesPrerenderBrowserTest() {
    sub_feature_list_.InitAndEnableFeatureWithParameters(
        blink::features::kAutoSpeculationRules, {{"config", GetConfig()}});
  }

 protected:
  void SetUp() override {
    ssl_server().RegisterRequestHandler(base::BindLambdaForTesting(
        [&](const net::test_server::HttpRequest& request)
            -> std::unique_ptr<net::test_server::HttpResponse> {
          if (request.relative_url == kInitialUrlPath) {
            auto response =
                std::make_unique<net::test_server::BasicHttpResponse>();
            response->set_code(net::HTTP_OK);
            response->set_content_type("text/html");

            // This will trigger the auto speculation rules configured in
            // SetUp().
            response->set_content(
                "<!DOCTYPE html><main data-reactroot></main>");
            return response;
          }
          return nullptr;
        }));

    PrerenderBrowserTest::SetUp();
  }

  PreloadingPredictor PredictorToExpectInUkm() override {
    return content_preloading_predictor::
        kSpeculationRulesFromAutoSpeculationRules;
  }

  GURL GetInitialUrl() const { return GetUrl(kInitialUrlPath); }

  GURL GetPrerenderedUrl() const { return GetUrl(kPrerenderedUrlPath); }

  std::string GetConfig() const {
    // JavaScriptFramework::kReact is 9, and it is detected by the presence of
    // data-reactroot attributes.
    return base::StringPrintf(R"(
    {
      "framework_to_speculation_rules": {
        "9": "{\"prerender\":[{\"source\":\"list\", \"urls\":[\"%s\"]}]}"
      }
    }
    )",
                              kPrerenderedUrlPath);
  }

 private:
  base::test::ScopedFeatureList sub_feature_list_;

  static constexpr char kInitialUrlPath[] = "/start.html";
  static constexpr char kPrerenderedUrlPath[] = "/empty.html?prerender";
};

INSTANTIATE_TEST_SUITE_P(/* no prefix */,
                         AutoSpeculationRulesPrerenderBrowserTest,
                         testing::Bool());

class AutoSpeculationRulesPrerenderBrowserTestWithHoldback
    : public AutoSpeculationRulesPrerenderBrowserTest {
 public:
  AutoSpeculationRulesPrerenderBrowserTestWithHoldback() {
    sub_feature_list_.InitAndEnableFeatureWithParameters(
        blink::features::kAutoSpeculationRules,
        {{"config", GetConfig()}, {"holdback", "true"}});
  }

 private:
  base::test::ScopedFeatureList sub_feature_list_;
};

INSTANTIATE_TEST_SUITE_P(/* no prefix */,
                         AutoSpeculationRulesPrerenderBrowserTestWithHoldback,
                         testing::Bool());

IN_PROC_BROWSER_TEST_P(AutoSpeculationRulesPrerenderBrowserTest, Metrics) {
  const GURL kInitialUrl = GetInitialUrl();
  const GURL kPrerenderingUrl = GetPrerenderedUrl();

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  WaitForPrerenderLoadCompletion(kPrerenderingUrl);
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 1);

  NavigationHandleObserver activation_observer(web_contents(),
                                               kPrerenderingUrl);
  NavigatePrimaryPage(kPrerenderingUrl);
  // Ensure the state has been propagated to renderer processes.
  ASSERT_EQ(false, EvalJs(web_contents(), "document.prerendering"));

  // The prerender host should be consumed.
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));

  // Activating the prerendered page should not issue a request.
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);

  // Check UMA final status
  ExpectFinalStatusForSpeculationRuleFromAutoSpeculationRules(
      PrerenderFinalStatus::kActivated);

  // Check UKM metrics, the same as in the
  // PrerenderBrowserTest.SpeculationRulesPrerender test except the predictor is
  // overridden by the AutoSpeculationRulesPrerenderBrowserTest class.
  {
    // Cross-check that both Preloading_Prediction and Preloading_Attempt UKMs
    // are logged on successful activation for speculation rules prerender.
    ukm::SourceId ukm_source_id = activation_observer.next_page_ukm_source_id();
    auto attempt_ukm_entries = test_ukm_recorder()->GetEntries(
        Preloading_Attempt::kEntryName, test::kPreloadingAttemptUkmMetrics);
    auto prediction_ukm_entries =
        test_ukm_recorder()->GetEntries(Preloading_Prediction::kEntryName,
                                        test::kPreloadingPredictionUkmMetrics);
    EXPECT_EQ(prediction_ukm_entries.size(), 1u);
    if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
      EXPECT_EQ(attempt_ukm_entries.size(), 2u);
    } else {
      EXPECT_EQ(attempt_ukm_entries.size(), 1u);
    }

    auto prerender_page_load_ukm_entries =
        test_ukm_recorder()->GetEntriesByName(
            ukm::builders::PrerenderPageLoad::kEntryName);

    ukm::SourceId activation_id = ToSourceId(navigation_ids_[2]);
    EXPECT_EQ(activation_id, prerender_page_load_ukm_entries.back()->source_id);
    EXPECT_EQ(activation_id, prediction_ukm_entries.back().source_id);
    EXPECT_EQ(activation_id, attempt_ukm_entries.back().source_id);

    if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
      ExpectPreloadingAttemptUkm(
          {attempt_ukm_entry_builder().BuildEntry(
               activation_id, PreloadingType::kPrefetch,
               PreloadingEligibility::kEligible,
               PreloadingHoldbackStatus::kAllowed,
               PreloadingTriggeringOutcome::kSuccess,
               PreloadingFailureReason::kUnspecified,
               /*accurate=*/true,
               /*ready_time=*/kMockElapsedTime,
               blink::mojom::SpeculationEagerness::kImmediate),
           attempt_ukm_entry_builder().BuildEntry(
               activation_id, PreloadingType::kPrerender,
               PreloadingEligibility::kEligible,
               PreloadingHoldbackStatus::kAllowed,
               PreloadingTriggeringOutcome::kSuccess,
               PreloadingFailureReason::kUnspecified,
               /*accurate=*/true,
               /*ready_time=*/kMockElapsedTime,
               blink::mojom::SpeculationEagerness::kImmediate)});
    } else {
      ExpectPreloadingAttemptUkm({attempt_ukm_entry_builder().BuildEntry(
          activation_id, PreloadingType::kPrerender,
          PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed,
          PreloadingTriggeringOutcome::kSuccess,
          PreloadingFailureReason::kUnspecified,
          /*accurate=*/true,
          /*ready_time=*/kMockElapsedTime,
          blink::mojom::SpeculationEagerness::kImmediate)});
    }

    ExpectPreloadingPredictionUkm({prediction_ukm_entry_builder().BuildEntry(
        ukm_source_id,
        /*confidence=*/100,
        /*accurate_prediction=*/true)});
  }
}

IN_PROC_BROWSER_TEST_P(AutoSpeculationRulesPrerenderBrowserTestWithHoldback,
                       Metrics) {
#if BUILDFLAG(IS_MAC)
  // See https://crbug.com/496991016
  if (base::mac::MacOSMajorVersion() >= 26) {
    GTEST_SKIP() << "Disabled on macOS Tahoe and later.";
  }
#endif

  const GURL kInitialUrl = GetInitialUrl();
  const GURL kPrerenderingUrl = GetPrerenderedUrl();

  test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Wait for PrerenderHostRegistry to receive the holdback prerender
  // request, and it should be ignored.
  registry_observer.WaitForTrigger(kPrerenderingUrl);
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 0);

  NavigationHandleObserver next_page_observer(web_contents(), kPrerenderingUrl);
  NavigatePrimaryPage(kPrerenderingUrl);

  // No final status for holdbacks.

  // Check UKM metrics: similar to the non-holdback case, except for the
  // holdback status and no prerender page load entries.
  {
    // Cross-check that both Preloading_Prediction and Preloading_Attempt UKMs
    // are logged on successful activation for speculation rules prerender.
    ukm::SourceId ukm_source_id = next_page_observer.next_page_ukm_source_id();
    auto attempt_ukm_entries = test_ukm_recorder()->GetEntries(
        Preloading_Attempt::kEntryName, test::kPreloadingAttemptUkmMetrics);
    auto prediction_ukm_entries =
        test_ukm_recorder()->GetEntries(Preloading_Prediction::kEntryName,
                                        test::kPreloadingPredictionUkmMetrics);
    EXPECT_EQ(prediction_ukm_entries.size(), 1u);
    if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
      EXPECT_EQ(attempt_ukm_entries.size(), 2u);
    } else {
      EXPECT_EQ(attempt_ukm_entries.size(), 1u);
    }

    auto prerender_page_load_ukm_entries =
        test_ukm_recorder()->GetEntriesByName(
            ukm::builders::PrerenderPageLoad::kEntryName);

    ukm::SourceId next_page_id = ToSourceId(navigation_ids_[1]);
    EXPECT_TRUE(prerender_page_load_ukm_entries.empty());
    EXPECT_EQ(prediction_ukm_entries.back().source_id, next_page_id);
    EXPECT_EQ(attempt_ukm_entries.back().source_id, next_page_id);

    if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
      ExpectPreloadingAttemptUkm(
          {attempt_ukm_entry_builder().BuildEntry(
               next_page_id, PreloadingType::kPrefetch,
               PreloadingEligibility::kEligible,
               PreloadingHoldbackStatus::kAllowed,
               PreloadingTriggeringOutcome::kSuccess,
               PreloadingFailureReason::kUnspecified,
               /*accurate=*/true,
               /*ready_time=*/kMockElapsedTime,
               blink::mojom::SpeculationEagerness::kImmediate),
           attempt_ukm_entry_builder().BuildEntry(
               next_page_id, PreloadingType::kPrerender,
               PreloadingEligibility::kEligible,
               PreloadingHoldbackStatus::kHoldback,
               PreloadingTriggeringOutcome::kUnspecified,
               PreloadingFailureReason::kUnspecified,
               /*accurate=*/true,
               /*ready_time=*/std::nullopt,
               blink::mojom::SpeculationEagerness::kImmediate)});
    } else {
      ExpectPreloadingAttemptUkm({attempt_ukm_entry_builder().BuildEntry(
          next_page_id, PreloadingType::kPrerender,
          PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kHoldback,
          PreloadingTriggeringOutcome::kUnspecified,
          PreloadingFailureReason::kUnspecified,
          /*accurate=*/true,
          /*ready_time=*/std::nullopt,
          blink::mojom::SpeculationEagerness::kImmediate)});
    }

    ExpectPreloadingPredictionUkm({prediction_ukm_entry_builder().BuildEntry(
        ukm_source_id,
        /*confidence=*/100,
        /*accurate_prediction=*/true)});
  }
}

enum class PrerenderingResult { kSuccess, kFailed };
enum class BodySize { kSmall, kLarge };

class PrerenderAndPrefetchBrowserTest
    : public PrerenderBrowserTest,
      public testing::WithParamInterface<
          std::tuple<PrerenderingResult, BodySize>> {
 public:
  // Provides meaningful param names instead of /0, /1, ...
  static std::string DescribeParams(
      const testing::TestParamInfo<ParamType>& info) {
    auto [prerendering_result, body_size] = info.param;
    std::stringstream params_description;
    switch (prerendering_result) {
      case PrerenderingResult::kSuccess:
        params_description << "PrerenderSucceeded";
        break;
      case PrerenderingResult::kFailed:
        params_description << "PrerenderFailed";
        break;
    }
    switch (body_size) {
      case BodySize::kSmall:
        params_description << "_SmallBody";
        break;
      case BodySize::kLarge:
        params_description << "_LargeBody";
        break;
    }
    return params_description.str();
  }

 private:
  void SetUp() override {
    sub_feature_list_.InitWithFeaturesAndParameters(
        {
            {features::kPrefetchTesting,
             {
                 {features::kPrefetchReusableBodySizeLimit.name, "102118"},
             }},
        },
        {});
    PrerenderBrowserTest::SetUp();
  }

  void TearDown() override {
    PrerenderBrowserTest::TearDown();
    sub_feature_list_.Reset();
  }

  base::test::ScopedFeatureList sub_feature_list_;
};

IN_PROC_BROWSER_TEST_P(PrerenderAndPrefetchBrowserTest,
                       SpeculationRulesPrefetchThenPrerender) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = std::get<1>(GetParam()) == BodySize::kSmall
                                    ? GetUrl("/cacheable.html?prerender")
                                    : GetUrl("/cacheable_long.html?prerender");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Start prefetching `kPrerenderingUrl` and wait for its completion.
  PrefetchService* prefetch_service = PrefetchService::GetFromFrameTreeNodeId(
      current_frame_host()->GetFrameTreeNodeId());
  ASSERT_TRUE(prefetch_service);
  base::RunLoop run_loop;
  PrefetchContainer::SetPrefetchResponseCompletedCallbackForTesting(
      base::BindRepeating(
          [](base::RunLoop* run_loop, const GURL& url,
             base::WeakPtr<PrefetchContainer> prefetch_container) {
            CHECK(prefetch_container);
            CHECK_EQ(prefetch_container->GetURL(), url);
            run_loop->Quit();
          },
          &run_loop, kPrerenderingUrl));
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 0);
  AddPrefetchAsync(kPrerenderingUrl);
  run_loop.Run();
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 1);

  // Start prerendering `kPrerenderingUrl`.
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  ASSERT_TRUE(host_id);
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 1);

  switch (std::get<0>(GetParam())) {
    case PrerenderingResult::kSuccess:
      EXPECT_TRUE(HasHostForUrl(kPrerenderingUrl));
      break;
    case PrerenderingResult::kFailed:
      // Cancel prerendered page.
      const content::FrameTreeNodeId frame_tree_node_id =
          prerender_helper()
              ->GetPrerenderedMainFrameHost(host_id)
              ->GetFrameTreeNodeId();
      ASSERT_TRUE(web_contents_impl()->CancelPrerendering(
          FrameTreeNode::GloballyFindByID(frame_tree_node_id),
          PrerenderFinalStatus::kCancelAllHostsForTesting));
      EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));
      break;
  }

  // Start main navigation.
  NavigationHandleObserver activation_observer(web_contents(),
                                               kPrerenderingUrl);
  NavigatePrimaryPage(kPrerenderingUrl);
  auto delivery_type =
      EvalJs(web_contents()->GetPrimaryMainFrame(),
             "performance.getEntriesByType('navigation')[0].deliveryType");

  switch (std::get<0>(GetParam())) {
    case PrerenderingResult::kSuccess:
      // Main navigation activates the prerendered page even for the large page.
      ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kActivated);
      EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
      EXPECT_EQ(delivery_type, "navigational-prefetch");
      break;
    case PrerenderingResult::kFailed:
      // Main navigation shouldn't activate prerendered page (because it's
      // canceled).
      ExpectFinalStatusForSpeculationRule(
          PrerenderFinalStatus::kCancelAllHostsForTesting);

      if (std::get<1>(GetParam()) == BodySize::kSmall) {
        // The prefetched result should be still used for navigation for small
        // body, because it fits within PrefetchDataPipeTee buffer limit.
        EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
        EXPECT_EQ(delivery_type, "navigational-prefetch");
      } else {
        // The prefetched result can't be used for navigation for large body
        // due to PrefetchDataPipeTee buffer limit. A cached response from the
        // HTTP cache is used instead, we still should not see another request.
        EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
        EXPECT_EQ(delivery_type, "cache");
      }
      break;
  }

  switch (std::get<1>(GetParam())) {
    case BodySize::kSmall:
      EXPECT_EQ(GetBodyTextContent(), "This page is cacheable");
      break;

    case BodySize::kLarge:
      //  `document.body.textContent.trim().length` for
      //  `/find_in_long_page.html`
      EXPECT_EQ(GetBodyTextContent().size(), 102119u);
      break;
  }
}

INSTANTIATE_TEST_SUITE_P(
    /* no prefix */,
    PrerenderAndPrefetchBrowserTest,
    testing::Combine(testing::Values(PrerenderingResult::kSuccess,
                                     PrerenderingResult::kFailed),
                     testing::Values(BodySize::kSmall, BodySize::kLarge)),
    PrerenderAndPrefetchBrowserTest::DescribeParams);

// Tests that the speculationrules-triggered prerender would be destroyed after
// its initiator navigates away.
IN_PROC_BROWSER_TEST_P(PrerenderBrowserTestFallbackEnabledDisabled,
                       SpeculationInitiatorNavigateAway) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");

  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);

  // Navigate the initiator page to a non-prerendered page. This destroys the
  // prerendered page.
  test::PrerenderHostObserver host_observer(*web_contents_impl(), host_id);
  NavigatePrimaryPage(GetUrl("/empty.html?elsewhere"));
  host_observer.WaitForDestroyed();

  // The prerender host should be destroyed.
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));

  // Cross-check that in case where the navigation happens to a different page,
  // we log the correct metrics.
  ukm::SourceId ukm_source_id = PrimaryPageSourceId();
  if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
    ExpectPreloadingAttemptUkm({
        attempt_ukm_entry_builder().BuildEntry(
            ukm_source_id, PreloadingType::kPrefetch,
            PreloadingEligibility::kEligible,
            PreloadingHoldbackStatus::kAllowed,
            PreloadingTriggeringOutcome::kSuccess,
            PreloadingFailureReason::kUnspecified,
            /*accurate=*/true,
            /*ready_time=*/kMockElapsedTime,
            blink::mojom::SpeculationEagerness::kImmediate),
        attempt_ukm_entry_builder().BuildEntry(
            ukm_source_id, PreloadingType::kPrerender,
            PreloadingEligibility::kEligible,
            PreloadingHoldbackStatus::kAllowed,
            PreloadingTriggeringOutcome::kReady,
            PreloadingFailureReason::kUnspecified,
            /*accurate=*/false,
            /*ready_time=*/kMockElapsedTime,
            blink::mojom::SpeculationEagerness::kImmediate),
    });
  } else {
    ExpectPreloadingAttemptUkm({attempt_ukm_entry_builder().BuildEntry(
        ukm_source_id, PreloadingType::kPrerender,
        PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed,
        PreloadingTriggeringOutcome::kReady,
        PreloadingFailureReason::kUnspecified,
        /*accurate=*/false,
        /*ready_time=*/kMockElapsedTime,
        blink::mojom::SpeculationEagerness::kImmediate)});
  }
  ExpectPreloadingPredictionUkm({prediction_ukm_entry_builder().BuildEntry(
      ukm_source_id, /*confidence=*/100,
      /*accurate_prediction=*/false)});
}

// Tests that clicking a link can activate a prerender.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, ActivateOnLinkClick) {
  const GURL kInitialUrl = GetUrl("/simple_links.html");
  const GURL kPrerenderingUrl = GetUrl("/title2.html");

  // Navigate to an initial page which has a link to `kPrerenderingUrl`.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering `kPrerenderingUrl`.
  PrerenderHostId prerender_host_id = AddPrerender(kPrerenderingUrl);
  test::PrerenderHostObserver prerender_observer(*web_contents(),
                                                 prerender_host_id);

  // Click the link. It should activate the prerendered page.
  TestNavigationObserver nav_observer(web_contents());
  const std::string kLinkClickScript = R"(
      const link = document.querySelector('#same_site_link');
      link.click();
  )";
  EXPECT_TRUE(ExecJs(web_contents(), kLinkClickScript));
  nav_observer.WaitForNavigationFinished();
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);
  EXPECT_TRUE(prerender_observer.was_activated());
}

// Tests that clicking a link annotated with "target=_blank" cannot activate a
// prerender.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, ActivateOnLinkClick_TargetBlank) {
  const GURL kInitialUrl = GetUrl("/simple_links.html");
  const GURL kPrerenderingUrl = GetUrl("/title2.html");

  // Navigate to an initial page which has a link to `kPrerenderingUrl`.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering `kPrerenderingUrl`.
  PrerenderHostId prerender_host_id = AddPrerender(kPrerenderingUrl);
  test::PrerenderHostObserver prerender_observer(*web_contents(),
                                                 prerender_host_id);

  // Click the link annotated with "target=_blank". This should not activate the
  // prerendered page.
  TestNavigationObserver nav_observer(kPrerenderingUrl);
  nav_observer.StartWatchingNewWebContents();
  const std::string kLinkClickScript = R"(
      clickSameSiteNewWindowLink();
  )";
  EXPECT_TRUE(ExecJs(web_contents(), kLinkClickScript));
  nav_observer.WaitForNavigationFinished();
  EXPECT_EQ(nav_observer.last_navigation_url(), kPrerenderingUrl);
  EXPECT_FALSE(prerender_observer.was_activated());

  // The navigation occurred in a new WebContents, so the original WebContents
  // should still be showing the initial trigger page.
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);
  // Also, the prerendered page should still be alive.
  EXPECT_TRUE(HasHostForUrl(kPrerenderingUrl));

  // Navigate to `kPrerenderingUrl` on the original WebContents. This should
  // activate the prerendered page.
  NavigatePrimaryPage(kPrerenderingUrl);
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);
  EXPECT_TRUE(prerender_observer.was_activated());
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kActivated);
}

class PrerenderTargetHintBrowserTest : public PrerenderBrowserTest {
 public:
  void TestActivateOnWindowOpen(std::string_view window_features);

  std::string SpeculationRulesInsertionScriptWithBothTargetHint(
      const GURL& url,
      const std::string& action = "prerender") {
    constexpr char add_speculationrules_with_both_target_hints[] = R"({
      var script = document.createElement('script');
      script.type = 'speculationrules';
      script.text = `{"$2": [
          {"target_hint": "_self", "urls": ["$1"]},
          {"target_hint": "_blank", "urls": ["$1"]}
        ]
      }`;
      document.head.appendChild(script);
    })";

    return base::ReplaceStringPlaceholders(
        add_speculationrules_with_both_target_hints, {url.spec(), action},
        nullptr);
  }

  std::string SpeculationRulesInsertionScriptWithOneSelfAndTwoBlankTargetHint(
      const GURL& url,
      const std::string& action = "prerender") {
    constexpr char add_speculationrules_with_both_target_hints[] = R"({
      var script = document.createElement('script');
      script.type = 'speculationrules';
      script.text = `{"$2": [
          {"target_hint": "_self", "urls": ["$1"]},
          {"target_hint": "_blank", "urls": ["$1"]},
          {"target_hint": "_blank", "urls": ["$1"]}
        ]
      }`;
      document.head.appendChild(script);
    })";

    return base::ReplaceStringPlaceholders(
        add_speculationrules_with_both_target_hints, {url.spec(), action},
        nullptr);
  }

  std::string SpeculationRulesWithIdAndTargetHint(
      const GURL& url,
      const std::string& id,
      const std::string& target_hint,
      const std::string& action = "prerender") {
    constexpr char add_speculationrules_with_id_and_target_hint[] = R"({
      var script = document.createElement('script');
      script.type = 'speculationrules';
      script.id = '$1';
      script.text = `{"$4":
                      [{
                        "target_hint": "$2",
                        "urls": ["$3"]
                      }]
      }`;
      document.head.appendChild(script);
    })";

    return base::ReplaceStringPlaceholders(
        add_speculationrules_with_id_and_target_hint,
        {id, target_hint, url.spec(), action}, nullptr);
  }
};

// Tests that clicking a link annotated with "target=_blank" can activate a
// prerender whose target_hint is "_blank".
IN_PROC_BROWSER_TEST_F(PrerenderTargetHintBrowserTest,
                       ActivateOnLinkClick_TargetBlank_WithTargetHintBlank) {
  const GURL kInitialUrl = GetUrl("/simple_links.html");
  const GURL kPrerenderingUrl = GetUrl("/title2.html");

  // Navigate to an initial page which has a link to `kPrerenderingUrl`.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering `kPrerenderingUrl`.
  PrerenderHostId host_id = prerender_helper()->AddPrerender(
      kPrerenderingUrl, /*eagerness=*/std::nullopt, "_blank");
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  ASSERT_NE(prerender_web_contents, web_contents_impl());
  ExpectWebContentsIsForNewTabPrerendering(*prerender_web_contents);

  // Click the link annotated with "target=_blank". This should activate the
  // prerendered page.
  TestNavigationObserver activation_observer(kPrerenderingUrl);
  activation_observer.WatchExistingWebContents();
  test::PrerenderHostObserver prerender_observer(*prerender_web_contents,
                                                 host_id);
  const std::string kLinkClickScript = R"(
      clickSameSiteNewWindowLink();
  )";
  EXPECT_TRUE(ExecJs(web_contents(), kLinkClickScript));
  activation_observer.WaitForNavigationFinished();
  EXPECT_EQ(prerender_web_contents->GetLastCommittedURL(), kPrerenderingUrl);
  EXPECT_EQ(activation_observer.last_navigation_url(), kPrerenderingUrl);
  EXPECT_TRUE(prerender_observer.was_activated());
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));

  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kActivated);

  ukm::SourceId ukm_source_id = activation_observer.next_page_ukm_source_id();
  ExpectPreloadingAttemptUkm({attempt_ukm_entry_builder().BuildEntry(
      ukm_source_id, PreloadingType::kPrerender,
      PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed,
      PreloadingTriggeringOutcome::kSuccess,
      PreloadingFailureReason::kUnspecified,
      /*accurate=*/true,
      /*ready_time=*/kMockElapsedTime,
      blink::mojom::SpeculationEagerness::kImmediate)});

  ExpectPreloadingPredictionUkm({prediction_ukm_entry_builder().BuildEntry(
      ukm_source_id,
      /*confidence=*/100,
      /*accurate_prediction=*/true)});

  // The navigation occurred in a new WebContents, so the original WebContents
  // should still be showing the initial trigger page.
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);
}

// Tests that clicking a link annotated with "target=_blank" does not activate a
// mismatched prerender url whose target_hint is "_blank" and the navigation
// does not cancel the prerender.
IN_PROC_BROWSER_TEST_F(
    PrerenderTargetHintBrowserTest,
    DoesNotActivateOnMismatchedLinkClick_TargetBlank_WithTargetHintBlank) {
  const GURL initial_url = GetUrl("/simple_links.html");
  const GURL prerendering_url = GetUrl("/title2.html?different");

  // Navigate to an initial page which has a link other than `prerendering_url`.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Start prerendering `prerendering_url`.
  PrerenderHostId host_id = prerender_helper()->AddPrerender(
      prerendering_url, /*eagerness=*/std::nullopt, "_blank");
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  ASSERT_NE(prerender_web_contents, web_contents_impl());
  ExpectWebContentsIsForNewTabPrerendering(*prerender_web_contents);

  // Click the link annotated with "target=_blank" but different from the
  // prerendered url. This should not activate the prerendered page.
  TestNavigationObserver nav_observer(GetUrl("/title2.html"));
  nav_observer.StartWatchingNewWebContents();
  test::PrerenderHostObserver prerender_observer(*prerender_web_contents,
                                                 host_id);
  const std::string kLinkClickScript = R"(
      clickSameSiteNewWindowLink();
  )";
  EXPECT_TRUE(ExecJs(web_contents(), kLinkClickScript));
  nav_observer.WaitForNavigationFinished();
  EXPECT_FALSE(prerender_observer.was_activated());
  EXPECT_FALSE(HasHostForUrl(prerendering_url));

  // Navigating a different url than the prerendered url into a new tab should
  // not cancel the prerender.
  EXPECT_TRUE(prerender_helper()->HasNewTabHandle(host_id));

  // The navigation occurred in a new WebContents, so the original WebContents
  // should still be showing the initial trigger page.
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), initial_url);
}

// Tests that using window.open the prerendered url with a customized window
// name cannot activate a prerender whose target_hint is "_blank".
IN_PROC_BROWSER_TEST_F(
    PrerenderTargetHintBrowserTest,
    DoesNotActivateOnWindowOpen_WithCustomizedWindowName_WithTargetHintBlank) {
  const GURL initial_url = GetUrl("/simple_links.html");
  const GURL prerendering_url = GetUrl("/title2.html");

  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Start prerendering `prerendering_url`.
  PrerenderHostId host_id = prerender_helper()->AddPrerender(
      prerendering_url, /*eagerness=*/std::nullopt, "_blank");
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  ASSERT_NE(prerender_web_contents, web_contents_impl());
  ExpectWebContentsIsForNewTabPrerendering(*prerender_web_contents);

  // Use window.open a customized window name should not activate
  // `prerendering_url`.
  TestNavigationObserver nav_observer(prerendering_url);
  nav_observer.StartWatchingNewWebContents();
  test::PrerenderHostObserver prerender_observer(*prerender_web_contents,
                                                 host_id);

  std::string window_open_script =
      R"(window.open($1, 'WindowName', 'noopener');)";
  EXPECT_TRUE(ExecJs(web_contents(),
                     JsReplace(window_open_script, prerendering_url.spec())));

  nav_observer.WaitForNavigationFinished();
  EXPECT_FALSE(prerender_observer.was_activated());

  // Navigating prerendered url with a customized window name should not cancel
  // the prerender.
  EXPECT_TRUE(prerender_helper()->HasNewTabHandle(host_id));

  // The navigation occurred in a new WebContents, so the original WebContents
  // should still be showing the initial trigger page.
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), initial_url);
}

// Tests that clicking a link annotated with "target=_blank" can activate a
// prerender whose target_hint is "_blank" where the initiator page is in the
// background when the speculation rules were added.
IN_PROC_BROWSER_TEST_F(
    PrerenderTargetHintBrowserTest,
    BackgroundedPage_ActivateOnLinkClick_TargetBlank_WithTargetHintBlank) {
  const GURL initial_url = GetUrl("/simple_links.html");
  const GURL prerender_url = GetUrl("/title2.html");
  // Inject mock time task runner.
  auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
  PrerenderHostRegistry* registry =
      web_contents_impl()->GetPrerenderHostRegistry();
  registry->SetTaskRunnerForTesting(task_runner);

  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  web_contents()->WasHidden();

  // The timers should be still running.
  ASSERT_TRUE(registry->GetEmbedderTimerForTesting()->IsRunning());
  ASSERT_TRUE(registry->GetSpeculationRulesTimerForTesting()->IsRunning());

  // Start prerendering `prerender_url`.
  PrerenderHostId host_id = prerender_helper()->AddPrerender(
      prerender_url, /*eagerness=*/std::nullopt, "_blank");
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  ASSERT_NE(prerender_web_contents, web_contents_impl());
  ExpectWebContentsIsForNewTabPrerendering(*prerender_web_contents);
  web_contents()->WasShown();

  // The timers should be stopped after WasShown().
  ASSERT_FALSE(registry->GetEmbedderTimerForTesting()->IsRunning());
  ASSERT_FALSE(registry->GetSpeculationRulesTimerForTesting()->IsRunning());
  // Forward the time by
  // PrerenderHostRegistry::kTimeToLiveInBackgroundForSpeculationRules shouldn't
  // affect the prerender.
  task_runner->FastForwardBy(
      PrerenderHostRegistry::kTimeToLiveInBackgroundForSpeculationRules);

  // Click the link annotated with "target=_blank". This should activate the
  // prerendered page.
  TestNavigationObserver activation_observer(prerender_url);
  activation_observer.WatchExistingWebContents();
  test::PrerenderHostObserver prerender_observer(*prerender_web_contents,
                                                 host_id);
  const std::string kLinkClickScript = R"(
      clickSameSiteNewWindowLink();
  )";
  EXPECT_TRUE(ExecJs(web_contents(), kLinkClickScript));
  activation_observer.WaitForNavigationFinished();
  EXPECT_EQ(prerender_web_contents->GetLastCommittedURL(), prerender_url);
  EXPECT_EQ(activation_observer.last_navigation_url(), prerender_url);
  EXPECT_TRUE(prerender_observer.was_activated());
  EXPECT_FALSE(HasHostForUrl(prerender_url));

  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kActivated);

  ukm::SourceId ukm_source_id = activation_observer.next_page_ukm_source_id();
  ExpectPreloadingAttemptUkm({attempt_ukm_entry_builder().BuildEntry(
      ukm_source_id, PreloadingType::kPrerender,
      PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed,
      PreloadingTriggeringOutcome::kSuccess,
      PreloadingFailureReason::kUnspecified,
      /*accurate=*/true,
      /*ready_time=*/kMockElapsedTime,
      blink::mojom::SpeculationEagerness::kImmediate)});

  ExpectPreloadingPredictionUkm({prediction_ukm_entry_builder().BuildEntry(
      ukm_source_id,
      /*confidence=*/100,
      /*accurate_prediction=*/true)});

  // The navigation occurred in a new WebContents, so the original WebContents
  // should still be showing the initial trigger page.
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), initial_url);
}

// Tests that the prerendering started by a hidden initiator page will be
// canceled after timeout.
// TODO(b/40234240): Flaky on win.
#if BUILDFLAG(IS_WIN)
#define MAYBE_BackgroundedPageTimeout_TargetBlank_WithTargetHintBlank \
  DISABLED_BackgroundedPageTimeout_TargetBlank_WithTargetHintBlank
#else
#define MAYBE_BackgroundedPageTimeout_TargetBlank_WithTargetHintBlank \
  BackgroundedPageTimeout_TargetBlank_WithTargetHintBlank
#endif
IN_PROC_BROWSER_TEST_F(
    PrerenderTargetHintBrowserTest,
    MAYBE_BackgroundedPageTimeout_TargetBlank_WithTargetHintBlank) {
  const GURL initial_url = GetUrl("/simple_links.html");
  const GURL prerender_url = GetUrl("/title2.html");
  // Inject mock time task runner.
  auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
  PrerenderHostRegistry* registry =
      web_contents_impl()->GetPrerenderHostRegistry();
  registry->SetTaskRunnerForTesting(task_runner);

  // Navigate to an initial page which has a link to `prerender_url`.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  web_contents()->WasHidden();

  // The timers should be still running.
  ASSERT_TRUE(registry->GetSpeculationRulesTimerForTesting()->IsRunning());

  // Start prerendering `prerender_url`.
  PrerenderHostId host_id = prerender_helper()->AddPrerender(
      prerender_url, /*eagerness=*/std::nullopt, "_blank");
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  ASSERT_NE(prerender_web_contents, web_contents_impl());
  ExpectWebContentsIsForNewTabPrerendering(*prerender_web_contents);
  test::PrerenderHostObserver prerender_observer(*prerender_web_contents,
                                                 host_id);

  // Expire the timers.
  task_runner->FastForwardBy(
      PrerenderHostRegistry::kTimeToLiveInBackgroundForSpeculationRules);

  // The timers should cancel prerendering.
  prerender_observer.WaitForDestroyed();
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kTimeoutBackgrounded, 1);
}

IN_PROC_BROWSER_TEST_F(
    PrerenderTargetHintBrowserTest,
    PrerenderWhenInitiatorInBackground_Queue_Processing_WithTargetHint) {
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL initial_url = embedded_test_server()->GetURL("/empty.html");
  const GURL prerender_url1 =
      embedded_test_server()->GetURL("/empty.html?prerender1");
  const GURL prerender_url2 =
      embedded_test_server()->GetURL("/empty.html?prerender2");

  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  web_contents()->WasHidden();

  // Insert 2 URLs into the speculation rules at the same time.
  WebContents* prerender_web_contents = nullptr;
  WebContents* prerender2_web_contents = nullptr;

  base::RunLoop run_loop;
  auto creation_subscription = RegisterWebContentsCreationCallback(
      base::BindLambdaForTesting([&](WebContents* web_contents) {
        if (prerender_web_contents == nullptr) {
          prerender_web_contents = web_contents;
        } else {
          prerender2_web_contents = web_contents;
        }
        run_loop.QuitClosure().Run();
      }));
  AddPrerendersAsync({prerender_url1, prerender_url2},
                     /*eagerness=*/std::nullopt,
                     /*target_hint=*/"_blank");
  run_loop.Run();
  ExpectWebContentsIsForNewTabPrerendering(*prerender_web_contents);

  // Check the prerender host is already ready.
  prerender_helper()->WaitForPrerenderLoadCompletion(*prerender_web_contents,
                                                     prerender_url1);
  PrerenderHost* prerender_host =
      static_cast<WebContentsImpl*>(prerender_web_contents)
          ->GetPrerenderHostRegistry()
          ->FindHostByUrlForTesting(prerender_url1);
  auto* preloading_attempt_impl = static_cast<PreloadingAttemptImpl*>(
      prerender_host->preloading_attempt().get());
  EXPECT_EQ(test::PreloadingAttemptAccessor(preloading_attempt_impl)
                .GetTriggeringOutcome(),
            PreloadingTriggeringOutcome::kReady);

  // Currently, prerender_url2 will be cancelled since there is no queue
  // mechanism for prerender-into-new-tab yet.
  // TODO(crbug.com/350785853): Add queue mechanism and
  // update test expectation.
  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::kTabClosedWithoutUserGesture);
}

// Tests that clicking a link annotated with "target=_blank rel=noopener" cannot
// activate a prerender.
IN_PROC_BROWSER_TEST_F(PrerenderTargetHintBrowserTest,
                       ActivateOnLinkClick_TargetBlankWithNoopener) {
  const GURL kInitialUrl = GetUrl("/simple_links.html");
  const GURL kPrerenderingUrl = GetUrl("/title2.html");

  // Navigate to an initial page which has a link to `kPrerenderingUrl`.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering `kPrerenderingUrl`.
  PrerenderHostId prerender_host_id = AddPrerender(kPrerenderingUrl);
  test::PrerenderHostObserver prerender_observer(*web_contents(),
                                                 prerender_host_id);

  // Click the link annotated with "target=_blank rel=noopener". This should not
  // activate the prerendered page.
  TestNavigationObserver nav_observer(kPrerenderingUrl);
  nav_observer.StartWatchingNewWebContents();
  const std::string kLinkClickScript = R"(
      clickSameSiteNewWindowWithNoopenerLink();
  )";
  EXPECT_TRUE(ExecJs(web_contents(), kLinkClickScript));
  nav_observer.WaitForNavigationFinished();
  EXPECT_EQ(nav_observer.last_navigation_url(), kPrerenderingUrl);
  EXPECT_FALSE(prerender_observer.was_activated());

  // The navigation occurred in a new WebContents, so the original WebContents
  // should still be showing the initial trigger page.
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);
  // Also, the prerendered page should still be alive.
  EXPECT_TRUE(HasHostForUrl(kPrerenderingUrl));

  // Navigate to `kPrerenderingUrl` on the original WebContents. This should
  // activate the prerendered page.
  NavigatePrimaryPage(kPrerenderingUrl);
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);
  EXPECT_TRUE(prerender_observer.was_activated());
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kActivated);
}

// Tests that clicking a link annotated with "target=_blank rel=noopener" can
// activate a prerender whose target_hint is "_blank".
IN_PROC_BROWSER_TEST_F(
    PrerenderTargetHintBrowserTest,
    ActivateOnLinkClick_TargetBlankWithNoopener_WithTargetHintBlank) {
  const GURL kInitialUrl = GetUrl("/simple_links.html");
  const GURL kPrerenderingUrl = GetUrl("/title2.html");

  // Navigate to an initial page which has a link to `kPrerenderingUrl`.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering `kPrerenderingUrl`.
  PrerenderHostId host_id = prerender_helper()->AddPrerender(
      kPrerenderingUrl, /*eagerness=*/std::nullopt, "_blank");
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  ASSERT_NE(prerender_web_contents, web_contents_impl());
  ExpectWebContentsIsForNewTabPrerendering(*prerender_web_contents);

  // Click the link annotated with "target=_blank rel=noopener". This should
  // activate the prerendered page.
  TestNavigationObserver activation_observer(kPrerenderingUrl);
  activation_observer.WatchExistingWebContents();
  test::PrerenderHostObserver prerender_observer(*prerender_web_contents,
                                                 host_id);
  const std::string kLinkClickScript = R"(
      clickSameSiteNewWindowWithNoopenerLink();
  )";
  EXPECT_TRUE(ExecJs(web_contents(), kLinkClickScript));
  activation_observer.WaitForNavigationFinished();
  EXPECT_EQ(prerender_web_contents->GetLastCommittedURL(), kPrerenderingUrl);
  EXPECT_EQ(activation_observer.last_navigation_url(), kPrerenderingUrl);
  EXPECT_EQ(prerender_web_contents->GetLastCommittedURL(), kPrerenderingUrl);
  EXPECT_TRUE(prerender_observer.was_activated());
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));

  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kActivated);

  ukm::SourceId ukm_source_id = activation_observer.next_page_ukm_source_id();
  ExpectPreloadingAttemptUkm({attempt_ukm_entry_builder().BuildEntry(
      ukm_source_id, PreloadingType::kPrerender,
      PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed,
      PreloadingTriggeringOutcome::kSuccess,
      PreloadingFailureReason::kUnspecified,
      /*accurate=*/true,
      /*ready_time=*/kMockElapsedTime,
      blink::mojom::SpeculationEagerness::kImmediate)});

  ExpectPreloadingPredictionUkm({prediction_ukm_entry_builder().BuildEntry(
      ukm_source_id,
      /*confidence=*/100,
      /*accurate_prediction=*/true)});

  // The navigation occurred in a new WebContents, so the original WebContents
  // should still be showing the initial trigger page.
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);
}

// Tests that clicking a link annotated with "target=_blank rel=opener" cannot
// activate a prerender.
IN_PROC_BROWSER_TEST_F(PrerenderTargetHintBrowserTest,
                       ActivateOnLinkClick_TargetBlankWithOpener) {
  const GURL kInitialUrl = GetUrl("/simple_links.html");
  const GURL kPrerenderingUrl = GetUrl("/title2.html");

  // Navigate to an initial page which has a link to `kPrerenderingUrl`.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering `kPrerenderingUrl`.
  PrerenderHostId prerender_host_id = AddPrerender(kPrerenderingUrl);
  test::PrerenderHostObserver prerender_observer(*web_contents(),
                                                 prerender_host_id);

  // Click the link annotated with "target=_blank rel=opener". This should not
  // activate the prerendered page.
  TestNavigationObserver nav_observer(kPrerenderingUrl);
  nav_observer.StartWatchingNewWebContents();
  const std::string kLinkClickScript = R"(
      clickSameSiteNewWindowWithOpenerLink();
  )";
  EXPECT_TRUE(ExecJs(web_contents(), kLinkClickScript));
  nav_observer.WaitForNavigationFinished();
  EXPECT_EQ(nav_observer.last_navigation_url(), kPrerenderingUrl);
  EXPECT_FALSE(prerender_observer.was_activated());

  // The navigation occurred in a new WebContents, so the original WebContents
  // should still be showing the initial trigger page.
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);
  // Also, the prerendered page should still be alive.
  EXPECT_TRUE(HasHostForUrl(kPrerenderingUrl));

  // Navigate to `kPrerenderingUrl` on the original WebContents. The page opened
  // with "rel=opener" should prevent it from activating the prerendered page.
  NavigatePrimaryPage(kPrerenderingUrl);
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);
  EXPECT_FALSE(prerender_observer.was_activated());

  // The prerendered page should be destroyed on activation attempt.
  prerender_observer.WaitForDestroyed();
  EXPECT_TRUE(GetHostForUrl(kPrerenderingUrl).is_null());
  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::kActivatedWithAuxiliaryBrowsingContexts);
}

// Tests that clicking a link annotated with "target=_blank rel=opener" cannot
// activate a prerender whose target_hint is "_blank".
IN_PROC_BROWSER_TEST_F(
    PrerenderTargetHintBrowserTest,
    ActivateOnLinkClick_TargetBlankWithOpener_WithTargetHintBlank) {
  const GURL kInitialUrl = GetUrl("/simple_links.html");
  const GURL kPrerenderingUrl = GetUrl("/title2.html");

  // Navigate to an initial page which has a link to `kPrerenderingUrl`.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering `kPrerenderingUrl`.
  PrerenderHostId host_id = prerender_helper()->AddPrerender(
      kPrerenderingUrl, /*eagerness=*/std::nullopt, "_blank");
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  ASSERT_NE(prerender_web_contents, web_contents_impl());
  ExpectWebContentsIsForNewTabPrerendering(*prerender_web_contents);

  ukm::SourceId triggering_primary_page_source_id =
      web_contents_impl()->GetPrimaryMainFrame()->GetPageUkmSourceId();

  // Click the link annotated with "target=_blank rel=opener". This should not
  // activate the prerendered page.
  test::PrerenderHostObserver prerender_observer(*prerender_web_contents,
                                                 host_id);
  const std::string kLinkClickScript = R"(
      clickSameSiteNewWindowWithOpenerLink();
  )";
  EXPECT_TRUE(ExecJs(web_contents(), kLinkClickScript));
  // The WebContents pre-created for prerendering should not be used.
  EXPECT_NE(prerender_web_contents->GetLastCommittedURL(), kPrerenderingUrl);
  EXPECT_FALSE(prerender_observer.was_activated());
  // The host should still be available.
  EXPECT_TRUE(HasHostForUrl(*prerender_web_contents, kPrerenderingUrl));

  // The navigation occurred in a new WebContents, so the original WebContents
  // should still be showing the initial trigger page.
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Navigate to `kPrerenderingUrl` on the original WebContents. This should
  // destroy the prerendered page and its WebContents.
  NavigatePrimaryPage(kPrerenderingUrl);
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);
  EXPECT_FALSE(prerender_observer.was_activated());
  prerender_observer.WaitForDestroyed();
  EXPECT_TRUE(GetHostForUrl(kPrerenderingUrl).is_null());
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kTriggerDestroyed);

  // Wait for UKM recording in PreloadingDataImpl::WebContentsDestroyed() on
  // the destruction of the prerender WebContents.
  // TODO(nhiroki): Wait for that in a more deterministic way instead of
  // RunUntilIdle().
  base::RunLoop().RunUntilIdle();

  // The prerender WebContents doesn't have the primary page that can record UKM
  // on destruction. Instead, it asks the primary page hosted on the primary
  // WebContents to record UKM.
  ExpectPreloadingAttemptPreviousPrimaryPageUkm(
      attempt_previous_ukm_entry_builder().BuildEntry(
          triggering_primary_page_source_id, PreloadingType::kPrerender,
          PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed,
          PreloadingTriggeringOutcome::kReady,
          PreloadingFailureReason::kUnspecified,
          /*accurate=*/false,
          /*ready_time=*/kMockElapsedTime,
          blink::mojom::SpeculationEagerness::kImmediate));
  ExpectPreloadingPredictioPreviousPrimaryPageUkm(
      {prediction_previous_ukm_entry_builder().BuildEntry(
          triggering_primary_page_source_id,
          /*confidence=*/100,
          /*accurate=*/false)});
}

// `window_features` is passed to the 3rd argument of window.open().
void PrerenderTargetHintBrowserTest::TestActivateOnWindowOpen(
    std::string_view window_features) {
  const GURL initial_url = GetUrl("/simple_links.html");
  const GURL prerendering_url = GetUrl("/title2.html");

  // Navigate to an initial page which has a link to `prerendering_url`.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Start prerendering `prerendering_url`.
  PrerenderHostId host_id = prerender_helper()->AddPrerender(
      prerendering_url, /*eagerness=*/std::nullopt, "_blank");
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  ASSERT_NE(prerender_web_contents, web_contents_impl());
  ExpectWebContentsIsForNewTabPrerendering(*prerender_web_contents);

  // Open a new window with "_blank" and `window_features`. This should activate
  // the prerendered page.
  TestNavigationObserver activation_observer(prerendering_url);
  activation_observer.WatchExistingWebContents();
  test::PrerenderHostObserver prerender_observer(*prerender_web_contents,
                                                 host_id);
  const std::string script = base::StringPrintf(R"(
      window.open("title2.html", "_blank", "%s");
  )",
                                                window_features);
  EXPECT_TRUE(ExecJs(web_contents(), script));
  activation_observer.WaitForNavigationFinished();
  EXPECT_EQ(prerender_web_contents->GetLastCommittedURL(), prerendering_url);
  EXPECT_EQ(activation_observer.last_navigation_url(), prerendering_url);
  EXPECT_TRUE(prerender_observer.was_activated());
  EXPECT_FALSE(HasHostForUrl(*prerender_web_contents, prerendering_url));

  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kActivated);

  ukm::SourceId ukm_source_id = activation_observer.next_page_ukm_source_id();
  ExpectPreloadingAttemptUkm({attempt_ukm_entry_builder().BuildEntry(
      ukm_source_id, PreloadingType::kPrerender,
      PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed,
      PreloadingTriggeringOutcome::kSuccess,
      PreloadingFailureReason::kUnspecified,
      /*accurate=*/true,
      /*ready_time=*/kMockElapsedTime,
      blink::mojom::SpeculationEagerness::kImmediate)});

  // The navigation occurred in a new WebContents, so the original WebContents
  // should still be showing the initial trigger page.
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), initial_url);
}

// Tests that adding speculation rules with both target_hint and removes
// target_hint=_self won't affect prerender activation on target_hint=_blank.
IN_PROC_BROWSER_TEST_F(PrerenderTargetHintBrowserTest,
                       PrerenderBothTargetHintButRemovesTargetHintSelf) {
  const GURL initial_url = GetUrl("/simple_links.html");
  const GURL prerendering_url = GetUrl("/title2.html");

  const std::string add_speculation_rules_target_hint_self_script =
      SpeculationRulesWithIdAndTargetHint(prerendering_url, "self_specrules",
                                          "_self");
  const std::string add_speculation_rules_target_hint_blank_script =
      SpeculationRulesWithIdAndTargetHint(prerendering_url, "blank_specrules",
                                          "_blank");

  // Navigate to an initial page which has a link to `prerendering_url`.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Adding speculation rules with target_hint=_self.
  EXPECT_TRUE(
      ExecJs(web_contents(), add_speculation_rules_target_hint_self_script));
  prerender_helper()->WaitForPrerenderLoadCompletion(*web_contents(),
                                                     prerendering_url);

  // Adding speculation rules with target_hint=_blank.
  WebContents* new_tab_prerender_web_contents = nullptr;
  base::RunLoop run_loop;

  auto creation_subscription = RegisterWebContentsCreationCallback(
      base::BindLambdaForTesting([&](content::WebContents* web_contents) {
        new_tab_prerender_web_contents = web_contents;
        run_loop.QuitClosure().Run();
      }));

  EXPECT_TRUE(
      ExecJs(web_contents(), add_speculation_rules_target_hint_blank_script));
  // Wait for the new tab prerender.
  run_loop.Run();

  prerender_helper()->WaitForPrerenderLoadCompletion(
      *new_tab_prerender_web_contents, prerendering_url);

  ASSERT_NE(new_tab_prerender_web_contents, web_contents_impl());
  ExpectWebContentsIsForNewTabPrerendering(*new_tab_prerender_web_contents);

  ASSERT_TRUE(
      ExecJs(web_contents_impl()->GetPrimaryMainFrame(),
             "document.querySelector('script[id=self_specrules]').remove()"));

  // Speculationrules removal for the initiator tab shouldn't cancel the
  // prerender in the new WebContents.
  EXPECT_FALSE(HasHostForUrl(*web_contents(), prerendering_url));
  EXPECT_TRUE(HasHostForUrl(*new_tab_prerender_web_contents, prerendering_url));

  // Open a new window with "_blank" and `noopener`. This should activate
  // the prerendered page.
  test::PrerenderHostObserver new_tab_prerender_observer(
      *new_tab_prerender_web_contents, prerendering_url);

  {
    const std::string new_tab_opener_script =
        "window.open(\"title2.html\", \"_blank\", \"noopener\")";
    EXPECT_TRUE(ExecJs(web_contents(), new_tab_opener_script));
    new_tab_prerender_observer.WaitForActivation();
    EXPECT_EQ(new_tab_prerender_web_contents->GetLastCommittedURL(),
              prerendering_url);
    EXPECT_FALSE(
        HasHostForUrl(*new_tab_prerender_web_contents, prerendering_url));
  }
}

// Tests that adding speculation rules with both target_hint and removes
// target_hint=_blank won't affect prerender activation on target_hint=_self.
IN_PROC_BROWSER_TEST_F(PrerenderTargetHintBrowserTest,
                       PrerenderBothTargetHintButRemovesTargetHintBlank) {
  const GURL initial_url = GetUrl("/simple_links.html");
  const GURL prerendering_url = GetUrl("/title2.html");

  const std::string add_speculation_rules_target_hint_self_script =
      SpeculationRulesWithIdAndTargetHint(prerendering_url, "self_specrules",
                                          "_self");
  const std::string add_speculation_rules_target_hint_blank_script =
      SpeculationRulesWithIdAndTargetHint(prerendering_url, "blank_specrules",
                                          "_blank");

  // Navigate to an initial page which has a link to `prerendering_url`.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Adding speculation rules with target_hint=_self.
  EXPECT_TRUE(
      ExecJs(web_contents(), add_speculation_rules_target_hint_self_script));
  prerender_helper()->WaitForPrerenderLoadCompletion(*web_contents(),
                                                     prerendering_url);
  // Adding speculation rules with target_hint=_blank.
  WebContents* new_tab_prerender_web_contents = nullptr;
  base::RunLoop run_loop;

  auto creation_subscription = RegisterWebContentsCreationCallback(
      base::BindLambdaForTesting([&](content::WebContents* web_contents) {
        new_tab_prerender_web_contents = web_contents;
        run_loop.QuitClosure().Run();
      }));

  EXPECT_TRUE(
      ExecJs(web_contents(), add_speculation_rules_target_hint_blank_script));
  // Wait for the new tab prerender.
  run_loop.Run();

  prerender_helper()->WaitForPrerenderLoadCompletion(
      *new_tab_prerender_web_contents, prerendering_url);

  ASSERT_NE(new_tab_prerender_web_contents, web_contents_impl());
  ExpectWebContentsIsForNewTabPrerendering(*new_tab_prerender_web_contents);
  PrerenderHostId new_tab_host_id = test::PrerenderTestHelper::GetHostForUrl(
      *new_tab_prerender_web_contents, prerendering_url);

  test::PrerenderHostObserver new_tab_prerender_observer(
      *new_tab_prerender_web_contents, new_tab_host_id);

  ASSERT_TRUE(
      ExecJs(web_contents_impl()->GetPrimaryMainFrame(),
             "document.querySelector('script[id=blank_specrules]').remove()"));

  // Speculationrules removal for the new tab shouldn't cancel the prerender in
  // the initial WebContents.
  EXPECT_TRUE(HasHostForUrl(*web_contents(), prerendering_url));
  new_tab_prerender_observer.WaitForDestroyed();

  test::PrerenderHostObserver prerender_observer(*web_contents(),
                                                 prerendering_url);

  // The prerender in the initial WebContents should be able to be activated.
  {
    ASSERT_TRUE(ExecJs(web_contents()->GetPrimaryMainFrame(),
                       JsReplace("location = $1", prerendering_url)));
    prerender_observer.WaitForActivation();
  }
}

// Tests that speculation rules with both target_hint in one script section can
// be prerendered and activated correctly.
IN_PROC_BROWSER_TEST_F(PrerenderTargetHintBrowserTest,
                       ActivateOnBothTargetHint) {
  const GURL initial_url = GetUrl("/simple_links.html");
  const GURL prerendering_url = GetUrl("/title2.html");

  const std::string add_speculation_rules_script =
      SpeculationRulesInsertionScriptWithBothTargetHint(prerendering_url);

  // Navigate to an initial page which has a link to `prerendering_url`.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Start prerendering `prerendering_url`.
  WebContents* new_tab_prerender_web_contents = nullptr;
  base::RunLoop run_loop;

  auto creation_subscription = RegisterWebContentsCreationCallback(
      base::BindLambdaForTesting([&](content::WebContents* web_contents) {
        new_tab_prerender_web_contents = web_contents;
        run_loop.QuitClosure().Run();
      }));

  EXPECT_TRUE(ExecJs(web_contents(), add_speculation_rules_script));
  // Wait for the new tab prerender.
  run_loop.Run();

  prerender_helper()->WaitForPrerenderLoadCompletion(*web_contents(),
                                                     prerendering_url);
  prerender_helper()->WaitForPrerenderLoadCompletion(
      *new_tab_prerender_web_contents, prerendering_url);

  ASSERT_NE(new_tab_prerender_web_contents, web_contents_impl());
  ExpectWebContentsIsForNewTabPrerendering(*new_tab_prerender_web_contents);

  // Open a new window with "_blank" and `noopener`. This should activate
  // the prerendered page.
  test::PrerenderHostObserver new_tab_prerender_observer(
      *new_tab_prerender_web_contents, prerendering_url);
  test::PrerenderHostObserver prerender_observer(*web_contents(),
                                                 prerendering_url);

  {
    const std::string new_tab_opener_script =
        "window.open(\"title2.html\", \"_blank\", \"noopener\")";
    EXPECT_TRUE(ExecJs(web_contents(), new_tab_opener_script));
    new_tab_prerender_observer.WaitForActivation();
    EXPECT_EQ(new_tab_prerender_web_contents->GetLastCommittedURL(),
              prerendering_url);

    // Prerender activation in the new tab shouldn't cancel the prerender in
    // the initial WebContents.
    EXPECT_TRUE(HasHostForUrl(*web_contents(), prerendering_url));
    EXPECT_FALSE(
        HasHostForUrl(*new_tab_prerender_web_contents, prerendering_url));
  }

  // The prerender in the initial WebContents should be able to be activated.
  {
    ASSERT_TRUE(ExecJs(web_contents()->GetPrimaryMainFrame(),
                       JsReplace("location = $1", prerendering_url)));
    prerender_observer.WaitForActivation();
  }
}

// Tests that speculation rules with 1 _self and 2 _blank target_hints in one
// script section can be prerendered and activated correctly.
IN_PROC_BROWSER_TEST_F(PrerenderTargetHintBrowserTest,
                       ActivateOnOneSelfAndTwoBlankTargetHint) {
  const GURL initial_url = GetUrl("/simple_links.html");
  const GURL prerendering_url = GetUrl("/title2.html");

  const std::string add_speculation_rules_script =
      SpeculationRulesInsertionScriptWithOneSelfAndTwoBlankTargetHint(
          prerendering_url);

  // Navigate to an initial page which has a link to `prerendering_url`.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Start prerendering `prerendering_url`.
  WebContents* new_tab_prerender_web_contents = nullptr;
  base::RunLoop run_loop;

  auto creation_subscription = RegisterWebContentsCreationCallback(
      base::BindLambdaForTesting([&](content::WebContents* web_contents) {
        new_tab_prerender_web_contents = web_contents;
        run_loop.QuitClosure().Run();
      }));

  EXPECT_TRUE(ExecJs(web_contents(), add_speculation_rules_script));
  // Wait for the new tab prerender.
  run_loop.Run();

  prerender_helper()->WaitForPrerenderLoadCompletion(*web_contents(),
                                                     prerendering_url);
  prerender_helper()->WaitForPrerenderLoadCompletion(
      *new_tab_prerender_web_contents, prerendering_url);

  ASSERT_NE(new_tab_prerender_web_contents, web_contents_impl());
  ExpectWebContentsIsForNewTabPrerendering(*new_tab_prerender_web_contents);

  // Open a new window with "_blank" and `noopener`. This should activate
  // the prerendered page.
  test::PrerenderHostObserver new_tab_prerender_observer(
      *new_tab_prerender_web_contents, prerendering_url);
  test::PrerenderHostObserver prerender_observer(*web_contents(),
                                                 prerendering_url);

  {
    const std::string new_tab_opener_script =
        "window.open(\"title2.html\", \"_blank\", \"noopener\")";
    EXPECT_TRUE(ExecJs(web_contents(), new_tab_opener_script));
    new_tab_prerender_observer.WaitForActivation();
    EXPECT_EQ(new_tab_prerender_web_contents->GetLastCommittedURL(),
              prerendering_url);

    // Prerender activation in the new tab shouldn't cancel the prerender in
    // the initial WebContents.
    EXPECT_TRUE(HasHostForUrl(*web_contents(), prerendering_url));
    EXPECT_FALSE(
        HasHostForUrl(*new_tab_prerender_web_contents, prerendering_url));
  }

  // The prerender in the initial WebContents should be able to be activated.
  {
    ASSERT_TRUE(ExecJs(web_contents()->GetPrimaryMainFrame(),
                       JsReplace("location = $1", prerendering_url)));
    prerender_observer.WaitForActivation();
  }
}

// Tests that window.open() annotated with "_blank" and "noopener" can activate
// a prerender whose target_hint is "_blank".
IN_PROC_BROWSER_TEST_F(PrerenderTargetHintBrowserTest,
                       ActivateOnWindowOpen_NewTab) {
  TestActivateOnWindowOpen("noopener");
}

// Tests that window.open() annotated with "_blank" and "noopener,popup" can
// activate a prerender whose target_hint is "_blank".
IN_PROC_BROWSER_TEST_F(PrerenderTargetHintBrowserTest,
                       ActivateOnWindowOpen_PopUp) {
  TestActivateOnWindowOpen("noopener,popup");
}

// TODO(crbug.com/40234240): Add more test cases for prerender-in-new-tab:
// - Multiple prerendering requests with the same URL but different target hint.
// - Navigation in a new tab to the prerendering URL multiple times. Only the
//   first navigation should activate the prerendered page.

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, ResponseHeaders) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/set-header?X-Foo: bar");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Start prerendering `kPrerenderingUrl` and check if `X-Foo` header is
  // observed.
  NavigationHandleObserver observer1(web_contents(), kPrerenderingUrl);
  AddPrerender(kPrerenderingUrl);
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  EXPECT_TRUE(observer1.has_committed());
  EXPECT_EQ("bar", observer1.GetNormalizedResponseHeader("x-foo"));

  // Activate the page and check if `X-Foo` header is observed again.
  NavigationHandleObserver observer2(web_contents(), kPrerenderingUrl);
  NavigatePrimaryPage(kPrerenderingUrl);
  EXPECT_TRUE(observer2.has_committed());
  EXPECT_EQ("bar", observer2.GetNormalizedResponseHeader("x-foo"));
}

// Tests that cancelling a prerender-into-new-tab trigger by invoking
// CancelHosts on initiator WebContents's PrerenderHostRegistry will
// eventually destruct corresponding PrerenderNewTabHandle and its WebContents
// created for the new-tab trigger.
IN_PROC_BROWSER_TEST_F(PrerenderTargetHintBrowserTest,
                       NewTabPrerenderCancellationOnInitiatorPHR) {
  const GURL initial_url = GetUrl("/empty.html");
  const GURL prerendering_url = GetUrl("/empty.html?prerender");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Start prerendering.
  PrerenderHostId host_id = prerender_helper()->AddPrerender(
      prerendering_url, /*eagerness=*/std::nullopt, "_blank");
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  WebContentsDestroyedWatcher wc_destroyed_watcher(prerender_web_contents);
  test::PrerenderHostObserver host_observer(*prerender_web_contents, host_id);

  // Call CancelHost on initiator WebContents's PrerenderHostRegistry.
  web_contents_impl()->GetPrerenderHostRegistry()->CancelHost(
      host_id, PrerenderFinalStatus::kDestroyed);

  host_observer.WaitForDestroyed();
  // WebContents created for the new-tab trigger will be destroyed.
  wc_destroyed_watcher.Wait();
  EXPECT_FALSE(prerender_helper()->HasNewTabHandle(host_id));
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kDestroyed);
}

// Tests that cancelling a prerender-into-new-tab trigger by invoking
// CancelHosts on PrerenderHostRegistry of WebContents created by new-tab
// triggers will eventually destruct corresponding PrerenderNewTabHandle on
// initiator's PHR and that WebContents created for the new-tab trigger.
IN_PROC_BROWSER_TEST_F(PrerenderTargetHintBrowserTest,
                       NewTabPrerenderCancellationOnNewTabPHR) {
  const GURL initial_url = GetUrl("/empty.html");
  const GURL prerendering_url = GetUrl("/empty.html?prerender");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Start prerendering.
  PrerenderHostId host_id = prerender_helper()->AddPrerender(
      prerendering_url, /*eagerness=*/std::nullopt, "_blank");
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  WebContentsDestroyedWatcher wc_destroyed_watcher(prerender_web_contents);
  test::PrerenderHostObserver host_observer(*prerender_web_contents, host_id);

  // Call CancelHost on WebContents's PrerenderHostRegistry that was created for
  // the new-tab trigger.
  static_cast<WebContentsImpl*>(prerender_web_contents)
      ->GetPrerenderHostRegistry()
      ->CancelHost(host_id, PrerenderFinalStatus::kDestroyed);

  host_observer.WaitForDestroyed();
  // WebContents created for the new-tab trigger will be destroyed.
  wc_destroyed_watcher.Wait();
  EXPECT_FALSE(prerender_helper()->HasNewTabHandle(host_id));
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kDestroyed);
}

// Tests that closing initiator's WebContents will eventually destruct
// corresponding PrerenderNewTabHandle WebContents created for the new-tab
// trigger without crashing.
IN_PROC_BROWSER_TEST_F(PrerenderTargetHintBrowserTest,
                       NewTabPrerenderCancellationByInitiatorWCClosure) {
  const GURL initial_url = GetUrl("/empty.html");
  const GURL prerendering_url = GetUrl("/empty.html?prerender");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Start prerendering.
  PrerenderHostId host_id = prerender_helper()->AddPrerender(
      prerendering_url, /*eagerness=*/std::nullopt, "_blank");
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  WebContentsDestroyedWatcher wc_destroyed_watcher(prerender_web_contents);
  test::PrerenderHostObserver host_observer(*prerender_web_contents, host_id);

  shell()->Close();

  host_observer.WaitForDestroyed();
  // WebContents created for the new-tab trigger will be destroyed.
  wc_destroyed_watcher.Wait();
  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::kTabClosedWithoutUserGesture);
}

// Tests that trigger cancellation via BrowsingDataRemover (e.g.,
// Clear-Site-Data) is handled safely without causing Use-After-Free due to
// synchronous destruction of the WebContentsImpl during iteration.
IN_PROC_BROWSER_TEST_F(PrerenderTargetHintBrowserTest,
                       NewTabPrerenderCancellationByBrowsingDataRemover) {
  const GURL initial_url = GetUrl("/empty.html");
  const GURL prerendering_url = GetUrl("/empty.html?prerender");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Start prerendering.
  PrerenderHostId host_id = prerender_helper()->AddPrerender(
      prerendering_url, /*eagerness=*/std::nullopt, "_blank");
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  WebContentsDestroyedWatcher wc_destroyed_watcher(prerender_web_contents);

  // Trigger browsing data removal which will call CancelHostsByOriginFilter.
  BrowsingDataRemover* remover =
      web_contents_impl()->GetBrowserContext()->GetBrowsingDataRemover();
  BrowsingDataRemoverCompletionObserver completion_observer(remover);
  remover->RemoveAndReply(base::Time::Min(), base::Time::Max(),
                          BrowsingDataRemover::DATA_TYPE_CACHE,
                          BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
                          &completion_observer);
  completion_observer.BlockUntilCompletion();

  // WebContents created for the new-tab trigger will be destroyed safely.
  wc_destroyed_watcher.Wait();
  EXPECT_FALSE(prerender_helper()->HasNewTabHandle(host_id));
}

// Tests that prerendering is cancelled if a network request for the
// navigation results in an empty response with 404 status.
IN_PROC_BROWSER_TEST_P(PrerenderTargetAgnosticBrowserTest,
                       PrerenderCancelledOnEmptyBody404) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  // Specify a URL for which we don't have a corresponding file in the data dir.
  const GURL kPrerenderingUrl = GetUrl("/404");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering `kPrerenderingUrl`.
  test::PrerenderHostCreationWaiter host_creation_waiter;
  prerender_helper()->AddPrerendersAsync(
      {kPrerenderingUrl}, /*eagerness=*/std::nullopt, GetTargetHint());
  PrerenderHostId host_id = host_creation_waiter.Wait();
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  test::PrerenderHostObserver host_observer(*prerender_web_contents, host_id);
  host_observer.WaitForDestroyed();

  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  if (IsPrefetchAheadOfPrerenderTriggered()) {
    ExpectFinalStatusForSpeculationRule(
        PrerenderFinalStatus::kPrerenderFailedDuringPrefetch);
    histogram_tester().ExpectUniqueSample(
        "Prerender.Experimental.PrefetchAheadOfPrerenderFailed."
        "PrefetchStatus.SpeculationRule",
        PrefetchStatus::kPrefetchFailedNon2XX, 1);
  } else {
    ExpectFinalStatusForSpeculationRule(
        PrerenderFinalStatus::kNavigationBadHttpStatus);
  }
}

// Tests that prerendering is cancelled if a network request for the
// navigation results in an non-empty response with 404 status.
IN_PROC_BROWSER_TEST_P(PrerenderTargetAgnosticBrowserTest,
                       PrerenderCancelledOnNonEmptyBody404) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/page404.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Add prerendering to the 404 error page, then check that it got cancelled.
  test::PrerenderHostCreationWaiter host_creation_waiter;
  prerender_helper()->AddPrerendersAsync(
      {kPrerenderingUrl}, /*eagerness=*/std::nullopt, GetTargetHint());
  PrerenderHostId host_id = host_creation_waiter.Wait();
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  test::PrerenderHostObserver host_observer(*prerender_web_contents, host_id);
  host_observer.WaitForDestroyed();

  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  if (IsPrefetchAheadOfPrerenderTriggered()) {
    ExpectFinalStatusForSpeculationRule(
        PrerenderFinalStatus::kPrerenderFailedDuringPrefetch);
    histogram_tester().ExpectUniqueSample(
        "Prerender.Experimental.PrefetchAheadOfPrerenderFailed."
        "PrefetchStatus.SpeculationRule",
        PrefetchStatus::kPrefetchFailedNon2XX, 1);
  } else {
    ExpectFinalStatusForSpeculationRule(
        PrerenderFinalStatus::kNavigationBadHttpStatus);
  }
}

// Tests that prerendering is cancelled if a network request for the
// navigation results in an non-empty response with 500 status.
IN_PROC_BROWSER_TEST_P(PrerenderTargetAgnosticBrowserTest,
                       PrerenderCancelledOn500Page) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/page500.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Add prerendering to the 500 error page, then check that it got cancelled.
  test::PrerenderHostCreationWaiter host_creation_waiter;
  prerender_helper()->AddPrerendersAsync(
      {kPrerenderingUrl}, /*eagerness=*/std::nullopt, GetTargetHint());
  PrerenderHostId host_id = host_creation_waiter.Wait();
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  test::PrerenderHostObserver host_observer(*prerender_web_contents, host_id);
  host_observer.WaitForDestroyed();

  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  if (IsPrefetchAheadOfPrerenderTriggered()) {
    ExpectFinalStatusForSpeculationRule(
        PrerenderFinalStatus::kPrerenderFailedDuringPrefetch);
    histogram_tester().ExpectUniqueSample(
        "Prerender.Experimental.PrefetchAheadOfPrerenderFailed."
        "PrefetchStatus.SpeculationRule",
        PrefetchStatus::kPrefetchFailedNon2XX, 1);
  } else {
    ExpectFinalStatusForSpeculationRule(
        PrerenderFinalStatus::kNavigationBadHttpStatus);
  }
}

IN_PROC_BROWSER_TEST_P(PrerenderTargetAgnosticBrowserTest,
                       PrerenderCancelledOn204Page) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/title1.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering `kPrerenderingUrl` that returns 204 response code.
  const GURL kPrerenderingUrl = GetUrl("/echo?status=204");
  test::PrerenderHostCreationWaiter host_creation_waiter;
  prerender_helper()->AddPrerendersAsync(
      {kPrerenderingUrl}, /*eagerness=*/std::nullopt, GetTargetHint());
  PrerenderHostId host_id = host_creation_waiter.Wait();
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  test::PrerenderHostObserver host_observer(*prerender_web_contents, host_id);

  // The prerender should be destroyed.
  host_observer.WaitForDestroyed();

  // Cancellation must have occurred due to bad http status code.
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::kNavigationBadHttpStatus);
}

IN_PROC_BROWSER_TEST_P(PrerenderTargetAgnosticBrowserTest,
                       PrerenderCancelledOn205Page) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/title1.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering `kPrerenderingUrl` that returns 205 response code.
  const GURL kPrerenderingUrl = GetUrl("/echo?status=205");
  test::PrerenderHostCreationWaiter host_creation_waiter;
  prerender_helper()->AddPrerendersAsync(
      {kPrerenderingUrl}, /*eagerness=*/std::nullopt, GetTargetHint());
  PrerenderHostId host_id = host_creation_waiter.Wait();
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  test::PrerenderHostObserver host_observer(*prerender_web_contents, host_id);

  // The prerender should be destroyed.
  host_observer.WaitForDestroyed();

  // Cancellation must have occurred due to bad http status code.
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::kNavigationBadHttpStatus);
}

namespace {

// Tests that an iframe navigation whose response has either 204 or 205 doesn't
// cancel prerendering.
// This is also a regression test for https://crbug.com/1362818.
void PrerenderBrowserTest::TestPrerenderAllowedOnIframeWithStatusCode(
    OriginType origin_type,
    std::string status_code) {
  // This test is designed for 204 and 205 status codes.
  ASSERT_TRUE(status_code == "204" || status_code == "205");

  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/title1.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering `kPrerenderingUrl`.
  const GURL kPrerenderingUrl = GetUrl("/title1.html");
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  test::PrerenderHostObserver host_observer(*web_contents_impl(), host_id);

  // Construct an iframe URL whose response has 204/205.
  GURL iframe_url;
  std::string file_path = "/echo?status=" + status_code;
  switch (origin_type) {
    case OriginType::kSameOrigin:
      iframe_url = GetUrl(file_path);
      break;
    case OriginType::kSameSiteCrossOrigin:
      iframe_url = GetSameSiteCrossOriginUrl(file_path);
      break;
    case OriginType::kCrossSite:
      iframe_url = GetCrossSiteUrl(file_path);
      break;
  }

  // Fetch the iframe.
  TestNavigationManager iframe_navigation_manager(web_contents(), iframe_url);
  RenderFrameHost* prerender_rfh = GetPrerenderedMainFrameHost(host_id);
  std::ignore = ExecJs(prerender_rfh, JsReplace(R"(
                const i = document.createElement('iframe');
                i.src = $1;
                document.body.appendChild(i);
             )",
                                                iframe_url.spec()));
  switch (origin_type) {
    case OriginType::kSameOrigin:
      // Wait for the completion of the iframe navigation.
      ASSERT_TRUE(iframe_navigation_manager.WaitForNavigationFinished());
      break;
    case OriginType::kSameSiteCrossOrigin:
    case OriginType::kCrossSite:
      // Cross-origin iframe navigation is deferred in WillStartRequest() before
      // checking the status code.
      ASSERT_TRUE(
          iframe_navigation_manager.WaitForFirstYieldAfterDidStartNavigation());
      auto* request = static_cast<NavigationRequest*>(
          iframe_navigation_manager.GetNavigationHandle());
      EXPECT_TRUE(request->IsDeferredForTesting());
      ASSERT_EQ(1u, request->GetNavigationThrottleRegistryForTesting()
                        ->GetDeferringThrottles()
                        .size());
      EXPECT_STREQ("PrerenderSubframeNavigationThrottle",
                   (*request->GetNavigationThrottleRegistryForTesting()
                         ->GetDeferringThrottles()
                         .begin())
                       ->GetNameForLogging());
      break;
  }

  // Fetching an iframe whose response has 204/205 status code shouldn't cancel
  // prerendering unlike the mainframe whose response has 204/205 status code.
  // https://wicg.github.io/nav-speculation/prerendering.html#no-bad-navs
  EXPECT_EQ(GetHostForUrl(kPrerenderingUrl), host_id);
}

}  // namespace

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       PrerenderAllowedOnIframe_204_SameOrigin) {
  TestPrerenderAllowedOnIframeWithStatusCode(OriginType::kSameOrigin, "204");
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       PrerenderAllowedOnIframe_204_SameSiteCrossOrigin) {
  TestPrerenderAllowedOnIframeWithStatusCode(OriginType::kSameSiteCrossOrigin,
                                             "204");
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       PrerenderAllowedOnIframe_204_CrossSite) {
  TestPrerenderAllowedOnIframeWithStatusCode(OriginType::kCrossSite, "204");
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       PrerenderAllowedOnIframe_205_SameOrigin) {
  TestPrerenderAllowedOnIframeWithStatusCode(OriginType::kSameOrigin, "205");
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       PrerenderAllowedOnIframe_205_SameSiteCrossOrigin) {
  TestPrerenderAllowedOnIframeWithStatusCode(OriginType::kSameSiteCrossOrigin,
                                             "205");
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       PrerenderAllowedOnIframe_205_CrossSite) {
  TestPrerenderAllowedOnIframeWithStatusCode(OriginType::kCrossSite, "205");
}

void PrerenderBrowserTest::TestCancelOnAuthRequested(TriggerType trigger_type) {
  const bool is_prefetch_ahead_of_prerender_triggered =
      trigger_type == TriggerType::kSpeculationRules &&
      IsPrerender2FallbackPrefetchSpecRulesEnabled();

  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/title1.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering `kPrerenderingUrl`.
  const GURL kPrerenderingUrl = GetUrl("/auth-basic");
  test::PrerenderHostObserver host_observer(*web_contents_impl(),
                                            kPrerenderingUrl);
  auto handle = TriggerPrerender(kPrerenderingUrl, trigger_type);

  // The prerender should be destroyed.
  host_observer.WaitForDestroyed();
  EXPECT_TRUE(GetHostForUrl(kPrerenderingUrl).is_null());

  // Navigate primary page to flush the metrics.
  const GURL kNavigatedURL = GetUrl("/title2.html");
  ASSERT_TRUE(NavigateToURL(shell(), kNavigatedURL));

  handle.reset();
  // Cross-check that Preloading.Attempt logs the correct failure reason.
  if (is_prefetch_ahead_of_prerender_triggered) {
    ExpectPreloadingAttemptUkm(
        {attempt_ukm_entry_builder().BuildEntry(
             PrimaryPageSourceId(), PreloadingType::kPrefetch,
             PreloadingEligibility::kEligible,
             PreloadingHoldbackStatus::kAllowed,
             PreloadingTriggeringOutcome::kFailure,
             ToPreloadingFailureReason(PrefetchStatus::kPrefetchFailedNon2XX),
             /*accurate=*/true,
             /*ready_time=*/std::nullopt,
             blink::mojom::SpeculationEagerness::kImmediate),
         attempt_ukm_entry_builder().BuildEntry(
             PrimaryPageSourceId(), PreloadingType::kPrerender,
             PreloadingEligibility::kEligible,
             PreloadingHoldbackStatus::kAllowed,
             PreloadingTriggeringOutcome::kFailure,
             ToPreloadingFailureReason(
                 PrerenderFinalStatus::kPrerenderFailedDuringPrefetch),
             /*accurate=*/false,
             /*ready_time=*/std::nullopt,
             blink::mojom::SpeculationEagerness::kImmediate)});
  } else if (trigger_type ==
             TriggerType::kEmbedderWithoutPrefetchAheadOfPrerender) {
    auto attempt_ukm_entry_builder_embedder =
        std::make_unique<test::PreloadingAttemptUkmEntryBuilder>(
            kPreloadingPredictorEmbedderForTest);
    ExpectPreloadingAttemptUkm({attempt_ukm_entry_builder_embedder->BuildEntry(
        PrimaryPageSourceId(), PreloadingType::kPrerender,
        PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed,
        PreloadingTriggeringOutcome::kFailure,
        ToPreloadingFailureReason(PrerenderFinalStatus::kLoginAuthRequested),
        /*accurate=*/false,
        /*ready_time=*/std::nullopt,
        /*eagerness=*/std::nullopt)});
  } else {
    ExpectPreloadingAttemptUkm({attempt_ukm_entry_builder().BuildEntry(
        PrimaryPageSourceId(), PreloadingType::kPrerender,
        PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed,
        PreloadingTriggeringOutcome::kFailure,
        ToPreloadingFailureReason(PrerenderFinalStatus::kLoginAuthRequested),
        /*accurate=*/false,
        /*ready_time=*/std::nullopt,
        blink::mojom::SpeculationEagerness::kImmediate)});
  }

  // Cancellation must have occurred due to authentication request.
  switch (trigger_type) {
    case TriggerType::kSpeculationRules:
      if (is_prefetch_ahead_of_prerender_triggered) {
        histogram_tester().ExpectUniqueSample(
            "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
            PrerenderFinalStatus::kPrerenderFailedDuringPrefetch, 1);
        histogram_tester().ExpectUniqueSample(
            "Prerender.Experimental.PrefetchAheadOfPrerenderFailed."
            "PrefetchStatus.SpeculationRule",
            PrefetchStatus::kPrefetchFailedNon2XX, 1);
      } else {
        histogram_tester().ExpectUniqueSample(
            "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
            PrerenderFinalStatus::kLoginAuthRequested, 1);
      }
      break;
    case TriggerType::kEmbedderWithoutPrefetchAheadOfPrerender:
      if (is_prefetch_ahead_of_prerender_triggered) {
        histogram_tester().ExpectUniqueSample(
            "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_"
            "EmbedderSuffixForTest",
            PrerenderFinalStatus::kPrerenderFailedDuringPrefetch, 1);
        histogram_tester().ExpectUniqueSample(
            "Prerender.Experimental.PrefetchAheadOfPrerenderFailed."
            "PrefetchStatus.Embedder_EmbedderSuffixForTest",
            PrefetchStatus::kPrefetchFailedNon2XX, 1);
      } else {
        histogram_tester().ExpectUniqueSample(
            "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_"
            "EmbedderSuffixForTest",
            PrerenderFinalStatus::kLoginAuthRequested, 1);
      }
      break;
  }
}

IN_PROC_BROWSER_TEST_P(PrerenderBrowserTestFallbackEnabledDisabled,
                       CancelOnAuthRequested) {
  TestCancelOnAuthRequested(TriggerType::kSpeculationRules);
}

IN_PROC_BROWSER_TEST_P(
    PrerenderBrowserTestFallbackEnabledDisabled,
    CancelOnAuthRequested_EmbedderWithoutPrefetchAheadOfPrerender) {
  TestCancelOnAuthRequested(
      TriggerType::kEmbedderWithoutPrefetchAheadOfPrerender);
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, CancelOnAuthRequestedSubframe) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/title1.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering `kPrerenderingUrl`.
  const GURL kPrerenderingUrl = GetUrl("/title1.html");
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  test::PrerenderHostObserver host_observer(*web_contents_impl(), host_id);

  // Fetch a subframe that requires authentication.
  const GURL kAuthIFrameUrl = GetUrl("/auth-basic");
  RenderFrameHost* prerender_rfh = GetPrerenderedMainFrameHost(host_id);
  std::ignore =
      ExecJs(prerender_rfh,
             "const i = document.createElement('iframe'); i.src = '" +
                 kAuthIFrameUrl.spec() + "'; document.body.appendChild(i);");

  // The prerender should be destroyed.
  host_observer.WaitForDestroyed();
  EXPECT_TRUE(GetHostForUrl(kPrerenderingUrl).is_null());

  // Cancellation must have occurred due to authentication request.
  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::kLoginAuthRequested);
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, CancelOnAuthRequestedSubResource) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering `kPrerenderingUrl`.
  const GURL kPrerenderingUrl = GetUrl("/title1.html");
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  test::PrerenderHostObserver host_observer(*web_contents_impl(), host_id);

  ASSERT_TRUE(GetHostForUrl(kPrerenderingUrl));

  // Fetch a subresrouce.
  std::string fetch_subresource_script = R"(
        const imgElement = document.createElement('img');
        imgElement.src = '/auth-basic/favicon.gif';
        document.body.appendChild(imgElement);
  )";
  std::ignore =
      ExecJs(GetPrerenderedMainFrameHost(host_id), fetch_subresource_script);

  // The prerender should be destroyed.
  host_observer.WaitForDestroyed();
  EXPECT_TRUE(GetHostForUrl(kPrerenderingUrl).is_null());

  // Cancellation must have occurred due to authentication request.
  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::kLoginAuthRequested);
}

// Prefetch requests should be canceled upon auth requested.
// The following tests are for the cases where:
// - No ServiceWorker intercepts the prefetch request.
// - A ServiceWorker intercepts the request but falls back to the network.
// - A ServiceWorker intercepts the request and fetches it as ServiceWorker
//   subresource. This is the regression tests for https://crbug.com/445521064.
// These tests (and `PrefetchCertificateValidation_*` tests) are placed here to
// reuse the common test helpers for testing cert/auth errors.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       PrefetchCancelOnAuthRequested_NoServiceWorker) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/title1.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start a prefetch and wait for its completion.
  test::TestPrefetchWatcher test_prefetch_watcher;
  const GURL prefetch_url = GetUrl("/auth-basic");
  AddPrefetchAsync(prefetch_url);
  test_prefetch_watcher.WaitUntilPrefetchResponseCompleted(
      static_cast<RenderFrameHostImpl*>(
          shell()->web_contents()->GetPrimaryMainFrame())
          ->GetDocumentToken(),
      prefetch_url);

  // Check that the prefetch has failed and isn't used for navigation.
  histogram_tester().ExpectUniqueSample("Preloading.Prefetch.PrefetchStatus",
                                        PrefetchStatus::kPrefetchFailedNon2XX,
                                        1);
  ASSERT_TRUE(NavigateToURL(shell(), prefetch_url));
  EXPECT_FALSE(test_prefetch_watcher.PrefetchUsedInLastNavigation());
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       PrefetchCancelOnAuthRequested_ServiceWorkerFallback) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/title1.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  RegisterServiceWorker("/fetch_event_passthrough.js");

  // Start a prefetch and wait for its completion.
  test::TestPrefetchWatcher test_prefetch_watcher;
  const GURL prefetch_url = GetUrl("/auth-basic");
  AddPrefetchAsync(prefetch_url);
  test_prefetch_watcher.WaitUntilPrefetchResponseCompleted(
      static_cast<RenderFrameHostImpl*>(
          shell()->web_contents()->GetPrimaryMainFrame())
          ->GetDocumentToken(),
      prefetch_url);

  // Check that the prefetch has failed and isn't used for navigation.
  histogram_tester().ExpectUniqueSample("Preloading.Prefetch.PrefetchStatus",
                                        PrefetchStatus::kPrefetchFailedNon2XX,
                                        1);
  ASSERT_TRUE(NavigateToURL(shell(), prefetch_url));
  EXPECT_FALSE(test_prefetch_watcher.PrefetchUsedInLastNavigation());
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       PrefetchCancelOnAuthRequested_ServiceWorkerSubresource) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/title1.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  RegisterServiceWorker("/fetch_event_respond_with_fetch.js");

  // Start a prefetch and wait for its completion.
  test::TestPrefetchWatcher test_prefetch_watcher;
  const GURL prefetch_url = GetUrl("/auth-basic");
  AddPrefetchAsync(prefetch_url);
  test_prefetch_watcher.WaitUntilPrefetchResponseCompleted(
      static_cast<RenderFrameHostImpl*>(
          shell()->web_contents()->GetPrimaryMainFrame())
          ->GetDocumentToken(),
      prefetch_url);

  // Check that the prefetch has failed and isn't used for navigation.
  histogram_tester().ExpectUniqueSample("Preloading.Prefetch.PrefetchStatus",
                                        PrefetchStatus::kPrefetchFailedNon2XX,
                                        1);
  ASSERT_TRUE(NavigateToURL(shell(), prefetch_url));
  EXPECT_FALSE(test_prefetch_watcher.PrefetchUsedInLastNavigation());
}

IN_PROC_BROWSER_TEST_F(PrerenderTargetHintBrowserTest,
                       CancelOnSpeculationCandidateRemoved) {
  GURL url_ping(GetUrl(kPagehideEventPath));

  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/title1.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering.
  const GURL kPrerenderingUrl = GetUrl("/title1.html?prerender");
  test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());
  AddPrerenderAsync(kPrerenderingUrl);
  registry_observer.WaitForTrigger(kPrerenderingUrl);
  PrerenderHostId host_id = GetHostForUrl(kPrerenderingUrl);
  ASSERT_TRUE(host_id);
  WaitForPrerenderLoadCompletion(kPrerenderingUrl);

  RenderFrameHost* prerender_host = GetPrerenderedMainFrameHost(host_id);
  // Call fetchLater() to record that the pagehide event is fired.
  std::string js = R"(
        addEventListener('pagehide', () => {
          fetchLater($1);
        });)";
  EXPECT_TRUE(ExecJs(prerender_host, JsReplace(js, url_ping)));
  EXPECT_FALSE(PageHideReceived());

  // Remove the rules and check that the prerender is cancelled with an
  // appropriate final status.
  test::PrerenderHostObserver host_observer(*web_contents_impl(), host_id);
  ASSERT_TRUE(ExecJs(
      web_contents_impl()->GetPrimaryMainFrame(),
      "document.querySelector('script[type=speculationrules]').remove()"));
  host_observer.WaitForDestroyed();
  EXPECT_TRUE(GetHostForUrl(kPrerenderingUrl).is_null());
  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::kSpeculationRuleRemoved);

  // Intended prerender cancellation such as speculation rules removal is
  // expected to dispatch the pagehide event unlike other unexpected prerender
  // failures.
  WaitForPageHide();
  EXPECT_TRUE(PageHideReceived());
}

// Tests removing speculation rules whose target_hint is "_blank" (i.e.,
// prerender into new tab).
IN_PROC_BROWSER_TEST_F(
    PrerenderTargetHintBrowserTest,
    CancelOnSpeculationCandidateRemoved_WithTargetHintBlank) {
  GURL url_ping(GetUrl(kPagehideEventPath));

  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/title1.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering.
  const GURL kPrerenderingUrl = GetUrl("/title1.html?prerender");
  PrerenderHostId host_id = prerender_helper()->AddPrerender(
      kPrerenderingUrl, /*eagerness=*/std::nullopt, "_blank");
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  ASSERT_NE(prerender_web_contents, web_contents_impl());
  ExpectWebContentsIsForNewTabPrerendering(*prerender_web_contents);
  // Call fetchLater() to record that the pagehide event is fired.
  std::string js = R"(
        addEventListener('pagehide', () => {
          fetchLater($1);
        });)";

  RenderFrameHost* prerender_host =
      prerender_helper()->GetPrerenderedMainFrameHost(*prerender_web_contents,
                                                      host_id);

  EXPECT_TRUE(ExecJs(prerender_host, JsReplace(js, url_ping)));
  EXPECT_FALSE(PageHideReceived());

  base::WeakPtr<WebContents> prerender_web_contents_weak =
      prerender_web_contents->GetWeakPtr();

  // Remove the rules and check that the prerender is cancelled with an
  // appropriate final status.
  test::PrerenderHostObserver host_observer(*prerender_web_contents, host_id);
  ASSERT_TRUE(ExecJs(
      web_contents_impl()->GetPrimaryMainFrame(),
      "document.querySelector('script[type=speculationrules]').remove()"));
  host_observer.WaitForDestroyed();
  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::kSpeculationRuleRemoved);

  // Intended prerender cancellation such as speculation rules removal is
  // expected to dispatch the pagehide event unlike other unexpected prerender
  // failures.
  WaitForPageHide();
  EXPECT_TRUE(PageHideReceived());

  // During the cancellation, the prerender WebContents should be destroyed.
  EXPECT_FALSE(prerender_web_contents_weak);

  ukm::SourceId triggering_primary_page_source_id =
      web_contents_impl()->GetPrimaryMainFrame()->GetPageUkmSourceId();

  // The prerender WebContents doesn't have the primary page that can record UKM
  // on destruction. Instead, it asks the primary page hosted on the primary
  // WebContents to record UKM.
  ExpectPreloadingAttemptPreviousPrimaryPageUkm(
      attempt_previous_ukm_entry_builder().BuildEntry(
          triggering_primary_page_source_id, PreloadingType::kPrerender,
          PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed,
          PreloadingTriggeringOutcome::kReady,
          PreloadingFailureReason::kUnspecified,
          /*accurate=*/false,
          /*ready_time=*/kMockElapsedTime,
          blink::mojom::SpeculationEagerness::kImmediate));
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       DontCancelOnSpeculationUpdateIfStillEligible) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/title1.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering.
  const GURL kPrerenderingUrl = GetUrl("/title2.html");
  test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());
  ASSERT_TRUE(ExecJs(web_contents_impl()->GetPrimaryMainFrame(),
                     JsReplace(
                         R"(
                         let sc = document.createElement('script');
                         sc.type = 'speculationrules';
                         sc.textContent = JSON.stringify({
                           prerender: [
                             {source: "list", urls: [$1]}
                           ]
                         });
                         document.head.appendChild(sc);
                         )",
                         kPrerenderingUrl)));
  registry_observer.WaitForTrigger(kPrerenderingUrl);
  PrerenderHostId host_id = GetHostForUrl(kPrerenderingUrl);
  ASSERT_TRUE(host_id);

  ASSERT_TRUE(ExecJs(web_contents_impl()->GetPrimaryMainFrame(),
                     JsReplace(
                         R"(
                         document.querySelector('script[type=speculationrules]')
                             .remove();
                         let sc = document.createElement('script');
                         sc.type = 'speculationrules';
                         sc.textContent = JSON.stringify({
                           prerender: [
                             {source: "list", urls: ["/empty.html", $1]}
                           ]
                         });
                         document.head.appendChild(sc);
                         )",
                         kPrerenderingUrl)));

  // Replace the rules. Even though the original rules are gone, the new ones
  // still permit the prerender so it continues.
  {
    base::RunLoop run_loop;
    base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
        FROM_HERE, run_loop.QuitClosure(), TestTimeouts::action_timeout());
    run_loop.Run();
    ASSERT_TRUE(GetHostForUrl(kPrerenderingUrl));
  }

  // Remove the rules and check that the prerender is cancelled.
  test::PrerenderHostObserver host_observer(*web_contents_impl(), host_id);
  ASSERT_TRUE(ExecJs(
      web_contents_impl()->GetPrimaryMainFrame(),
      "document.querySelector('script[type=speculationrules]').remove()"));
  host_observer.WaitForDestroyed();
  EXPECT_TRUE(GetHostForUrl(kPrerenderingUrl).is_null());
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       CanStartSecondPrerenderWhenCancellingFirst) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/title1.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering.
  const GURL kPrerenderingUrl = GetUrl("/title2.html");
  test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());
  ASSERT_TRUE(ExecJs(web_contents_impl()->GetPrimaryMainFrame(),
                     JsReplace(
                         R"(
                         let sc = document.createElement('script');
                         sc.type = 'speculationrules';
                         sc.textContent = JSON.stringify({
                           prerender: [
                             {source: "list", urls: [$1]}
                           ]
                         });
                         document.head.appendChild(sc);
                         )",
                         kPrerenderingUrl)));
  registry_observer.WaitForTrigger(kPrerenderingUrl);
  PrerenderHostId host_id = GetHostForUrl(kPrerenderingUrl);
  ASSERT_TRUE(host_id);

  // Starting a different prerender still works.
  // (For now, this works unconditionally. In the future this might depend on
  // some other conditions.)
  const GURL kPrerenderingUrl2 = GetUrl("/title3.html");
  test::PrerenderHostObserver host_observer(*web_contents_impl(), host_id);
  ASSERT_TRUE(ExecJs(web_contents_impl()->GetPrimaryMainFrame(),
                     JsReplace(
                         R"(
                         document.querySelector('script[type=speculationrules]')
                             .remove();
                         let sc = document.createElement('script');
                         sc.type = 'speculationrules';
                         sc.textContent = JSON.stringify({
                           prerender: [
                             {source: "list", urls: [$1]}
                           ]
                         });
                         document.head.appendChild(sc);
                         )",
                         kPrerenderingUrl2)));

  // The original prerender should be cancelled.
  host_observer.WaitForDestroyed();
  EXPECT_TRUE(GetHostForUrl(kPrerenderingUrl).is_null());

  // And the new one should be discovered.
  registry_observer.WaitForTrigger(kPrerenderingUrl2);
  PrerenderHostId second_host_id = GetHostForUrl(kPrerenderingUrl2);
  EXPECT_TRUE(second_host_id);
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, RetriggerPrerenderAfterRemoval) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/title1.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering.
  const GURL kPrerenderingUrl = GetUrl("/title2.html");
  {
    test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());
    ASSERT_TRUE(ExecJs(web_contents_impl()->GetPrimaryMainFrame(),
                       JsReplace(
                           R"(
                          let sc = document.createElement('script');
                          sc.type = 'speculationrules';
                          sc.textContent = JSON.stringify({
                            prerender: [
                              {source: "list", urls: [$1]}
                            ]
                          });
                          document.head.appendChild(sc);
                          )",
                           kPrerenderingUrl)));
    registry_observer.WaitForTrigger(kPrerenderingUrl);
    PrerenderHostId host_id = GetHostForUrl(kPrerenderingUrl);
    ASSERT_TRUE(host_id);
    test::PrerenderHostObserver host_observer(*web_contents_impl(), host_id);

    // Remove the rules and check that the prerender is cancelled with an
    // appropriate final status.
    ASSERT_TRUE(ExecJs(
        web_contents_impl()->GetPrimaryMainFrame(),
        "document.querySelector('script[type=speculationrules]').remove()"));
    host_observer.WaitForDestroyed();
    EXPECT_TRUE(GetHostForUrl(kPrerenderingUrl).is_null());
  }
  {
    AddPrerender(kPrerenderingUrl);
    PrerenderHostId host_id = GetHostForUrl(kPrerenderingUrl);
    EXPECT_TRUE(host_id);
  }
}

// Tests that prerendering triggered by prerendered pages is deferred until
// activation.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderChain) {
  // kInitialUrl prerenders kPrerenderChain1, then kPrerenderChain1 prerenders
  // kPrerenderChain2.
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderChain1 =
      GetUrl("/prerender/page_with_trigger_function.html?1");
  const GURL kPrerenderChain2 =
      GetUrl("/prerender/page_with_trigger_function.html?2");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  PrerenderHostId host_id = AddPrerender(kPrerenderChain1);

  EXPECT_EQ(GetRequestCount(kPrerenderChain1), 1);
  EXPECT_TRUE(host_id);
  RenderFrameHost* prerender_host = GetPrerenderedMainFrameHost(host_id);
  EXPECT_TRUE(AddTestUtilJS(prerender_host));

  // Add a prerender trigger to the prerendering page.
  EXPECT_TRUE(ExecJs(prerender_host,
                     JsReplace("add_speculation_rules($1)", kPrerenderChain2)));

  // Speculation rules is processed by the idle task runner in Blink. To ensure
  // the speculation candidates has been sent by renderer processes, we should
  // wait until this runner finishes all tasks.
  EXPECT_TRUE(ExecJs(prerender_host, R"(
    const idlePromise = new Promise(resolve => requestIdleCallback(resolve));
    idlePromise;
  )"));

  // Start a navigation request that should not be deferred, and wait it to
  // reach the server. If the prerender request for kPrerenderChain2 is not
  // deferred, the navigation request for kPrerenderChain2 will reach the server
  // earlier than the non-deferred one, so we can wait until the latest request
  // reaches the sever to prove that the prerender request for kPrerenderChain2
  // is deferred.
  EXPECT_TRUE(ExecJs(prerender_host, "add_iframe_async('/title1.html')",
                     EvalJsOptions::EXECUTE_SCRIPT_NO_RESOLVE_PROMISES));
  WaitForRequest(GetUrl("/title1.html"), 1);

  // The prerender requests were deferred by Mojo capability control, so
  // prerendering pages should not trigger prerendering.
  EXPECT_EQ(GetRequestCount(kPrerenderChain2), 0);
  EXPECT_FALSE(HasHostForUrl(kPrerenderChain2));

  // Activate the prerendering page to grant the deferred prerender requests.
  NavigatePrimaryPage(kPrerenderChain1);
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderChain1);

  // The prerendered page was activated. The prerender requests should be
  // processed.
  WaitForPrerenderLoadCompletion(kPrerenderChain2);
  EXPECT_EQ(GetRequestCount(kPrerenderChain2), 1);
  EXPECT_TRUE(HasHostForUrl(kPrerenderChain2));
}

// Tests that sub-frames cannot trigger prerendering.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, IgnoreSubFrameInitiatedPrerender) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kSubFrameUrl =
      GetUrl("/prerender/page_with_trigger_function.html");
  const GURL kPrerenderingUrl = GetUrl("/title.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  RenderFrameHostImpl* main_frame_host = current_frame_host();
  EXPECT_TRUE(AddTestUtilJS(main_frame_host));
  EXPECT_EQ("LOADED",
            EvalJs(web_contents(), JsReplace("add_iframe($1)", kSubFrameUrl)));
  RenderFrameHost* child_frame_host = ChildFrameAt(main_frame_host, 0);
  ASSERT_NE(child_frame_host, nullptr);
  ASSERT_EQ(child_frame_host->GetLastCommittedURL(), kSubFrameUrl);

  // Add a prerender trigger to the subframe.
  EXPECT_TRUE(ExecJs(child_frame_host,
                     JsReplace("add_speculation_rules($1)", kPrerenderingUrl)));

  // Speculation rules is processed by the idle task runner in Blink. To ensure
  // the speculation candidates has been sent by renderer processes, we should
  // wait until this runner finishes all tasks.
  EXPECT_TRUE(ExecJs(child_frame_host, R"(
    const idlePromise = new Promise(resolve => requestIdleCallback(resolve));
    idlePromise;
  )"));

  // Start a navigation request that should not be ignored, and wait it to
  // reach the server. If the prerender request is not ignored, the navigation
  // request for kPrerenderingUrl will reach the server earlier than the
  // non-ignored one, so we can wait until the latest request reaches the sever
  // to prove that the prerender request for kPrerenderingUrl is ignored.
  EXPECT_TRUE(ExecJs(main_frame_host, "add_iframe_async('/title1.html')",
                     EvalJsOptions::EXECUTE_SCRIPT_NO_RESOLVE_PROMISES));
  WaitForRequest(GetUrl("/title1.html"), 1);

  // The prerender requests were ignored by SpeculationHostImpl.
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 0);
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));
}

// Regression test for https://crbug.com/1194865.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, CloseOnPrerendering) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Start prerendering `kPrerenderingUrl`.
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 0);
  AddPrerender(kPrerenderingUrl);
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);

  // A prerender host for the URL should be registered.
  EXPECT_TRUE(HasHostForUrl(kPrerenderingUrl));

  // Should not crash.
  shell()->Close();

  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::kTabClosedWithoutUserGesture);
}

namespace {

class RedirectChainObserver : public WebContentsObserver {
 public:
  RedirectChainObserver(WebContents& web_contents, const GURL& url)
      : WebContentsObserver(&web_contents), url_(url) {}
  std::vector<GURL>& redirect_chain() { return redirect_chain_; }

 private:
  void DidFinishNavigation(NavigationHandle* handle) override {
    if (handle->GetURL() != url_) {
      return;
    }
    redirect_chain_ = handle->GetRedirectChain();
  }

  const GURL url_;
  std::vector<GURL> redirect_chain_;
};

}  // namespace

IN_PROC_BROWSER_TEST_P(PrerenderBrowserTestFallbackEnabledDisabled,
                       SameOriginRedirection) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering a URL that causes same-origin redirection.
  const GURL kRedirectedUrl = GetUrl("/empty.html?prerender");
  const GURL kPrerenderingUrl =
      GetUrl("/server-redirect?" + kRedirectedUrl.spec());
  RedirectChainObserver redirect_chain_observer(*shell()->web_contents(),
                                                kRedirectedUrl);
  AddPrerender(kPrerenderingUrl);
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  EXPECT_EQ(GetRequestCount(kRedirectedUrl), 1);

  ASSERT_EQ(2u, redirect_chain_observer.redirect_chain().size());
  EXPECT_EQ(kPrerenderingUrl, redirect_chain_observer.redirect_chain()[0]);
  EXPECT_EQ(kRedirectedUrl, redirect_chain_observer.redirect_chain()[1]);

  // The prerender host should be registered for the initial request URL, not
  // the redirected URL.
  EXPECT_TRUE(HasHostForUrl(kPrerenderingUrl));
  EXPECT_FALSE(HasHostForUrl(kRedirectedUrl));

  // Regression test for https://crbug.com/1211274. Make sure that we don't
  // crash when activating a prerendered page which performed a same-origin
  // redirect.
  RedirectChainObserver activation_redirect_chain_observer(
      *shell()->web_contents(), kRedirectedUrl);

  NavigationHandleObserver activation_observer(web_contents(),
                                               kPrerenderingUrl);
  NavigatePrimaryPage(kPrerenderingUrl);
  ASSERT_EQ(1u, activation_redirect_chain_observer.redirect_chain().size());
  EXPECT_EQ(kRedirectedUrl,
            activation_redirect_chain_observer.redirect_chain()[0]);

  // Cross-check that in case redirection when the prerender navigates and user
  // ends up navigating to the redirected URL. accurate_triggering is true.
  ukm::SourceId ukm_source_id = activation_observer.next_page_ukm_source_id();
  if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
    ExpectPreloadingAttemptUkm(
        {attempt_ukm_entry_builder().BuildEntry(
             ukm_source_id, PreloadingType::kPrefetch,
             PreloadingEligibility::kEligible,
             PreloadingHoldbackStatus::kAllowed,
             PreloadingTriggeringOutcome::kSuccess,
             PreloadingFailureReason::kUnspecified,
             /*accurate=*/true,
             /*ready_time=*/kMockElapsedTime,
             blink::mojom::SpeculationEagerness::kImmediate),
         attempt_ukm_entry_builder().BuildEntry(
             ukm_source_id, PreloadingType::kPrerender,
             PreloadingEligibility::kEligible,
             PreloadingHoldbackStatus::kAllowed,
             PreloadingTriggeringOutcome::kSuccess,
             PreloadingFailureReason::kUnspecified,
             /*accurate=*/true,
             /*ready_time=*/kMockElapsedTime,
             blink::mojom::SpeculationEagerness::kImmediate)});
  } else {
    ExpectPreloadingAttemptUkm({attempt_ukm_entry_builder().BuildEntry(
        ukm_source_id, PreloadingType::kPrerender,
        PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed,
        PreloadingTriggeringOutcome::kSuccess,
        PreloadingFailureReason::kUnspecified,
        /*accurate=*/true,
        /*ready_time=*/kMockElapsedTime,
        blink::mojom::SpeculationEagerness::kImmediate)});
  }
}

IN_PROC_BROWSER_TEST_P(PrerenderBrowserTestFallbackEnabledDisabled,
                       CrossSiteRedirection) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering a URL that causes cross-origin redirection. The
  // cross-origin redirection should fail prerendering.
  const GURL kRedirectedUrl = GetCrossSiteUrl("/empty.html?prerender");
  const GURL kPrerenderingUrl =
      GetUrl("/server-redirect?" + kRedirectedUrl.spec());
  test::PrerenderHostObserver host_observer(*web_contents_impl(),
                                            kPrerenderingUrl);

  base::RunLoop run_loop;
  std::optional<PrefetchStatus> prefetch_status;
  PrefetchContainer::SetPrefetchResponseCompletedCallbackForTesting(
      base::BindLambdaForTesting(
          [&](base::WeakPtr<PrefetchContainer> prefetch_container) {
            if (prefetch_container->GetURL() != kPrerenderingUrl) {
              return;
            }
            prefetch_status = prefetch_container->GetPrefetchStatus();
            run_loop.Quit();
          }));

  AddPrerenderAsync(kPrerenderingUrl);
  host_observer.WaitForDestroyed();

  if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
    // The cancellation is controlled by `PrerenderNavigationThrottle`. If
    // `kPrerender2FallbackPrefetchSpecRule` is enabled, prefetch ahead of
    // prerender is triggered and it follows all redirect in the loading phase
    // of prefetch, and `PrerenderNavigationThrottle` cancels the prerender in
    // the serving phase of prefetch.
    run_loop.Run();
    EXPECT_TRUE(prefetch_status.has_value());
    EXPECT_EQ(prefetch_status.value(), PrefetchStatus::kPrefetchSuccessful);
    EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
    EXPECT_EQ(GetRequestCount(kRedirectedUrl), 1);
  } else {
    EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
    EXPECT_EQ(GetRequestCount(kRedirectedUrl), 0);
  }

  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));
  EXPECT_FALSE(HasHostForUrl(kRedirectedUrl));
  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::kCrossSiteRedirectInInitialNavigation);
}

// Makes sure that activation on navigation for an iframes doesn't happen.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, Activation_iFrame) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  EXPECT_TRUE(AddTestUtilJS(current_frame_host()));

  // Start a prerender.
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);

  // Attempt to activate the prerendered page for an iframe. This should fail
  // and fallback to network request.
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  EXPECT_EQ("LOADED", EvalJs(web_contents(),
                             JsReplace("add_iframe($1)", kPrerenderingUrl)));
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 2);

  // Activation shouldn't happen, so the prerender host should not be consumed.
  EXPECT_EQ(GetHostForUrl(kPrerenderingUrl), host_id);
}

// Make sure that the prerendering browsing context has an isolated trivial
// session history. history.length should be limited to 1 in the prerendering
// browsing context.
//
// Explainer:
// https://github.com/jeremyroman/alternate-loading-modes/blob/main/browsing-context.md#session-history
IN_PROC_BROWSER_TEST_F(
    PrerenderBrowserTest,
    SessionHistoryShouldHaveSingleNavigationEntryInPrerender) {
  // Navigate the primary main frame to an initial page.
  const GURL kInitialUrl = GetUrl("/empty.html?initial");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  TestNavigationHistory(kInitialUrl, /*expected_history_index=*/0,
                        /*expected_history_length=*/1);

  // Navigate the primary main frame to another page so that the initiator
  // page's `history.length` becomes 2. That helps us to distinguish the initial
  // page's session history and the prerendering page's session history. This is
  // not a robust way, but probably good enough in this test.
  const GURL k2ndUrl = GetUrl("/empty.html?2nd");
  ASSERT_TRUE(NavigateToURL(shell(), k2ndUrl));
  TestNavigationHistory(k2ndUrl, /*expected_history_index=*/1,
                        /*expected_history_length=*/2);

  // Start a prerender.
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  RenderFrameHost* prerender_frame_host = GetPrerenderedMainFrameHost(host_id);
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 1);

  TestNavigationHistory(k2ndUrl, /*expected_history_index=*/1,
                        /*expected_history_length=*/2);
  AssertPrerenderHistoryLength(host_id, prerender_frame_host);

  // From here, we perform several operations which usually append a new entry
  // to the session history, however, all navigations within the prerendering
  // browsing context should be done with replacement in the isolated session
  // history.
  // TODO: Factor out this test into several tests. This test is getting large.

  // Perform history.replaceState() in the prerendered page. Note
  // history.replaceState() doesn't append a new entry anyway. The purpose of
  // testing history.replaceState() here is just for the comparison; pushState()
  // vs replaceState(). Both should have the same behavior in a prerendering
  // browsing context.
  {
    FrameNavigateParamsCapturer capturer(
        FrameTreeNode::From(prerender_frame_host));

    ASSERT_EQ(base::Value(),
              EvalJs(prerender_frame_host,
                     "history.replaceState('state1', null, null)"));

    TestNavigationHistory(k2ndUrl, /*expected_history_index=*/1,
                          /*expected_history_length=*/2);
    AssertPrerenderHistoryLength(host_id, prerender_frame_host);
    EXPECT_EQ("state1", EvalJs(prerender_frame_host, "history.state"));

    EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY,
              capturer.navigation_type());
    EXPECT_TRUE(capturer.is_same_document());
    EXPECT_TRUE(capturer.did_replace_entry());
  }

  // Perform history.pushState() in the prerendered page.
  {
    FrameNavigateParamsCapturer capturer(
        FrameTreeNode::From(prerender_frame_host));

    ASSERT_EQ(base::Value(), EvalJs(prerender_frame_host,
                                    "history.pushState('state2', null, null)"));

    TestNavigationHistory(k2ndUrl, /*expected_history_index=*/1,
                          /*expected_history_length=*/2);
    AssertPrerenderHistoryLength(host_id, prerender_frame_host);
    EXPECT_EQ("state2", EvalJs(prerender_frame_host, "history.state"));

    EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY,
              capturer.navigation_type());
    EXPECT_TRUE(capturer.is_same_document());
    EXPECT_TRUE(capturer.did_replace_entry());
  }

  // Do a fragment navigation in the prerendered main frame.
  {
    FrameNavigateParamsCapturer capturer(
        FrameTreeNode::From(prerender_frame_host));

    const GURL kPrerenderingAnchorUrl = GetUrl("/empty.html?prerender#anchor");
    NavigatePrerenderedPage(host_id, kPrerenderingAnchorUrl);
    WaitForPrerenderLoadCompletion(host_id);
    ASSERT_EQ(GetRequestCount(kPrerenderingAnchorUrl), 1);

    TestNavigationHistory(k2ndUrl, /*expected_history_index=*/1,
                          /*expected_history_length=*/2);
    AssertPrerenderHistoryLength(host_id, prerender_frame_host);
    // history.state should be replaced with a fragment navigation.
    EXPECT_EQ(base::Value(), EvalJs(prerender_frame_host, "history.state"));

    EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY,
              capturer.navigation_type());
    EXPECT_TRUE(capturer.is_same_document());
    EXPECT_TRUE(capturer.did_replace_entry());
  }

  // Add a same-origin iframe to the prerendered page and let it navigate to the
  // different same-origin URL.
  {
    // Add an iframe.
    const GURL kSameOriginSubframeUrl1 =
        GetUrl("/empty.html?same_origin_iframe1");
    EXPECT_TRUE(AddTestUtilJS(prerender_frame_host));
    ASSERT_EQ("LOADED",
              EvalJs(prerender_frame_host,
                     JsReplace("add_iframe($1)", kSameOriginSubframeUrl1)));
    ASSERT_EQ(GetRequestCount(kSameOriginSubframeUrl1), 1);

    auto* child_frame = ChildFrameAt(prerender_frame_host, 0);
    ASSERT_NE(nullptr, child_frame);
    EXPECT_EQ(kSameOriginSubframeUrl1, child_frame->GetLastCommittedURL());

    // Let the added iframe navigate to the different URL.
    {
      FrameNavigateParamsCapturer capturer(FrameTreeNode::From(child_frame));
      const GURL kSameOriginSubframeUrl2 =
          GetUrl("/empty.html?same_origin_iframe2");
      ASSERT_EQ(kSameOriginSubframeUrl2,
                EvalJs(child_frame,
                       JsReplace("location = $1", kSameOriginSubframeUrl2)));
      capturer.Wait();
      child_frame = ChildFrameAt(prerender_frame_host, 0);
      EXPECT_EQ(kSameOriginSubframeUrl2, child_frame->GetLastCommittedURL());
      ASSERT_EQ(GetRequestCount(kSameOriginSubframeUrl2), 1);

      TestNavigationHistory(k2ndUrl, /*expected_history_index=*/1,
                            /*expected_history_length=*/2);
      AssertPrerenderHistoryLength(host_id, prerender_frame_host);
      EXPECT_EQ(base::Value(), EvalJs(prerender_frame_host, "history.state"));

      EXPECT_EQ(NAVIGATION_TYPE_AUTO_SUBFRAME, capturer.navigation_type());
      EXPECT_FALSE(capturer.is_same_document());
      EXPECT_TRUE(capturer.did_replace_entry());
      EXPECT_TRUE(capturer.is_renderer_initiated());
    }

    // Use WebContents::OpenURL() to let the added iframe navigate.
    {
      FrameNavigateParamsCapturer capturer(FrameTreeNode::From(child_frame));
      const GURL kSameOriginSubframeUrl3 =
          GetUrl("/empty.html?same_origin_iframe3");
      shell()->web_contents()->OpenURL(
          OpenURLParams(kSameOriginSubframeUrl3, Referrer(),
                        child_frame->GetFrameTreeNodeId(),
                        WindowOpenDisposition::CURRENT_TAB,
                        ui::PAGE_TRANSITION_AUTO_SUBFRAME,
                        /*is_renderer_initiated=*/false),
          /*navigation_handle_callback=*/{});
      capturer.Wait();
      child_frame = ChildFrameAt(prerender_frame_host, 0);
      EXPECT_EQ(kSameOriginSubframeUrl3, child_frame->GetLastCommittedURL());
      ASSERT_EQ(GetRequestCount(kSameOriginSubframeUrl3), 1);

      TestNavigationHistory(k2ndUrl, /*expected_history_index=*/1,
                            /*expected_history_length=*/2);
      AssertPrerenderHistoryLength(host_id, prerender_frame_host);
      EXPECT_EQ(base::Value(), EvalJs(prerender_frame_host, "history.state"));

      EXPECT_EQ(NAVIGATION_TYPE_AUTO_SUBFRAME, capturer.navigation_type());
      EXPECT_FALSE(capturer.is_same_document());
      EXPECT_TRUE(capturer.did_replace_entry());
      EXPECT_FALSE(capturer.is_renderer_initiated());
    }
  }

  // Perform history.back() in the prerendered page, which should be no-op.
  {
    int current_request_count = GetRequestCount(k2ndUrl);
    ASSERT_EQ(base::Value(), EvalJs(prerender_frame_host, "history.back()"));
    // Make sure that loading is not happening.
    EXPECT_FALSE(FrameTreeNode::GloballyFindByID(
                     PrerenderHost::GetFrameTreeNodeIdForId(host_id))
                     ->frame_tree()
                     .IsLoadingIncludingInnerFrameTrees());

    TestNavigationHistory(k2ndUrl, /*expected_history_index=*/1,
                          /*expected_history_length=*/2);
    AssertPrerenderHistoryLength(host_id, prerender_frame_host);
    EXPECT_EQ(base::Value(), EvalJs(prerender_frame_host, "history.state"));
    EXPECT_EQ(current_request_count, GetRequestCount(k2ndUrl));
  }

  // Perform history.forward() in the prerendered page, which should be no-op.
  {
    int current_request_count = GetRequestCount(k2ndUrl);
    ASSERT_EQ(base::Value(), EvalJs(prerender_frame_host, "history.forward()"));
    // Make sure that loading is not happening.
    EXPECT_FALSE(FrameTreeNode::GloballyFindByID(
                     PrerenderHost::GetFrameTreeNodeIdForId(host_id))
                     ->frame_tree()
                     .IsLoadingIncludingInnerFrameTrees());

    TestNavigationHistory(k2ndUrl, /*expected_history_index=*/1,
                          /*expected_history_length=*/2);
    AssertPrerenderHistoryLength(host_id, prerender_frame_host);
    EXPECT_EQ(base::Value(), EvalJs(prerender_frame_host, "history.state"));
    EXPECT_EQ(current_request_count, GetRequestCount(k2ndUrl));
  }
}

// Make sure that activation appends the prerendering page's single navigation
// entry to the initiator page's joint session history. We can go back or
// forward after activation.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, SessionHistoryAfterActivation) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/empty.html?initial");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  TestNavigationHistory(kInitialUrl, 0, 1);

  // Navigate to another page.
  const GURL k2ndUrl = GetUrl("/empty.html?2nd");
  ASSERT_TRUE(NavigateToURL(shell(), k2ndUrl));
  ASSERT_EQ(GetRequestCount(k2ndUrl), 1);
  TestNavigationHistory(k2ndUrl, 1, 2);

  // Start a prerender.
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  RenderFrameHost* prerender_frame_host = GetPrerenderedMainFrameHost(host_id);
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  TestNavigationHistory(k2ndUrl, 1, 2);

  // Call history.pushState(...) in  prerendering.
  ASSERT_EQ(base::Value(),
            EvalJs(prerender_frame_host,
                   "history.pushState('teststate', null, null)"));
  TestNavigationHistory(k2ndUrl, 1, 2);
  AssertPrerenderHistoryLength(host_id, prerender_frame_host);
  EXPECT_EQ("teststate", EvalJs(prerender_frame_host, "history.state"));

  // Activate.
  NavigatePrimaryPage(kPrerenderingUrl);
  // The joint session history becomes [initial, 2nd, <prerender>].
  TestNavigationHistory(kPrerenderingUrl, 2, 3);
  EXPECT_EQ("teststate", EvalJs(web_contents(), "history.state"));

  FrameTreeNode* root = static_cast<WebContentsImpl*>(web_contents())
                            ->GetPrimaryFrameTree()
                            .root();
  // Go Back.
  {
    FrameNavigateParamsCapturer capturer(root);
    GoBack();
    // The joint session history becomes [initial, <2nd>, prerender].
    TestNavigationHistory(k2ndUrl, 1, 3);
    EXPECT_EQ(base::Value(), EvalJs(web_contents(), "history.state"));

    EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY,
              capturer.navigation_type());
    EXPECT_FALSE(capturer.is_same_document());
  }

  // Go Forward.
  {
    FrameNavigateParamsCapturer capturer(root);
    GoForward();
    // The joint session history becomes [initial, 2nd, <prerender>].
    TestNavigationHistory(kPrerenderingUrl, 2, 3);
    EXPECT_EQ("teststate", EvalJs(web_contents(), "history.state"));

    EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY,
              capturer.navigation_type());
    EXPECT_FALSE(capturer.is_same_document());
  }
}

class PrerenderOopsifBrowserTest : public PrerenderBrowserTest {
 public:
  PrerenderOopsifBrowserTest() {
    feature_list_.InitWithFeaturesAndParameters(
        {{blink::features::kIsolateSandboxedIframes,
          {{"grouping", "per-origin"}}}},
        {/* disabled_features */});
  }

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

// Test for crbug.com/1470312.
// Prior to the CL that introduced this test, if IsolatedSandboxedIframes are
// enabled, and an isolated frame sends the parent a postMessage, then the
// proxies were attached to the active page and not the prerendered  mainframe.
// These were proxies that were created on demand when processing the
// postMessage. (to ensure the recipient can reply to the sender frame, or to a
// frame that the sender could reach). This led to a CHECK failure in
// ~BrowsingContextInstance(). This test verifies that problem has been
// resolved.
IN_PROC_BROWSER_TEST_F(PrerenderOopsifBrowserTest,
                       OopsifSrcdocSandboxIframeWithPostmessage) {
  // Navigate to an initial page.
  const GURL kInitialUrl =
      GetUrl("/prerender/cross_origin_prerender.html?initial");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  EXPECT_TRUE(AddTestUtilJS(current_frame_host()));

  // Start a prerender.
  const GURL kPrerenderingUrl =
      GetUrl("/prerender/cross_origin_srcdoc_sandboxed_postmessage.html");
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  RenderFrameHost* prerender_frame_host = GetPrerenderedMainFrameHost(host_id);
  EXPECT_TRUE(AddTestUtilJS(prerender_frame_host));
  // Create a srcdoc iframe in the prerendered page.
  EXPECT_TRUE(ExecJs(prerender_frame_host, "createSrcdoc();"));
  base::RunLoop().RunUntilIdle();

  // Load another same-origin iframe to ensure loading the srcdoc iframe
  // starts and then it's deferred until activation.
  const GURL kSameOriginSubframeUrl =
      GetUrl("/prerender/cross_origin_prerender.html");
  ASSERT_EQ("LOADED",
            EvalJs(prerender_frame_host,
                   JsReplace("add_iframe($1)", kSameOriginSubframeUrl)));

  // Activate.
  NavigatePrimaryPage(kPrerenderingUrl);
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);

  // Verify postMessage from srcdoc to mainframe completed.
  RenderFrameHostImpl* main_frame =
      static_cast<RenderFrameHostImpl*>(web_contents()->GetPrimaryMainFrame());
  EXPECT_TRUE(ExecJs(
      main_frame,
      "Promise.all([child_response_promise, prerender_handler_promise]);"));

  // OOPSIFs only process-isolate if the parent gets site isolation, which in
  // this case doesn't happen on Android.
  if (AreAllSitesIsolatedForTesting()) {
    RenderFrameHostImpl* sandboxed_render_frame_host =
        main_frame->child_at(0)->current_frame_host();
    EXPECT_TRUE(sandboxed_render_frame_host->GetSiteInstance()
                    ->GetSecurityPrincipal()
                    .IsSandboxed());
    ASSERT_NE(main_frame->GetProcess(),
              sandboxed_render_frame_host->GetProcess());
  }
}

// Makes sure that cross-origin subframe navigations are deferred during
// prerendering.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       DeferCrossOriginSubframeNavigation) {
  // Navigate to an initial page.
  const GURL kInitialUrl =
      GetUrl("/prerender/cross_origin_prerender.html?initial");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  EXPECT_TRUE(AddTestUtilJS(current_frame_host()));

  // Start a prerender.
  const GURL kPrerenderingUrl =
      GetUrl("/prerender/cross_origin_prerender.html?prerender");
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);

  const GURL kSameOriginSubframeUrl =
      GetUrl("/prerender/cross_origin_prerender.html?same_origin_iframe");
  const GURL kCrossOriginSubframeUrl = GetCrossSiteUrl(
      "/prerender/cross_origin_prerender.html?cross_origin_iframe");

  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  ASSERT_EQ(GetRequestCount(kSameOriginSubframeUrl), 0);
  ASSERT_EQ(GetRequestCount(kCrossOriginSubframeUrl), 0);

  // Add a cross-origin iframe to the prerendering page.
  RenderFrameHost* prerender_frame_host = GetPrerenderedMainFrameHost(host_id);
  EXPECT_TRUE(AddTestUtilJS(prerender_frame_host));

  // Use ExecuteScriptAsync instead of EvalJs as inserted cross-origin iframe
  // navigation would be deferred and script execution does not finish until
  // the activation.
  ExecuteScriptAsync(prerender_frame_host, JsReplace("add_iframe_async($1)",
                                                     kCrossOriginSubframeUrl));
  base::RunLoop().RunUntilIdle();

  // Add a same-origin iframe to the prerendering page.
  ASSERT_EQ("LOADED",
            EvalJs(prerender_frame_host,
                   JsReplace("add_iframe($1)", kSameOriginSubframeUrl)));
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  ASSERT_EQ(GetRequestCount(kSameOriginSubframeUrl), 1);
  ASSERT_EQ(GetRequestCount(kCrossOriginSubframeUrl), 0);

  // Activate.
  NavigatePrimaryPage(kPrerenderingUrl);
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);
  ASSERT_EQ("LOADED",
            EvalJs(prerender_frame_host, JsReplace("wait_iframe_async($1)",
                                                   kCrossOriginSubframeUrl)));
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  ASSERT_EQ(GetRequestCount(kSameOriginSubframeUrl), 1);
  EXPECT_EQ(GetRequestCount(kCrossOriginSubframeUrl), 1);

  const char kInitialDocumentPrerenderingScript[] =
      "initial_document_prerendering";
  const char kCurrentDocumentPrerenderingScript[] = "document.prerendering";
  const char kOnprerenderingchangeObservedScript[] =
      "onprerenderingchange_observed";
  const char kActivationStartScript[] =
      "performance.getEntriesByType('navigation')[0].activationStart";
  EXPECT_EQ(true,
            EvalJs(prerender_frame_host, kInitialDocumentPrerenderingScript));
  EXPECT_EQ(false,
            EvalJs(prerender_frame_host, kCurrentDocumentPrerenderingScript));
  EXPECT_EQ(true,
            EvalJs(prerender_frame_host, kOnprerenderingchangeObservedScript));
  EXPECT_NE(0, EvalJs(prerender_frame_host, kActivationStartScript));

  RenderFrameHost* same_origin_render_frame_host = FindRenderFrameHost(
      prerender_frame_host->GetPage(), kSameOriginSubframeUrl);
  CHECK(same_origin_render_frame_host);
  EXPECT_EQ(true, EvalJs(same_origin_render_frame_host,
                         kInitialDocumentPrerenderingScript));
  EXPECT_EQ(false, EvalJs(same_origin_render_frame_host,
                          kCurrentDocumentPrerenderingScript));
  EXPECT_EQ(true, EvalJs(same_origin_render_frame_host,
                         kOnprerenderingchangeObservedScript));
  EXPECT_NE(0, EvalJs(same_origin_render_frame_host, kActivationStartScript));

  RenderFrameHost* cross_origin_render_frame_host = FindRenderFrameHost(
      prerender_frame_host->GetPage(), kCrossOriginSubframeUrl);
  CHECK(cross_origin_render_frame_host);
  EXPECT_EQ(false, EvalJs(cross_origin_render_frame_host,
                          kInitialDocumentPrerenderingScript));
  EXPECT_EQ(false, EvalJs(cross_origin_render_frame_host,
                          kCurrentDocumentPrerenderingScript));
  EXPECT_EQ(false, EvalJs(cross_origin_render_frame_host,
                          kOnprerenderingchangeObservedScript));
  EXPECT_EQ(0, EvalJs(cross_origin_render_frame_host, kActivationStartScript));
}

// Makes sure that subframe navigations are deferred if cross-origin redirects
// are observed in a prerendering page.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       DeferCrossOriginRedirectsOnSubframeNavigation) {
  // Navigate to an initial page.
  const GURL kInitialUrl =
      GetUrl("/prerender/cross_origin_prerender.html?initial");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start a prerender.
  const GURL kPrerenderingUrl =
      GetUrl("/prerender/cross_origin_prerender.html?prerender");
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);

  const GURL kCrossOriginSubframeUrl = GetCrossSiteUrl(
      "/prerender/cross_origin_prerender.html?cross_origin_iframe");
  const GURL kServerRedirectSubframeUrl =
      GetUrl("/server-redirect?" + kCrossOriginSubframeUrl.spec());

  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  ASSERT_EQ(GetRequestCount(kServerRedirectSubframeUrl), 0);
  ASSERT_EQ(GetRequestCount(kCrossOriginSubframeUrl), 0);

  // Add an iframe pointing to a server redirect page to the prerendering page.
  RenderFrameHost* prerender_frame_host = GetPrerenderedMainFrameHost(host_id);
  EXPECT_TRUE(AddTestUtilJS(prerender_frame_host));
  // Use ExecuteScriptAsync instead of EvalJs as inserted iframe redirect
  // navigation would be deferred and script execution does not finish until
  // the activation.
  ExecuteScriptAsync(
      prerender_frame_host,
      JsReplace("add_iframe_async($1)", kServerRedirectSubframeUrl));
  WaitForRequest(kServerRedirectSubframeUrl, 1);
  ASSERT_EQ(GetRequestCount(kServerRedirectSubframeUrl), 1);
  ASSERT_EQ(GetRequestCount(kCrossOriginSubframeUrl), 0);

  // Activate.
  NavigatePrimaryPage(kPrerenderingUrl);
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);
  ASSERT_EQ("LOADED", EvalJs(prerender_frame_host,
                             JsReplace("wait_iframe_async($1)",
                                       kServerRedirectSubframeUrl)));
  EXPECT_EQ(GetRequestCount(kServerRedirectSubframeUrl), 1);
  EXPECT_EQ(GetRequestCount(kCrossOriginSubframeUrl), 1);

  const char kInitialDocumentPrerenderingScript[] =
      "initial_document_prerendering";
  const char kCurrentDocumentPrerenderingScript[] = "document.prerendering";
  const char kOnprerenderingchangeObservedScript[] =
      "onprerenderingchange_observed";
  EXPECT_EQ(true,
            EvalJs(prerender_frame_host, kInitialDocumentPrerenderingScript));
  EXPECT_EQ(false,
            EvalJs(prerender_frame_host, kCurrentDocumentPrerenderingScript));
  EXPECT_EQ(true,
            EvalJs(prerender_frame_host, kOnprerenderingchangeObservedScript));

  RenderFrameHost* cross_origin_render_frame_host = FindRenderFrameHost(
      prerender_frame_host->GetPage(), kCrossOriginSubframeUrl);
  CHECK(cross_origin_render_frame_host);
  EXPECT_EQ(false, EvalJs(cross_origin_render_frame_host,
                          kInitialDocumentPrerenderingScript));
  EXPECT_EQ(false, EvalJs(cross_origin_render_frame_host,
                          kCurrentDocumentPrerenderingScript));
  EXPECT_EQ(false, EvalJs(cross_origin_render_frame_host,
                          kOnprerenderingchangeObservedScript));
}

// Tests for main frame navigation in a prerendered page.
class PrerenderMainFrameNavigationBrowserTest
    : public testing::WithParamInterface<PreloadingTriggerType>,
      public PrerenderBrowserTest {
 protected:
  enum class NavigationType {
    kSameOrigin,
    kSameSiteCrossOrigin,
    kSameSiteCrossOriginWithOptIn,
    kCrossSite,
  };

  // Runs navigations in the `navigations_types` order and makes sure it ends
  // with `expected_status`.
  void TestMainFrameNavigation(
      const std::vector<NavigationType>& navigation_types,
      PrerenderFinalStatus expected_status) {
    ASSERT_FALSE(navigation_types.empty());
    PreloadingTriggerType trigger_type = GetParam();

    std::vector<GURL> urls;
    for (auto type : navigation_types) {
      urls.push_back(CreateUrl(type));
    }

    const GURL kInitialUrl = GetUrl("/empty.html");
    const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");

    // Navigate to an initial page.
    ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

    // Start a prerender.
    PrerenderHostId host_id;
    std::unique_ptr<PrerenderHandle> prerender_handle;
    switch (trigger_type) {
      case PreloadingTriggerType::kSpeculationRule:
        host_id = AddPrerender(kPrerenderingUrl);
        break;
      case PreloadingTriggerType::kSpeculationRuleFromIsolatedWorld:
        host_id = AddPrerender(kPrerenderingUrl, /*world_id=*/1);
        break;
      case PreloadingTriggerType::kEmbedder:
        prerender_handle = AddEmbedderTriggeredPrerender(kPrerenderingUrl);
        host_id = static_cast<PrerenderHandleImpl*>(prerender_handle.get())
                      ->prerender_host_id_for_testing();
        break;
      case PreloadingTriggerType::kSpeculationRuleFromAutoSpeculationRules:
        FAIL() << "Auto speculation rules does not work with empty.html";
    }
    ASSERT_TRUE(host_id);

    test::PrerenderHostObserver observer(*web_contents_impl(), host_id);

    // Run navigations in the main frame of the prerendered page. Only the last
    // URL of the given navigation URLs will separately be handled later as that
    // could cancel prerendering and never finish.
    for (auto it = urls.begin(); it != urls.end() - 1; ++it) {
      TestNavigationManager navigation_observer(web_contents(), *it);
      NavigatePrerenderedPage(host_id, *it);
      ASSERT_TRUE(navigation_observer.WaitForNavigationFinished());
      EXPECT_TRUE(navigation_observer.was_successful());
    }

    // The last navigation URL. This should cancel prerendering if the
    // expectation is not kActivated.
    const GURL& last_url = urls.back();

    switch (expected_status) {
      case PrerenderFinalStatus::kActivated: {
        // Navigation to the last URL should succeed.
        TestNavigationManager navigation_observer(web_contents(), last_url);
        NavigatePrerenderedPage(host_id, last_url);
        ASSERT_TRUE(navigation_observer.WaitForNavigationFinished());
        EXPECT_TRUE(navigation_observer.was_successful());

        // Activation should succeed.
        switch (trigger_type) {
          case PreloadingTriggerType::kSpeculationRule:
          case PreloadingTriggerType::kSpeculationRuleFromIsolatedWorld:
            NavigatePrimaryPage(kPrerenderingUrl);
            break;
          case PreloadingTriggerType::kEmbedder:
            NavigatePrimaryPageFromAddressBar(kPrerenderingUrl);
            break;
          case PreloadingTriggerType::kSpeculationRuleFromAutoSpeculationRules:
            FAIL() << "Auto speculation rules does not work with empty.html";
        }
        observer.WaitForActivation();
        EXPECT_TRUE(observer.was_activated());
        EXPECT_EQ(web_contents()->GetLastCommittedURL(), last_url);
        break;
      }
      default: {
        // Navigation to the last URL should cancel prerendering.
        NavigatePrerenderedPage(host_id, last_url);
        observer.WaitForDestroyed();
        EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));
        break;
      }
    }

    // Verify UMA/UKM records.
    switch (trigger_type) {
      case PreloadingTriggerType::kSpeculationRule:
        ExpectFinalStatusForSpeculationRule(expected_status);
        break;
      case PreloadingTriggerType::kSpeculationRuleFromIsolatedWorld:
        ExpectFinalStatusForSpeculationRuleFromIsolatedWorld(expected_status);
        break;
      case PreloadingTriggerType::kEmbedder:
        ExpectFinalStatusForEmbedder(expected_status);
        break;
      case PreloadingTriggerType::kSpeculationRuleFromAutoSpeculationRules:
        FAIL() << "Auto speculation rules does not work with empty.html";
    }
  }

  // Runs redirections in the `navigations_types` order and makes sure it ends
  // with `expected_status`.
  void TestMainFrameRedirection(
      const std::vector<NavigationType>& redirection_types,
      PrerenderFinalStatus expected_status) {
    ASSERT_FALSE(redirection_types.empty());
    PreloadingTriggerType trigger_type = GetParam();

    // Create a URL that rus a redirection sequence in the order of
    // `redirection_types`. To make the URL, create a final URL from the last
    // element of `redirection_types` and then prefix a rediretion URL by
    // iterating the types in reverse order.
    const GURL final_url = CreateUrl(redirection_types.back());
    GURL url = final_url;
    for (auto it = redirection_types.rbegin() + 1;
         it != redirection_types.rend(); ++it) {
      url = CreateRedirectionUrl(*it, url);
    }

    const GURL kInitialUrl = GetUrl("/empty.html");
    const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");

    // Navigate to an initial page.
    ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

    // Start a prerender.
    PrerenderHostId host_id;
    std::unique_ptr<PrerenderHandle> prerender_handle;
    switch (trigger_type) {
      case PreloadingTriggerType::kSpeculationRule:
        host_id = AddPrerender(kPrerenderingUrl);
        break;
      case PreloadingTriggerType::kSpeculationRuleFromIsolatedWorld:
        host_id = AddPrerender(kPrerenderingUrl, /*world_id=*/1);
        break;
      case PreloadingTriggerType::kEmbedder:
        prerender_handle = AddEmbedderTriggeredPrerender(kPrerenderingUrl);
        host_id = static_cast<PrerenderHandleImpl*>(prerender_handle.get())
                      ->prerender_host_id_for_testing();
        break;
      case PreloadingTriggerType::kSpeculationRuleFromAutoSpeculationRules:
        FAIL() << "Auto speculation rules does not work with empty.html";
    }
    ASSERT_TRUE(host_id);

    test::PrerenderHostObserver observer(*web_contents_impl(), host_id);

    // Run redirections in the main frame of the prerendered page.
    TestNavigationManager navigation_observer(web_contents(), url);
    NavigatePrerenderedPage(host_id, url);
    ASSERT_TRUE(navigation_observer.WaitForNavigationFinished());

    switch (expected_status) {
      case PrerenderFinalStatus::kActivated: {
        // Redirections should succeed.
        EXPECT_TRUE(navigation_observer.was_successful());

        // Activation should succeed.
        switch (trigger_type) {
          case PreloadingTriggerType::kSpeculationRule:
          case PreloadingTriggerType::kSpeculationRuleFromIsolatedWorld:
            NavigatePrimaryPage(kPrerenderingUrl);
            break;
          case PreloadingTriggerType::kEmbedder:
            NavigatePrimaryPageFromAddressBar(kPrerenderingUrl);
            break;
          case PreloadingTriggerType::kSpeculationRuleFromAutoSpeculationRules:
            FAIL() << "Auto speculation rules does not work with empty.html";
        }
        observer.WaitForActivation();
        EXPECT_TRUE(observer.was_activated());
        EXPECT_EQ(web_contents()->GetLastCommittedURL(), final_url);
        break;
      }
      default: {
        // Redirections should cancel prerendering.
        EXPECT_FALSE(navigation_observer.was_successful());
        observer.WaitForDestroyed();
        EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));
        break;
      }
    }

    // Verify UMA/UKM records.
    switch (trigger_type) {
      case PreloadingTriggerType::kSpeculationRule:
        ExpectFinalStatusForSpeculationRule(expected_status);
        break;
      case PreloadingTriggerType::kSpeculationRuleFromIsolatedWorld:
        ExpectFinalStatusForSpeculationRuleFromIsolatedWorld(expected_status);
        break;
      case PreloadingTriggerType::kEmbedder:
        ExpectFinalStatusForEmbedder(expected_status);
        break;
      case PreloadingTriggerType::kSpeculationRuleFromAutoSpeculationRules:
        FAIL() << "Auto speculation rules does not work with empty.html";
    }
  }

 private:
  GURL CreateUrl(NavigationType type) {
    static int number_for_prefix = 0;
    std::string prefix = base::NumberToString(number_for_prefix++);
    switch (type) {
      case NavigationType::kSameOrigin:
        return GetUrl("/empty.html?" + prefix);
      case NavigationType::kSameSiteCrossOrigin:
        return GetSameSiteCrossOriginUrl("/empty.html?" + prefix);
      case NavigationType::kSameSiteCrossOriginWithOptIn:
        return GetSameSiteCrossOriginUrl(
            "/prerender/prerender_with_opt_in_header.html?" + prefix);
      case NavigationType::kCrossSite:
        return GetCrossSiteUrl("/empty.html?" + prefix);
    }
  }

  // Creates a URL that redirects to `url_to_redirect`. The origin of the URL is
  // determined by `type`.
  GURL CreateRedirectionUrl(NavigationType type, const GURL& url_to_redirect) {
    switch (type) {
      case NavigationType::kSameOrigin:
        return GetUrl("/server-redirect?" + url_to_redirect.spec());
      case NavigationType::kSameSiteCrossOrigin:
        return GetSameSiteCrossOriginUrl("/server-redirect?" +
                                         url_to_redirect.spec());
      case NavigationType::kSameSiteCrossOriginWithOptIn:
        return GetSameSiteCrossOriginUrl(
            "/server-redirect-credentialed-prerender?" +
            url_to_redirect.spec());
      case NavigationType::kCrossSite:
        return GetCrossSiteUrl("/server-redirect?" + url_to_redirect.spec());
    }
  }
};

INSTANTIATE_TEST_SUITE_P(
    All,
    PrerenderMainFrameNavigationBrowserTest,
    testing::Values(PreloadingTriggerType::kSpeculationRule,
                    PreloadingTriggerType::kSpeculationRuleFromIsolatedWorld,
                    PreloadingTriggerType::kEmbedder),
    [](const testing::TestParamInfo<PreloadingTriggerType>& info) {
      switch (info.param) {
        case PreloadingTriggerType::kSpeculationRule:
          return "SpeculationRule";
        case PreloadingTriggerType::kSpeculationRuleFromIsolatedWorld:
          return "SpeculationRuleFromIsolatedWorld";
        case PreloadingTriggerType::kEmbedder:
          return "Embedder";
        case PreloadingTriggerType::kSpeculationRuleFromAutoSpeculationRules:
          ADD_FAILURE() << "Auto speculation rules does not work with "
                           "TestMainFrameNavigation";
          return "SpeculationRuleFromAutoSpeculationRules";
      }
    });

IN_PROC_BROWSER_TEST_P(PrerenderMainFrameNavigationBrowserTest, SameOrigin) {
  std::vector<NavigationType> navigations = {NavigationType::kSameOrigin};
  TestMainFrameNavigation(navigations, PrerenderFinalStatus::kActivated);
}

IN_PROC_BROWSER_TEST_P(PrerenderMainFrameNavigationBrowserTest,
                       SameSiteCrossOriginWithOptIn) {
  std::vector<NavigationType> navigations = {
      NavigationType::kSameSiteCrossOriginWithOptIn};
  TestMainFrameNavigation(navigations, PrerenderFinalStatus::kActivated);
}

IN_PROC_BROWSER_TEST_P(PrerenderMainFrameNavigationBrowserTest,
                       SameSiteCrossOrigin) {
  std::vector<NavigationType> navigations = {
      NavigationType::kSameSiteCrossOrigin};
  TestMainFrameNavigation(
      navigations,
      PrerenderFinalStatus::
          kSameSiteCrossOriginNavigationNotOptInInMainFrameNavigation);
}

IN_PROC_BROWSER_TEST_P(PrerenderMainFrameNavigationBrowserTest, CrossSite) {
  std::vector<NavigationType> navigations = {NavigationType::kCrossSite};
  TestMainFrameNavigation(
      navigations,
      PrerenderFinalStatus::kCrossSiteNavigationInMainFrameNavigation);
}

IN_PROC_BROWSER_TEST_P(PrerenderMainFrameNavigationBrowserTest,
                       SameSiteCrossOriginWithOptIn_SameOrigin) {
  std::vector<NavigationType> navigations = {
      NavigationType::kSameSiteCrossOriginWithOptIn,
      NavigationType::kSameOrigin};
  TestMainFrameNavigation(navigations, PrerenderFinalStatus::kActivated);
}

IN_PROC_BROWSER_TEST_P(
    PrerenderMainFrameNavigationBrowserTest,
    SameSiteCrossOriginWithOptIn_SameSiteCrossOriginWithOptIn) {
  std::vector<NavigationType> navigations = {
      NavigationType::kSameSiteCrossOriginWithOptIn,
      NavigationType::kSameSiteCrossOriginWithOptIn};
  TestMainFrameNavigation(navigations, PrerenderFinalStatus::kActivated);
}

IN_PROC_BROWSER_TEST_P(PrerenderMainFrameNavigationBrowserTest,
                       SameSiteCrossOriginWithOptIn_SameSiteCrossOrigin) {
  std::vector<NavigationType> navigations = {
      NavigationType::kSameSiteCrossOriginWithOptIn,
      NavigationType::kSameSiteCrossOrigin};
  TestMainFrameNavigation(
      navigations,
      PrerenderFinalStatus::
          kSameSiteCrossOriginNavigationNotOptInInMainFrameNavigation);
}

IN_PROC_BROWSER_TEST_P(PrerenderMainFrameNavigationBrowserTest,
                       SameSiteCrossOrigin_CrossSite) {
  std::vector<NavigationType> navigations = {
      NavigationType::kSameSiteCrossOriginWithOptIn,
      NavigationType::kCrossSite};
  TestMainFrameNavigation(
      navigations,
      PrerenderFinalStatus::kCrossSiteNavigationInMainFrameNavigation);
}

IN_PROC_BROWSER_TEST_P(PrerenderMainFrameNavigationBrowserTest,
                       Redirection_SameOrigin_SameOrigin) {
  std::vector<NavigationType> redirections = {NavigationType::kSameOrigin,
                                              NavigationType::kSameOrigin};
  TestMainFrameRedirection(redirections, PrerenderFinalStatus::kActivated);
}

IN_PROC_BROWSER_TEST_P(PrerenderMainFrameNavigationBrowserTest,
                       Redirection_SameOrigin_SameSiteCrossOriginWithOptIn) {
  std::vector<NavigationType> redirections = {
      NavigationType::kSameOrigin,
      NavigationType::kSameSiteCrossOriginWithOptIn};
  TestMainFrameRedirection(redirections, PrerenderFinalStatus::kActivated);
}

IN_PROC_BROWSER_TEST_P(PrerenderMainFrameNavigationBrowserTest,
                       Redirection_SameOrigin_SameSiteCrossOrigin) {
  std::vector<NavigationType> redirections = {
      NavigationType::kSameOrigin, NavigationType::kSameSiteCrossOrigin};
  TestMainFrameRedirection(
      redirections,
      PrerenderFinalStatus::
          kSameSiteCrossOriginRedirectNotOptInInMainFrameNavigation);
}

IN_PROC_BROWSER_TEST_P(PrerenderMainFrameNavigationBrowserTest,
                       Redirection_SameOrigin_CrossSite) {
  std::vector<NavigationType> redirections = {NavigationType::kSameOrigin,
                                              NavigationType::kCrossSite};
  TestMainFrameRedirection(
      redirections,
      PrerenderFinalStatus::kCrossSiteRedirectInMainFrameNavigation);
}

IN_PROC_BROWSER_TEST_P(PrerenderMainFrameNavigationBrowserTest,
                       Redirection_SameSiteCrossOriginWithOptIn_SameOrigin) {
  std::vector<NavigationType> redirections = {
      NavigationType::kSameSiteCrossOriginWithOptIn,
      NavigationType::kSameOrigin};
  TestMainFrameRedirection(redirections, PrerenderFinalStatus::kActivated);
}

IN_PROC_BROWSER_TEST_P(
    PrerenderMainFrameNavigationBrowserTest,
    Redirection_SameSiteCrossOriginWithOptIn_SameSiteCrossOriginWithOptIn) {
  std::vector<NavigationType> redirections = {
      NavigationType::kSameSiteCrossOriginWithOptIn,
      NavigationType::kSameSiteCrossOriginWithOptIn};
  TestMainFrameRedirection(redirections, PrerenderFinalStatus::kActivated);
}

IN_PROC_BROWSER_TEST_P(
    PrerenderMainFrameNavigationBrowserTest,
    Redirection_SameSiteCrossOriginWithOptIn_SameSiteCrossOrigin) {
  std::vector<NavigationType> redirections = {
      NavigationType::kSameSiteCrossOriginWithOptIn,
      NavigationType::kSameSiteCrossOrigin};
  TestMainFrameRedirection(
      redirections,
      PrerenderFinalStatus::
          kSameSiteCrossOriginRedirectNotOptInInMainFrameNavigation);
}

IN_PROC_BROWSER_TEST_P(PrerenderMainFrameNavigationBrowserTest,
                       Redirection_SameSiteCrossOriginWithOptIn_CrossSite) {
  std::vector<NavigationType> redirections = {
      NavigationType::kSameSiteCrossOriginWithOptIn,
      NavigationType::kCrossSite};
  TestMainFrameRedirection(
      redirections,
      PrerenderFinalStatus::kCrossSiteRedirectInMainFrameNavigation);
}

IN_PROC_BROWSER_TEST_P(
    PrerenderMainFrameNavigationBrowserTest,
    Redirection_SameOrigin_SameSiteCrossOriginWithOptIn_SameOrigin) {
  std::vector<NavigationType> redirections = {
      NavigationType::kSameOrigin,
      NavigationType::kSameSiteCrossOriginWithOptIn,
      NavigationType::kSameOrigin};
  TestMainFrameRedirection(redirections, PrerenderFinalStatus::kActivated);
}

IN_PROC_BROWSER_TEST_P(
    PrerenderMainFrameNavigationBrowserTest,
    Redirection_SameOrigin_SameSiteCrossOriginWithOptIn_SameSiteCrossOriginWithOptIn) {
  std::vector<NavigationType> redirections = {
      NavigationType::kSameOrigin,
      NavigationType::kSameSiteCrossOriginWithOptIn,
      NavigationType::kSameSiteCrossOriginWithOptIn};
  TestMainFrameRedirection(redirections, PrerenderFinalStatus::kActivated);
}

IN_PROC_BROWSER_TEST_P(
    PrerenderMainFrameNavigationBrowserTest,
    Redirection_SameOrigin_SameSiteCrossOriginWithOptIn_SameSiteCrossOrigin) {
  std::vector<NavigationType> redirections = {
      NavigationType::kSameOrigin,
      NavigationType::kSameSiteCrossOriginWithOptIn,
      NavigationType::kSameSiteCrossOrigin};
  TestMainFrameRedirection(
      redirections,
      PrerenderFinalStatus::
          kSameSiteCrossOriginRedirectNotOptInInMainFrameNavigation);
}

IN_PROC_BROWSER_TEST_P(
    PrerenderMainFrameNavigationBrowserTest,
    Redirection_SameOrigin_SameSiteCrossOriginWithOptIn_CrossSite) {
  std::vector<NavigationType> redirections = {
      NavigationType::kSameOrigin,
      NavigationType::kSameSiteCrossOriginWithOptIn,
      NavigationType::kCrossSite};
  TestMainFrameRedirection(
      redirections,
      PrerenderFinalStatus::kCrossSiteRedirectInMainFrameNavigation);
}

IN_PROC_BROWSER_TEST_P(
    PrerenderMainFrameNavigationBrowserTest,
    Redirection_SameSiteCrossOriginWithOptIn_SameOrigin_SameOrigin) {
  std::vector<NavigationType> redirections = {
      NavigationType::kSameSiteCrossOriginWithOptIn,
      NavigationType::kSameOrigin, NavigationType::kSameOrigin};
  TestMainFrameRedirection(redirections, PrerenderFinalStatus::kActivated);
}

IN_PROC_BROWSER_TEST_P(
    PrerenderMainFrameNavigationBrowserTest,
    Redirection_SameSiteCrossOriginWithOptIn_SameOrigin_SameSiteCrossOriginWithOptIn) {
  std::vector<NavigationType> redirections = {
      NavigationType::kSameSiteCrossOriginWithOptIn,
      NavigationType::kSameOrigin,
      NavigationType::kSameSiteCrossOriginWithOptIn};
  TestMainFrameRedirection(redirections, PrerenderFinalStatus::kActivated);
}

IN_PROC_BROWSER_TEST_P(
    PrerenderMainFrameNavigationBrowserTest,
    Redirection_SameSiteCrossOriginWithOptIn_SameOrigin_SameSiteCrossOrigin) {
  std::vector<NavigationType> redirections = {
      NavigationType::kSameSiteCrossOriginWithOptIn,
      NavigationType::kSameOrigin, NavigationType::kSameSiteCrossOrigin};
  TestMainFrameRedirection(
      redirections,
      PrerenderFinalStatus::
          kSameSiteCrossOriginRedirectNotOptInInMainFrameNavigation);
}

IN_PROC_BROWSER_TEST_P(
    PrerenderMainFrameNavigationBrowserTest,
    Redirection_SameSiteCrossOriginWithOptIn_SameOrigin_CrossSite) {
  std::vector<NavigationType> redirections = {
      NavigationType::kSameSiteCrossOriginWithOptIn,
      NavigationType::kSameOrigin, NavigationType::kCrossSite};
  TestMainFrameRedirection(
      redirections,
      PrerenderFinalStatus::kCrossSiteRedirectInMainFrameNavigation);
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MainFrameNavigation_NonHttpUrl) {
  const GURL initial_url = GetUrl("/empty.html");
  const GURL prerendering_url = GetUrl("/empty.html?prerender");
  // Note that local schemes (e.g., data URL) don't work for this test as
  // renderer-initiated navigation to those schemes are blocked by unrelated
  // navigation throttles like BlockedSchemeNavigationThrottle.
  const GURL non_http_url("ftp://example.com/");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), initial_url);

  // Start prerendering.
  PrerenderHostId host_id = AddPrerender(prerendering_url);
  ASSERT_TRUE(host_id);

  // Navigation to a non-http(s) URL on a prerendered page should cancel
  // prerendering.
  TestNavigationManager navigation_observer(web_contents(), non_http_url);
  NavigatePrerenderedPage(host_id, non_http_url);
  ASSERT_TRUE(navigation_observer.WaitForNavigationFinished());
  EXPECT_FALSE(navigation_observer.was_successful());
  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::kInvalidSchemeNavigation);
}

// Regression test for https://crbug.com/1198051
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MainFrameFragmentNavigation) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl =
      GetUrl("/navigation_controller/hash_anchor_with_iframe.html");
  const GURL kAnchorUrl =
      GetUrl("/navigation_controller/hash_anchor_with_iframe.html#Test");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start a prerender.
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);

  // Do a fragment navigation.
  NavigatePrerenderedPage(host_id, kAnchorUrl);
  WaitForPrerenderLoadCompletion(host_id);

  RedirectChainObserver redirect_chain_observer(*shell()->web_contents(),
                                                kAnchorUrl);

  // Activate.
  NavigatePrimaryPage(kPrerenderingUrl);
  // Regression test for https://crbug.com/1211274. Make sure that we don't
  // crash when activating a prerendered page which performed a fragment
  // navigation.
  ASSERT_EQ(1u, redirect_chain_observer.redirect_chain().size());
  EXPECT_EQ(kAnchorUrl, redirect_chain_observer.redirect_chain()[0]);

  // Make sure the render is not dead by doing a same page navigation.
  NavigatePrimaryPage(kAnchorUrl);

  // Make sure we did activate the page and issued no network requests
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
}

// Makes sure that activation on navigation for a pop-up window doesn't happen.
IN_PROC_BROWSER_TEST_P(PrerenderBrowserTestFallbackEnabledDisabled,
                       Activation_PopUpWindow) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  EXPECT_TRUE(AddTestUtilJS(current_frame_host()));

  // Start a prerender.
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);

  // Attempt to activate the prerendered page for a pop-up window. This should
  // fail.
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  EXPECT_EQ("LOADED", EvalJs(web_contents(),
                             JsReplace("open_window($1)", kPrerenderingUrl)));

  if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
    // It uses prefetch ahead of prerender and doesn't fallback to a network
    // request.
    EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  } else {
    // Otherwise, it falls back to a network request.
    EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 2);
  }

  // Activation shouldn't happen, so the prerender host should not be consumed.
  EXPECT_EQ(GetHostForUrl(kPrerenderingUrl), host_id);
}

// Makes sure that activation on navigation for a page that has a pop-up window
// doesn't happen.
IN_PROC_BROWSER_TEST_P(PrerenderBrowserTestFallbackEnabledDisabled,
                       Activation_PageWithPopUpWindow) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  EXPECT_TRUE(AddTestUtilJS(current_frame_host()));

  // Start a prerender.
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender_next");
  AddPrerender(kPrerenderingUrl);
  ASSERT_TRUE(HasHostForUrl(kPrerenderingUrl));

  // Open a pop-up window.
  const GURL kWindowUrl = GetUrl("/empty.html?prerender_window");
  EXPECT_EQ("LOADED",
            EvalJs(web_contents(), JsReplace("open_window($1)", kWindowUrl)));

  // Attempt to activate the prerendered page for the top-level frame. This
  // should fail because the pop-up window exists.
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  NavigatePrimaryPage(kPrerenderingUrl);
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);

  if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
    // It uses prefetch ahead of prerender and doesn't fallback to a network
    // request.
    EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  } else {
    // Otherwise, it falls back to a network request.
    EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 2);
  }

  // The prerender host should be canceled.
  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::kActivatedWithAuxiliaryBrowsingContexts);
}

// This is the same as Activation_PageWithPopUpWindow test but `window.opener`
// will be nullified after it is open. The window loses the communication with
// the opener but it is still treated as an auxiliary context in the browser
// internal, so the activation should fail.
IN_PROC_BROWSER_TEST_P(PrerenderBrowserTestFallbackEnabledDisabled,
                       Activation_PageWithPopUpWindow_OpenerIsNullified) {
  // Navigate to an initial page.
  const GURL initial_url = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  EXPECT_TRUE(AddTestUtilJS(current_frame_host()));

  // Start a prerender.
  const GURL prerendering_url = GetUrl("/empty.html?prerender_next");
  AddPrerender(prerendering_url);
  ASSERT_TRUE(HasHostForUrl(prerendering_url));

  // Open a pop-up window that initially has an opener but it is nullified
  // right away.
  const GURL window_url = GetUrl("/empty.html?prerender_window");
  const std::string kOpenWindowAndNullifyScript = R"(
      const win = window.open($1, '_blank');
      win.opener = null;
  )";
  TestNavigationObserver nav_observer(window_url);
  nav_observer.StartWatchingNewWebContents();
  EXPECT_TRUE(ExecJs(web_contents(),
                     JsReplace(kOpenWindowAndNullifyScript, window_url)));
  nav_observer.WaitForNavigationFinished();

  // Attempt to activate the prerendered page for the top-level frame. This
  // should fail because the pop-up window exists.
  ASSERT_EQ(GetRequestCount(prerendering_url), 1);
  NavigatePrimaryPage(prerendering_url);
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), prerendering_url);

  if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
    // It uses prefetch ahead of prerender and doesn't fallback to a network
    // request.
    EXPECT_EQ(GetRequestCount(prerendering_url), 1);
  } else {
    // Otherwise, it falls back to a network request.
    EXPECT_EQ(GetRequestCount(prerendering_url), 2);
  }

  // The prerender host should be canceled.
  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::kActivatedWithAuxiliaryBrowsingContexts);
}

// Tests that all RenderFrameHostImpls in the prerendering page know the
// prerendering state.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderIframe) {
  TestHostPrerenderingState(GetUrl("/page_with_iframe.html"));
}

// Blank <iframe> is a special case. Tests that the blank iframe knows the
// prerendering state as well.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderBlankIframe) {
  TestHostPrerenderingState(GetUrl("/page_with_blank_iframe.html"));
}

using PrerenderBrowserDeathTest = PrerenderBrowserTest;

// Tests that an inner WebContents cannot be attached in a prerendered page.
// See https://crbug.com/40191159 for details.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserDeathTest,
                       PrerenderCannotHaveInnerContents) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/page_with_blank_iframe.html");
  const GURL kInnerContentsUrl = GetUrl("/empty.html?prerender");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  RenderFrameHostImpl* prerendered_render_frame_host =
      GetPrerenderedMainFrameHost(host_id);

  EXPECT_CHECK_DEATH({
    CreateAndAttachInnerContents(
        prerendered_render_frame_host->child_at(0)->current_frame_host());
  });
}

// Ensure that whether or not a NavigationRequest is for a prerender activation
// is available in WebContentsObserver::DidStartNavigation.
class IsActivationObserver : public WebContentsObserver {
 public:
  IsActivationObserver(WebContents& web_contents, const GURL& url)
      : WebContentsObserver(&web_contents), url_(url) {}
  bool did_navigate() { return did_navigate_; }
  bool was_activation() { return was_activation_; }

 private:
  void DidStartNavigation(NavigationHandle* handle) override {
    if (handle->GetURL() != url_) {
      return;
    }
    did_navigate_ = true;
    was_activation_ = handle->IsPrerenderedPageActivation();
  }

  const GURL url_;
  bool did_navigate_ = false;
  bool was_activation_ = false;
};

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       NavigationRequestIsPrerenderedPageActivation) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");

  test::PrerenderHostObserver prerender_observer(*shell()->web_contents(),
                                                 kPrerenderingUrl);

  // Navigate to an initial page and start a prerender. Note, AddPrerender will
  // wait until the prerendered page has finished navigating.
  {
    ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
    ASSERT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);
    AddPrerender(kPrerenderingUrl);
  }

  IsActivationObserver is_activation_observer(*shell()->web_contents(),
                                              kPrerenderingUrl);

  // Now navigate the primary page to the prerendered URL so that we activate
  // the prerender.
  {
    ASSERT_TRUE(ExecJs(web_contents()->GetPrimaryMainFrame(),
                       JsReplace("location = $1", kPrerenderingUrl)));
    prerender_observer.WaitForActivation();
  }

  // Ensure that WebContentsObservers see the correct value for
  // IsPrerenderedPageActivation in DidStartNavigation.
  ASSERT_TRUE(is_activation_observer.did_navigate());
  EXPECT_TRUE(is_activation_observer.was_activation());
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, ActivationDoesntRunThrottles) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");

  test::PrerenderHostObserver prerender_observer(*shell()->web_contents(),
                                                 kPrerenderingUrl);

  // Navigate to the initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);
  ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));

  NavigationThrottle* throttle = nullptr;
  // This will attempt to insert a throttle that DEFERs the navigation at
  // WillStartRequest into all new navigations.
  ShellContentBrowserClient::Get()
      ->set_create_throttles_for_navigation_callback(base::BindLambdaForTesting(
          [&throttle](NavigationThrottleRegistry& registry) -> void {
            auto throttle_ptr =
                std::make_unique<TestNavigationThrottle>(registry);
            CHECK(!throttle);
            throttle = throttle_ptr.get();
            throttle_ptr->SetResponse(
                TestNavigationThrottle::WILL_START_REQUEST,
                TestNavigationThrottle::SYNCHRONOUS, NavigationThrottle::DEFER);

            registry.AddThrottle(std::move(throttle_ptr));
          }));

  // Start a prerender and ensure that a NavigationThrottle can defer the
  // prerendering navigation. Then resume the navigation so the prerender
  // navigation and load completes.
  {
    TestNavigationManager prerender_manager(shell()->web_contents(),
                                            kPrerenderingUrl);
    AddPrerenderAsync(kPrerenderingUrl);
    ASSERT_TRUE(prerender_manager.WaitForFirstYieldAfterDidStartNavigation());
    ASSERT_NE(throttle, nullptr);

    auto* request =
        NavigationRequest::From(prerender_manager.GetNavigationHandle());
    ASSERT_TRUE(request->IsDeferredForTesting());
    auto* registry = request->GetNavigationThrottleRegistryForTesting();
    ASSERT_EQ(1u, registry->GetDeferringThrottles().size());
    EXPECT_TRUE(registry->GetDeferringThrottles().contains(throttle));
    registry->ResumeProcessingNavigationEvent(throttle);
    throttle = nullptr;
    ASSERT_TRUE(prerender_manager.WaitForNavigationFinished());

    PrerenderHostId host_id = GetHostForUrl(kPrerenderingUrl);
    EXPECT_EQ(GetPrerenderedMainFrameHost(host_id)->GetLastCommittedURL(),
              kPrerenderingUrl);
  }

  // Now navigate the primary page to the prerendered URL so that we activate
  // the prerender. The throttle should not have been registered for the
  // activating navigation.
  {
    NavigatePrimaryPage(kPrerenderingUrl);
    prerender_observer.WaitForActivation();
    EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);
    EXPECT_EQ(throttle, nullptr);
  }
}

// Ensures that if we attempt to open a URL while prerendering with a window
// disposition other than CURRENT_TAB, we fail.
IN_PROC_BROWSER_TEST_P(PrerenderTargetAgnosticBrowserTest, SuppressOpenURL) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender1");
  const GURL kSecondUrl = GetUrl("/empty.html?prerender2");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Start prerendering `kPrerenderingUrl`.
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 0);
  PrerenderHostId host_id = prerender_helper()->AddPrerender(
      kPrerenderingUrl, /*eagerness=*/std::nullopt, GetTargetHint());
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  RenderFrameHost* prerendered_render_frame_host =
      test::PrerenderTestHelper::GetPrerenderedMainFrameHost(
          *prerender_web_contents, host_id);
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  OpenURLParams params(kSecondUrl, Referrer(),
                       prerendered_render_frame_host->GetFrameTreeNodeId(),
                       WindowOpenDisposition::NEW_WINDOW,
                       ui::PAGE_TRANSITION_LINK, true);
  params.initiator_origin =
      prerendered_render_frame_host->GetLastCommittedOrigin();
  params.source_render_process_id =
      prerendered_render_frame_host->GetProcess()->GetDeprecatedID();
  params.source_render_frame_id = prerendered_render_frame_host->GetRoutingID();
  auto* new_web_contents = prerender_web_contents->OpenURL(
      params, /*navigation_handle_callback=*/{});
  EXPECT_EQ(nullptr, new_web_contents);
}

// Tests that `RenderFrameHostImpl::ForEachRenderFrameHostImpl` and
// `WebContentsImpl::ForEachRenderFrameHostImpl` behave correctly when
// prerendering.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, ForEachRenderFrameHostImpl) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  // All frames are same-origin due to prerendering restrictions for
  // cross-origin.
  const GURL kPrerenderingUrl =
      GetUrl("/cross_site_iframe_factory.html?a.test(a.test(a.test),a.test)");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  RenderFrameHostImpl* initiator_render_frame_host = current_frame_host();

  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  RenderFrameHostImpl* prerendered_render_frame_host =
      GetPrerenderedMainFrameHost(host_id);
  RenderFrameHostImpl* rfh_sub_1 =
      prerendered_render_frame_host->child_at(0)->current_frame_host();
  RenderFrameHostImpl* rfh_sub_1_1 =
      rfh_sub_1->child_at(0)->current_frame_host();
  RenderFrameHostImpl* rfh_sub_2 =
      prerendered_render_frame_host->child_at(1)->current_frame_host();

  EXPECT_THAT(CollectAllRenderFrameHosts(prerendered_render_frame_host),
              testing::ElementsAre(prerendered_render_frame_host, rfh_sub_1,
                                   rfh_sub_2, rfh_sub_1_1));

  // When iterating over all RenderFrameHosts in a WebContents, we should see
  // the RFHs of both the primary page and the prerendered page.
  EXPECT_THAT(CollectAllRenderFrameHosts(web_contents_impl()),
              testing::UnorderedElementsAre(initiator_render_frame_host,
                                            prerendered_render_frame_host,
                                            rfh_sub_1, rfh_sub_2, rfh_sub_1_1));

  EXPECT_EQ(nullptr, initiator_render_frame_host->GetParentOrOuterDocument());
  EXPECT_EQ(nullptr, prerendered_render_frame_host->GetParentOrOuterDocument());
  EXPECT_EQ(prerendered_render_frame_host,
            rfh_sub_1->GetParentOrOuterDocument());
  EXPECT_EQ(rfh_sub_1, rfh_sub_1_1->GetParentOrOuterDocument());
  EXPECT_EQ(prerendered_render_frame_host,
            rfh_sub_2->GetParentOrOuterDocument());
  EXPECT_EQ(initiator_render_frame_host,
            initiator_render_frame_host->GetOutermostMainFrame());
  EXPECT_EQ(initiator_render_frame_host,
            initiator_render_frame_host->GetOutermostMainFrameOrEmbedder());
  // The outermost document of a prerendered page is the prerendered main
  // RenderFrameHost, not the primary main RenderFrameHost.
  EXPECT_EQ(prerendered_render_frame_host,
            prerendered_render_frame_host->GetOutermostMainFrame());
  EXPECT_EQ(prerendered_render_frame_host, rfh_sub_1->GetOutermostMainFrame());
  EXPECT_EQ(prerendered_render_frame_host,
            rfh_sub_1_1->GetOutermostMainFrame());
  EXPECT_EQ(prerendered_render_frame_host, rfh_sub_2->GetOutermostMainFrame());
  EXPECT_EQ(prerendered_render_frame_host,
            prerendered_render_frame_host->GetOutermostMainFrameOrEmbedder());
  EXPECT_EQ(prerendered_render_frame_host,
            rfh_sub_1->GetOutermostMainFrameOrEmbedder());
  EXPECT_EQ(prerendered_render_frame_host,
            rfh_sub_1_1->GetOutermostMainFrameOrEmbedder());
  EXPECT_EQ(prerendered_render_frame_host,
            rfh_sub_2->GetOutermostMainFrameOrEmbedder());

  // WebContentsImpl::ForEachFrameTree should include prerenders.
  bool visited_prerender_frame_tree = false;
  web_contents_impl()->ForEachFrameTree([&](FrameTree& frame_tree) {
    if (&frame_tree == prerendered_render_frame_host->frame_tree()) {
      visited_prerender_frame_tree = true;
    }
  });
  EXPECT_TRUE(visited_prerender_frame_tree);
}

// Tests that a prerendering page cannot change the visible URL of the
// corresponding WebContentsImpl instance before activation.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, TabVisibleURL) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/title1.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  ASSERT_EQ(shell()->web_contents()->GetVisibleURL(), kInitialUrl);
  AddPrerender(kPrerenderingUrl);

  // The visible URL should not be modified by the prerendering page.
  EXPECT_EQ(shell()->web_contents()->GetVisibleURL(), kInitialUrl);

  // Activate the prerendered page.
  NavigatePrimaryPage(kPrerenderingUrl);

  // The visible URL should be updated after activation.
  EXPECT_EQ(shell()->web_contents()->GetVisibleURL(), kPrerenderingUrl);
}

// Tests that prerendering will be cancelled if a prerendering page wants to set
// a WebContents-level preferred size.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, CancelOnPreferredSizeChanged) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/title1.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  test::PrerenderHostObserver host_observer(*web_contents_impl(), host_id);

  // Enable PreferredSize mode in the prerendering page. Usually this mode is
  // enabled by extentsions; here we enable it manually. Enabling this mode
  // makes renderers ask the browser to update WebContents-level preferred size,
  // which leads to the cancellation of prerendering.
  RenderFrameHostImpl* prerender_main_frame =
      GetPrerenderedMainFrameHost(host_id);
  prerender_main_frame->GetRenderViewHost()->EnablePreferredSizeMode();

  host_observer.WaitForDestroyed();
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));
  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::kInactivePageRestriction);
  histogram_tester().ExpectUniqueSample(
      "Prerender.CanceledForInactivePageRestriction.DisallowActivationReason."
      "SpeculationRule",
      DisallowActivationReasonId::kContentsPreferredSizeChanged, 1);
}

// Tests that prerendering cannot request the browser to create a popup widget.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, NoPopupWidget) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/title1.html");

  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  RenderFrameHostWrapper prerender_main_frame(
      GetPrerenderedMainFrameHost(host_id));

  std::string create_element_script = R"(
    const widgetElement = document.createElement('input');
    widgetElement.type = 'color';
    widgetElement.id = 'chooser';
    widgetElement.value = '#000000';
    document.body.appendChild(widgetElement);
  )";

  EXPECT_TRUE(ExecJs(prerender_main_frame.get(), create_element_script,
                     EvalJsOptions::EXECUTE_SCRIPT_NO_USER_GESTURE));

  std::string click_element_script = R"(
    const element = document.getElementById('chooser');
    element.click();
  )";

  // It should be ignored because prerendering page do not have user gestures.
  EXPECT_TRUE(ExecJs(prerender_main_frame.get(), click_element_script));

  // Give the test a chance to fail if the click() is not ignored.
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(HasHostForUrl(kPrerenderingUrl));
}

// This throttle cancels prerendering on subframe navigation in prerendered
// pages. The subframe navigation itself will keep proceeding.
class TestPrerenderCancellerSubframeNavigationThrottle
    : public NavigationThrottle {
 public:
  explicit TestPrerenderCancellerSubframeNavigationThrottle(
      NavigationThrottleRegistry& registry)
      : NavigationThrottle(registry),
        navigation_request_(
            NavigationRequest::From(&registry.GetNavigationHandle())) {}

  ThrottleCheckResult WillStartRequest() override {
    // Cancel prerendering if this navigation is for subframes in prerendered
    // pages.
    FrameTreeNode* frame_tree_node = navigation_request_->frame_tree_node();
    if (frame_tree_node->frame_tree().is_prerendering() &&
        !frame_tree_node->IsMainFrame()) {
      PrerenderHost& prerender_host =
          PrerenderHost::GetFromFrameTreeNode(*frame_tree_node);
      PrerenderHostRegistry* prerender_host_registry =
          prerender_host.GetPrerenderedMainFrameHost()
              ->delegate()
              ->GetPrerenderHostRegistry();
      prerender_host_registry->CancelHost(prerender_host.prerender_host_id(),
                                          PrerenderFinalStatus::kMaxValue);
    }
    return PROCEED;
  }

  const char* GetNameForLogging() override {
    return "TestPrerenderCancellerSubframeNavigationThrottle";
  }

 private:
  raw_ptr<NavigationRequest> navigation_request_;
};

// Regression test for https://crbug.com/1323309.
// Tests that subframe navigation in prerendered pages starting while
// PrerenderHost is being destroyed should not crash.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       SubframeNavigationWhilePrerenderHostIsBeingDestroyed) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");
  const GURL kCrossOriginSubframeUrl =
      GetCrossSiteUrl("/empty.html?cross_origin_iframe");

  // Navigate to the initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);
  ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));

  // Start a prerender.
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  test::PrerenderHostObserver observer(*web_contents_impl(), host_id);

  // Insert TestPrerenderCancellerSubframeNavigationThrottle that cancels
  // prerendering on subframe navigation in a prerendered page. This should run
  // before PrerenderSubframeNavigationThrottle.
  ShellContentBrowserClient::Get()
      ->set_create_throttles_for_navigation_callback(base::BindLambdaForTesting(
          [](NavigationThrottleRegistry& registry) -> void {
            registry.AddThrottle(
                std::make_unique<
                    TestPrerenderCancellerSubframeNavigationThrottle>(
                    registry));
          }));

  // Use ExecuteScriptAsync instead of EvalJs as inserted cross-origin iframe
  // navigation should be canceled and script execution cannot wait for the
  // completion.
  RenderFrameHost* prerender_frame_host = GetPrerenderedMainFrameHost(host_id);
  EXPECT_TRUE(AddTestUtilJS(prerender_frame_host));
  ExecuteScriptAsync(prerender_frame_host, JsReplace("add_iframe_async($1)",
                                                     kCrossOriginSubframeUrl));

  // Wait for the cancellation triggered by the throttle. The subframe
  // navigation should not crash during the period.
  observer.WaitForDestroyed();
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kMaxValue);
}

class MojoCapabilityControlTestContentBrowserClient
    : public ContentBrowserTestContentBrowserClient,
      public test::MojoCapabilityControlTestHelper {
 public:
  MojoCapabilityControlTestContentBrowserClient() = default;
  ~MojoCapabilityControlTestContentBrowserClient() override = default;
  MojoCapabilityControlTestContentBrowserClient(
      const MojoCapabilityControlTestContentBrowserClient&) = delete;
  MojoCapabilityControlTestContentBrowserClient& operator=(
      const MojoCapabilityControlTestContentBrowserClient&) = delete;

  // ContentBrowserClient implementation.
  void RegisterBrowserInterfaceBindersForFrame(
      RenderFrameHost* render_frame_host,
      mojo::BinderMapWithContext<RenderFrameHost*>* map) override {
    RegisterTestBrowserInterfaceBindersForFrame(render_frame_host, map);
  }
  void RegisterMojoBinderPoliciesForSameOriginPrerendering(
      MojoBinderPolicyMap& policy_map) override {
    RegisterTestMojoBinderPolicies(policy_map);
  }
};

// Tests that binding requests are handled according to MojoBinderPolicyMap
// during prerendering.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MojoCapabilityControl) {
  MojoCapabilityControlTestContentBrowserClient test_browser_client;

  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/page_with_iframe.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Start a prerender.
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  RenderFrameHost* prerendered_render_frame_host =
      GetPrerenderedMainFrameHost(host_id);
  std::vector<RenderFrameHost*> frames =
      CollectAllRenderFrameHosts(prerendered_render_frame_host);

  // A barrier closure to wait until a deferred interface is granted on all
  // frames.
  base::RunLoop run_loop;
  auto barrier_closure =
      base::BarrierClosure(frames.size(), run_loop.QuitClosure());

  mojo::RemoteSet<mojom::TestInterfaceForDefer> defer_remote_set;
  mojo::RemoteSet<mojom::TestInterfaceForGrant> grant_remote_set;
  for (auto* frame : frames) {
    auto* rfhi = static_cast<RenderFrameHostImpl*>(frame);
    EXPECT_TRUE(rfhi->frame_tree()->is_prerendering());
    EXPECT_EQ(rfhi->lifecycle_state(), LifecycleStateImpl::kPrerendering);
    EXPECT_EQ(rfhi->GetLifecycleState(),
              RenderFrameHost::LifecycleState::kPrerendering);

    mojo::Receiver<blink::mojom::BrowserInterfaceBroker>& bib =
        rfhi->browser_interface_broker_receiver_for_testing();
    blink::mojom::BrowserInterfaceBroker* prerender_broker =
        bib.internal_state()->impl();

    // Try to bind a kDefer interface.
    mojo::Remote<mojom::TestInterfaceForDefer> prerender_defer_remote;
    prerender_broker->GetInterface(
        prerender_defer_remote.BindNewPipeAndPassReceiver());
    // The barrier closure will be called after the deferred interface is
    // granted.
    prerender_defer_remote->Ping(barrier_closure);
    defer_remote_set.Add(std::move(prerender_defer_remote));

    // Try to bind a kGrant interface.
    mojo::Remote<mojom::TestInterfaceForGrant> prerender_grant_remote;
    prerender_broker->GetInterface(
        prerender_grant_remote.BindNewPipeAndPassReceiver());
    grant_remote_set.Add(std::move(prerender_grant_remote));
  }
  // Verify that BrowserInterfaceBrokerImpl defers running binders whose
  // policies are kDefer until the prerendered page is activated.
  EXPECT_EQ(test_browser_client.GetDeferReceiverSetSize(), 0U);
  // Verify that BrowserInterfaceBrokerImpl executes kGrant binders immediately.
  EXPECT_EQ(test_browser_client.GetGrantReceiverSetSize(), frames.size());

  // Activate the prerendered page.
  NavigatePrimaryPage(kPrerenderingUrl);
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);

  // Wait until the deferred interface is granted on all frames.
  run_loop.Run();
  EXPECT_EQ(test_browser_client.GetDeferReceiverSetSize(), frames.size());
}

// Tests that mojo capability control will cancel prerendering if the main frame
// receives a request for a kCancel interface.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       MojoCapabilityControl_CancelMainFrame) {
  MojoCapabilityControlTestContentBrowserClient test_browser_client;

  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/page_with_iframe.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Start a prerender.
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  auto* prerendered_render_frame_host = GetPrerenderedMainFrameHost(host_id);
  mojo::Receiver<blink::mojom::BrowserInterfaceBroker>& bib =
      prerendered_render_frame_host
          ->browser_interface_broker_receiver_for_testing();
  blink::mojom::BrowserInterfaceBroker* prerender_broker =
      bib.internal_state()->impl();

  // Send a kCancel request to cancel prerendering.
  EXPECT_TRUE(HasHostForUrl(kPrerenderingUrl));
  mojo::Remote<mojom::TestInterfaceForCancel> remote;
  prerender_broker->GetInterface(remote.BindNewPipeAndPassReceiver());
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kMojoBinderPolicy);
  // `TestInterfaceForCancel` doesn't have a enum value because it is not used
  // in production, so histogram_tester_ should log
  // PrerenderCancelledInterface::kUnknown here.
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderCancelledInterface.SpeculationRule",
      PrerenderCancelledInterface::kUnknown, 1);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderCancelledUnknownInterface."
      "SpeculationRule",
      InterfaceNameHasher(mojom::TestInterfaceForCancel::Name_), 1);
}

// Tests that mojo capability control will cancel prerendering if child frames
// receive a request for a kCancel interface.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       MojoCapabilityControl_CancelIframe) {
  MojoCapabilityControlTestContentBrowserClient test_browser_client;

  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/page_with_iframe.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Start a prerender.
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  auto* main_render_frame_host = GetPrerenderedMainFrameHost(host_id);
  ASSERT_GE(main_render_frame_host->child_count(), 1U);
  RenderFrameHostImpl* child_render_frame_host =
      main_render_frame_host->child_at(0U)->current_frame_host();
  EXPECT_NE(main_render_frame_host->GetLastCommittedURL(),
            child_render_frame_host->GetLastCommittedURL());
  mojo::Receiver<blink::mojom::BrowserInterfaceBroker>& bib =
      child_render_frame_host->browser_interface_broker_receiver_for_testing();
  blink::mojom::BrowserInterfaceBroker* prerender_broker =
      bib.internal_state()->impl();

  // Send a kCancel request to cancel prerendering.
  EXPECT_TRUE(HasHostForUrl(kPrerenderingUrl));

  mojo::Remote<mojom::TestInterfaceForCancel> remote;
  prerender_broker->GetInterface(remote.BindNewPipeAndPassReceiver());
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));

  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kMojoBinderPolicy);
  // `TestInterfaceForCancel` doesn't have a enum value because it is not used
  // in production, so histogram_tester_ should log
  // PrerenderCancelledInterface::kUnknown here.
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderCancelledInterface.SpeculationRule",
      PrerenderCancelledInterface::kUnknown, 1);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderCancelledUnknownInterface."
      "SpeculationRule",
      InterfaceNameHasher(mojom::TestInterfaceForCancel::Name_), 1);
}

// Tests that mojo capability control will crash the prerender if the browser
// process receives a kUnexpected interface.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       MojoCapabilityControl_HandleUnexpected) {
  MojoCapabilityControlTestContentBrowserClient test_browser_client;

  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender1");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Set up the error handler for bad mojo messages.
  std::string bad_message_error;
  mojo::SetDefaultProcessErrorHandler(
      base::BindLambdaForTesting([&](const std::string& error) {
        EXPECT_FALSE(error.empty());
        EXPECT_TRUE(bad_message_error.empty());
        bad_message_error = error;
      }));

  // Start a prerender.
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  auto* main_render_frame_host = GetPrerenderedMainFrameHost(host_id);

  // Rebind a receiver for testing.
  // mojo::ReportBadMessage must be called within the stack frame derived from
  // mojo IPC calls, so this browser test should call the
  // remote<blink::mojom::BrowserInterfaceBroker>::GetInterface() to test
  // unexpected interfaces. But its remote end is in renderer processes and
  // inaccessible, so the test code has to create another BrowserInterfaceBroker
  // pipe and rebind the receiver end so as to send the request from the remote.
  ASSERT_TRUE(
      main_render_frame_host->ResetBrowserInterfaceBrokerReceiverForTesting());
  mojo::Remote<blink::mojom::BrowserInterfaceBroker> remote_broker;
  mojo::PendingReceiver<blink::mojom::BrowserInterfaceBroker> fake_receiver =
      remote_broker.BindNewPipeAndPassReceiver();
  main_render_frame_host->BindBrowserInterfaceBrokerReceiver(
      std::move(fake_receiver));

  // Send a kUnexpected request.
  EXPECT_TRUE(HasHostForUrl(kPrerenderingUrl));
  mojo::Remote<mojom::TestInterfaceForUnexpected> remote;
  remote_broker->GetInterface(remote.BindNewPipeAndPassReceiver());
  remote_broker.FlushForTesting();
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));
  EXPECT_EQ(bad_message_error,
            "MBPA_BAD_INTERFACE: content.mojom.TestInterfaceForUnexpected");
}

// Regression test for https://crbug.com/1268714 and https://crbug.com/1424250.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MojoCapabilityControl_LoosenMode) {
  MojoCapabilityControlTestContentBrowserClient test_browser_client;

  // Some Android bots run with the site isolation disabled and behave
  // differently on cross-origin iframe creation in a prerendered page. More
  // specifically, when the site isolation is disabled, cross-site iframe will
  // not create a speculative RenderFrameHost, and it results in test failures.
  // To avoid it, this test explicitly runs with the site isolation enabled.
  IsolateAllSitesForTesting(base::CommandLine::ForCurrentProcess());

  GURL initial_url = GetUrl("/empty.html");
  GURL prerendering_url =
      GetUrl("/cross_site_iframe_factory.html?a.test(a.test,a.test)");
  GURL cross_origin_iframe_url = GetCrossSiteUrl("/title1.html");

  // 1. Navigate to an initial page and prerender a page.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  PrerenderHostId host_id = AddPrerender(prerendering_url);
  RenderFrameHostImpl* prerendered_render_frame_host =
      GetPrerenderedMainFrameHost(host_id);

  // 2. Let the first iframe navigate to a cross-origin url. It will create a
  // speculative RFH and the navigation will be deferred.
  TestNavigationManager subframe_navigation_manager(web_contents(),
                                                    cross_origin_iframe_url);
  std::string js = R"(
    const frame = document.getElementById($1);
    frame.contentWindow.location.href = $2;
  )";
  EXPECT_TRUE(ExecJs(prerendered_render_frame_host,
                     JsReplace(js, "child-0", cross_origin_iframe_url.spec())));

  // 3. Wait until the navigation to `cross_origin_iframe_url` is deferred by
  // NavigationThrottle.
  ASSERT_TRUE(
      subframe_navigation_manager.WaitForFirstYieldAfterDidStartNavigation());
  FrameTreeNode* child_ftn =
      FrameTreeNode::GloballyFindByID(
          PrerenderHost::GetFrameTreeNodeIdForId(host_id))
          ->child_at(0);
  NavigationRequest* child_navigation = child_ftn->navigation_request();
  ASSERT_NE(child_navigation, nullptr);
  ASSERT_TRUE(child_navigation->IsDeferredForTesting());

  // 4. Collect all RenderFrameHosts in the frame tree.
  std::vector<RenderFrameHostImpl*> all_prerender_frames;
  size_t count_speculative = 0;
  prerendered_render_frame_host->ForEachRenderFrameHostImplIncludingSpeculative(
      [&](RenderFrameHostImpl* rfh) {
        all_prerender_frames.push_back(rfh);
        count_speculative +=
            (rfh->lifecycle_state() == LifecycleStateImpl::kSpeculative);
      });
  // With feature DeferSpeculativeRFHCreation, the speculative RFH won't be
  // created when the navigation starts.
  if (base::FeatureList::IsEnabled(features::kDeferSpeculativeRFHCreation)) {
    ASSERT_EQ(all_prerender_frames.size(), 3u);
    ASSERT_EQ(count_speculative, 0u);
  } else {
    ASSERT_EQ(all_prerender_frames.size(), 4u);
    ASSERT_EQ(count_speculative, 1u);
  }

  // 5. Renderers attempt to build Mojo connections for kDefer and kGrant
  // interfaces during prerendering. This part simulates them.

  // A barrier closure to wait until a deferred interface is granted on all
  // frames.
  base::RunLoop run_loop;
  auto barrier_closure =
      base::BarrierClosure(all_prerender_frames.size(), run_loop.QuitClosure());

  // Iterate all the frames to bind interfaces.
  mojo::RemoteSet<mojom::TestInterfaceForDefer> defer_remote_set;
  mojo::RemoteSet<mojom::TestInterfaceForGrant> grant_remote_set;
  for (auto* rfhi : all_prerender_frames) {
    mojo::Receiver<blink::mojom::BrowserInterfaceBroker>& bib =
        rfhi->browser_interface_broker_receiver_for_testing();
    blink::mojom::BrowserInterfaceBroker* prerender_broker =
        bib.internal_state()->impl();

    // Try to bind a kDefer interface.
    mojo::Remote<mojom::TestInterfaceForDefer> prerender_defer_remote;
    prerender_broker->GetInterface(
        prerender_defer_remote.BindNewPipeAndPassReceiver());
    // The barrier closure will be called after the deferred interface is
    // granted.
    prerender_defer_remote->Ping(barrier_closure);
    defer_remote_set.Add(std::move(prerender_defer_remote));

    // Try to bind a kGrant interface.
    mojo::Remote<mojom::TestInterfaceForGrant> prerender_grant_remote;
    prerender_broker->GetInterface(
        prerender_grant_remote.BindNewPipeAndPassReceiver());
    grant_remote_set.Add(std::move(prerender_grant_remote));
  }

  // Verify that BrowserInterfaceBrokerImpl defers running binders whose
  // policies are kDefer until the prerendered page is activated.
  EXPECT_EQ(test_browser_client.GetDeferReceiverSetSize(), 0U);
  // Verify that BrowserInterfaceBrokerImpl executes kGrant binders immediately.
  EXPECT_EQ(test_browser_client.GetGrantReceiverSetSize(),
            all_prerender_frames.size());

  // 6. Activate the prerendered page and listen to the DidFinishNavigation
  // event, to ensure the Activate IPC is sent.
  TestActivationManager prerendered_activation_navigation(web_contents(),
                                                          prerendering_url);
  ASSERT_TRUE(ExecJs(web_contents()->GetPrimaryMainFrame(),
                     JsReplace("location = $1", prerendering_url)));
  prerendered_activation_navigation.WaitForNavigationFinished();
  EXPECT_TRUE(prerendered_activation_navigation.was_activated());

  // Make sure all the deferred interfaces are granted after activation. This is
  // a regression test for https://crbug.com/1424250.
  run_loop.Run();
  EXPECT_EQ(test_browser_client.GetDeferReceiverSetSize(),
            all_prerender_frames.size());

  // 7. Renderers attempt to build Mojo connections for kCancel interfaces.
  // This part simulates some subframe documents start sending kCancel
  // interfaces after they know about the activation. It tests the regression
  // situation caught by https://crbug.com/1268714. If some RenderFrameHostImpls
  // are not informed of the activation, this test will crash.
  for (auto* rfhi : all_prerender_frames) {
    mojo::Receiver<blink::mojom::BrowserInterfaceBroker>& bib =
        rfhi->browser_interface_broker_receiver_for_testing();
    blink::mojom::BrowserInterfaceBroker* prerender_broker =
        bib.internal_state()->impl();

    // Send a kCancel request to the browser. This test should not crash.
    mojo::Remote<mojom::TestInterfaceForCancel> remote;
    prerender_broker->GetInterface(remote.BindNewPipeAndPassReceiver());
    remote.FlushForTesting();
  }
}

// Test that prerenders triggered by speculation rules are canceled when a
// background timeout timer is fired.
void PrerenderBrowserTest::TestCancelPrerendersWhenTimeout(
    std::vector<Visibility> visibility_transitions) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderUrl1 = GetUrl("/empty.html?prerender1");
  const GURL kPrerenderUrl2 = GetUrl("/empty.html?prerender2");

  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  AddPrerender(kPrerenderUrl1);
  AddPrerender(kPrerenderUrl2);

  test::PrerenderHostObserver prerender_observer(*web_contents_impl(),
                                                 kPrerenderUrl1);

  PrerenderHostRegistry* registry =
      web_contents_impl()->GetPrerenderHostRegistry();

  // The timers should not start yet when the prerendered page is in the
  // foreground.
  ASSERT_FALSE(registry->GetEmbedderTimerForTesting()->IsRunning());
  ASSERT_FALSE(registry->GetSpeculationRulesTimerForTesting()->IsRunning());

  // Inject mock time task runner.
  auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
  registry->SetTaskRunnerForTesting(task_runner);

  // Changing the visibility state starts/stops the timeout timer.
  for (Visibility visibility : visibility_transitions) {
    switch (visibility) {
      case Visibility::HIDDEN:
        web_contents()->WasHidden();
        ASSERT_TRUE(registry->GetEmbedderTimerForTesting()->IsRunning());
        ASSERT_TRUE(
            registry->GetSpeculationRulesTimerForTesting()->IsRunning());
        break;
      case Visibility::OCCLUDED:
        web_contents()->WasOccluded();
        ASSERT_TRUE(registry->GetEmbedderTimerForTesting()->IsRunning());
        ASSERT_TRUE(
            registry->GetSpeculationRulesTimerForTesting()->IsRunning());
        break;
      case Visibility::VISIBLE:
        web_contents()->WasShown();
        ASSERT_FALSE(registry->GetEmbedderTimerForTesting()->IsRunning());
        ASSERT_FALSE(
            registry->GetSpeculationRulesTimerForTesting()->IsRunning());
        break;
    }
  }

  // The remaining part of this test assumes the timers are running.
  ASSERT_TRUE(registry->GetEmbedderTimerForTesting()->IsRunning());
  ASSERT_TRUE(registry->GetSpeculationRulesTimerForTesting()->IsRunning());

  // Expire the timers.
  task_runner->FastForwardBy(
      PrerenderHostRegistry::kTimeToLiveInBackgroundForSpeculationRules);
  ASSERT_FALSE(registry->GetEmbedderTimerForTesting()->IsRunning());
  ASSERT_FALSE(registry->GetSpeculationRulesTimerForTesting()->IsRunning());

  // The timers should cancel prerendering.
  prerender_observer.WaitForDestroyed();
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kTimeoutBackgrounded, 2);
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       CancelPrerendersWhenTimeout_Hidden) {
  // The timeout timers should start on the hidden state.
  TestCancelPrerendersWhenTimeout({Visibility::HIDDEN});
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       CancelPrerendersWhenTimeout_Occluded) {
  // The timeout timers should start on the occluded state.
  TestCancelPrerendersWhenTimeout({Visibility::OCCLUDED});
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       CancelPrerendersWhenTimeout_OccludedHidden) {
  // The timeout timers should start on the occluded state and then keep running
  // on the hidden state.
  TestCancelPrerendersWhenTimeout({Visibility::OCCLUDED, Visibility::HIDDEN});
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       CancelPrerendersWhenTimeout_OccludedVisibleHidden) {
  // The timeout timers should start on the occluded state, stop on the visible
  // state, and then restart on the hidden state.
  TestCancelPrerendersWhenTimeout(
      {Visibility::OCCLUDED, Visibility::VISIBLE, Visibility::HIDDEN});
}

// Test that a PrerenderHost triggered by embedder is canceled when it times out
// in the background.
void PrerenderBrowserTest::TestCancelOnlyEmbedderTriggeredPrerenderWhenTimeout(
    std::vector<Visibility> visibility_transitions) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderUrl1 = GetUrl("/empty.html?prerender1");
  const GURL kPrerenderUrl2 = GetUrl("/empty.html?prerender2");

  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering by speculation rules.
  AddPrerender(kPrerenderUrl1);

  test::PrerenderHostObserver host_observer(*web_contents_impl(),
                                            kPrerenderUrl2);
  // Start prerendering by embedder.
  std::unique_ptr<PrerenderHandle> prerender_handle =
      AddEmbedderTriggeredPrerenderAsync(kPrerenderUrl2);

  PrerenderHostRegistry* registry =
      web_contents_impl()->GetPrerenderHostRegistry();

  // The timers should not start yet when the prerendered page is in the
  // foreground.
  ASSERT_FALSE(registry->GetEmbedderTimerForTesting()->IsRunning());
  ASSERT_FALSE(registry->GetSpeculationRulesTimerForTesting()->IsRunning());

  // Inject mock time task runner.
  auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
  registry->SetTaskRunnerForTesting(task_runner);

  // Changing the visibility state starts/stops the timeout timer.
  for (Visibility visibility : visibility_transitions) {
    switch (visibility) {
      case Visibility::HIDDEN:
        web_contents()->WasHidden();
        ASSERT_TRUE(registry->GetEmbedderTimerForTesting()->IsRunning());
        ASSERT_TRUE(
            registry->GetSpeculationRulesTimerForTesting()->IsRunning());
        break;
      case Visibility::OCCLUDED:
        web_contents()->WasOccluded();
        ASSERT_TRUE(registry->GetEmbedderTimerForTesting()->IsRunning());
        ASSERT_TRUE(
            registry->GetSpeculationRulesTimerForTesting()->IsRunning());
        break;
      case Visibility::VISIBLE:
        web_contents()->WasShown();
        ASSERT_FALSE(registry->GetEmbedderTimerForTesting()->IsRunning());
        ASSERT_FALSE(
            registry->GetSpeculationRulesTimerForTesting()->IsRunning());
        break;
    }
  }

  // The remaining part of this test assumes the timers are running.
  ASSERT_TRUE(registry->GetEmbedderTimerForTesting()->IsRunning());
  ASSERT_TRUE(registry->GetSpeculationRulesTimerForTesting()->IsRunning());

  // PrerenderHost triggered by embedder should be destroyed and PrerenderHost
  // triggered by speculation rules should be alive, since the timeout value
  // differs depending on the trigger type.
  ASSERT_GT(PrerenderHostRegistry::kTimeToLiveInBackgroundForSpeculationRules,
            PrerenderHostRegistry::kTimeToLiveInBackgroundForEmbedder);
  task_runner->FastForwardBy(
      PrerenderHostRegistry::kTimeToLiveInBackgroundForEmbedder);

  host_observer.WaitForDestroyed();

  // The timer for speculation rules is still running and PrerenderHost for
  // speculation rules is alive.
  ASSERT_FALSE(registry->GetEmbedderTimerForTesting()->IsRunning());
  ASSERT_TRUE(registry->GetSpeculationRulesTimerForTesting()->IsRunning());
  EXPECT_TRUE(GetHostForUrl(kPrerenderUrl1));

  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_"
      "EmbedderSuffixForTest",
      PrerenderFinalStatus::kTimeoutBackgrounded, 1);
  histogram_tester().ExpectBucketCount(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kTimeoutBackgrounded, 0);
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       CancelOnlyEmbedderTriggeredPrerenderWhenTimeout_Hidden) {
  // The timeout timers should start on the hidden state.
  TestCancelOnlyEmbedderTriggeredPrerenderWhenTimeout({Visibility::HIDDEN});
}

IN_PROC_BROWSER_TEST_F(
    PrerenderBrowserTest,
    CancelOnlyEmbedderTriggeredPrerenderWhenTimeout_Occluded) {
  // The timeout timers should start on the occluded state.
  TestCancelOnlyEmbedderTriggeredPrerenderWhenTimeout({Visibility::OCCLUDED});
}

IN_PROC_BROWSER_TEST_F(
    PrerenderBrowserTest,
    CancelOnlyEmbedderTriggeredPrerenderWhenTimeout_OccludedHidden) {
  // The timeout timers should start on the occluded state and then keep running
  // on the hidden state.
  TestCancelOnlyEmbedderTriggeredPrerenderWhenTimeout(
      {Visibility::OCCLUDED, Visibility::HIDDEN});
}

IN_PROC_BROWSER_TEST_F(
    PrerenderBrowserTest,
    CancelOnlyEmbedderTriggeredPrerenderWhenTimeout_OccludedVisibleHidden) {
  // The timeout timers should start on the occluded state, stop on the visible
  // state, and then restart on the hidden state.
  TestCancelOnlyEmbedderTriggeredPrerenderWhenTimeout(
      {Visibility::OCCLUDED, Visibility::VISIBLE, Visibility::HIDDEN});
}

// Test that the timers for PrerenderHost timeout is reset when the
// hidden/occluded page gets visible.
void PrerenderBrowserTest::TestTimerResetWhenPageGoBackToForeground(
    Visibility visibility) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderUrl = GetUrl("/empty.html?prerender");

  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  AddPrerender(kPrerenderUrl);

  PrerenderHostRegistry* registry =
      web_contents_impl()->GetPrerenderHostRegistry();

  // The timers should not start yet when the prerendered page is in the
  // foreground.
  ASSERT_FALSE(registry->GetEmbedderTimerForTesting()->IsRunning());
  ASSERT_FALSE(registry->GetSpeculationRulesTimerForTesting()->IsRunning());

  // Changing the visibility state to HIDDEN/OCCLUDED will not stop prerendering
  // immediately, but start the timers.
  switch (visibility) {
    case Visibility::HIDDEN:
      web_contents()->WasHidden();
      break;
    case Visibility::OCCLUDED:
      web_contents()->WasOccluded();
      break;
    case Visibility::VISIBLE:
      ASSERT_TRUE(false);
      break;
  }

  // The remaining part of this test assumes the timers are running.
  ASSERT_TRUE(registry->GetEmbedderTimerForTesting()->IsRunning());
  ASSERT_TRUE(registry->GetSpeculationRulesTimerForTesting()->IsRunning());

  // The timers should be reset when the HIDDEN/OCCLUDED page goes back to the
  // foreground.
  web_contents()->WasShown();
  ASSERT_FALSE(registry->GetEmbedderTimerForTesting()->IsRunning());
  ASSERT_FALSE(registry->GetSpeculationRulesTimerForTesting()->IsRunning());

  // Activate the prerendered page.
  test::PrerenderHostObserver prerender_observer(*web_contents(),
                                                 GetHostForUrl(kPrerenderUrl));
  NavigatePrimaryPage(kPrerenderUrl);
  prerender_observer.WaitForActivation();
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderUrl);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kActivated, 1);
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       TimerResetWhenPageGoBackToForeground_Hidden) {
  TestTimerResetWhenPageGoBackToForeground(Visibility::HIDDEN);
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       TimerResetWhenPageGoBackToForeground_Occluded) {
  TestTimerResetWhenPageGoBackToForeground(Visibility::OCCLUDED);
}

// Test that a PrerenderHost in a triggered by speculation rules with
// "target=_blank" are canceled when it times out in the background .
void PrerenderBrowserTest::TestCancelPrerenderWithTargetBlankWhenTimeout(
    Visibility visibility) {
  const GURL kInitialUrl = GetUrl("/simple_links.html");
  const GURL kPrerenderUrl = GetUrl("/title2.html");

  // Navigate to an initial page which has a link to `kPrerenderUrl`.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering `kPrerenderUrl`.
  PrerenderHostId host_id = prerender_helper()->AddPrerender(
      kPrerenderUrl, /*eagerness=*/std::nullopt, "_blank");
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  ASSERT_NE(prerender_web_contents, web_contents_impl());
  ExpectWebContentsIsForNewTabPrerendering(*prerender_web_contents);

  PrerenderHostRegistry* registry =
      web_contents_impl()->GetPrerenderHostRegistry();

  // The timers should not start yet when the prerendered page is in the
  // foreground.
  ASSERT_FALSE(registry->GetEmbedderTimerForTesting()->IsRunning());
  ASSERT_FALSE(registry->GetSpeculationRulesTimerForTesting()->IsRunning());

  // Inject mock time task runner.
  auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
  registry->SetTaskRunnerForTesting(task_runner);

  test::PrerenderHostObserver prerender_observer(*prerender_web_contents,
                                                 host_id);

  // Changing the visibility state to HIDDEN/OCCLUDED will not stop prerendering
  // immediately, but start the timers.
  switch (visibility) {
    case Visibility::HIDDEN:
      web_contents()->WasHidden();
      break;
    case Visibility::OCCLUDED:
      web_contents()->WasOccluded();
      break;
    case Visibility::VISIBLE:
      ASSERT_TRUE(false);
      break;
  }

  // The remaining part of this test assumes the timers are running.
  ASSERT_TRUE(registry->GetEmbedderTimerForTesting()->IsRunning());
  ASSERT_TRUE(registry->GetSpeculationRulesTimerForTesting()->IsRunning());

  // Expire the timers.
  task_runner->FastForwardBy(
      PrerenderHostRegistry::kTimeToLiveInBackgroundForSpeculationRules);
  ASSERT_FALSE(registry->GetEmbedderTimerForTesting()->IsRunning());
  ASSERT_FALSE(registry->GetSpeculationRulesTimerForTesting()->IsRunning());

  prerender_observer.WaitForDestroyed();
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kTimeoutBackgrounded, 1);

  // The navigation occurred in a new WebContents, so the original WebContents
  // should still be showing the initial trigger page.
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);
}

IN_PROC_BROWSER_TEST_F(PrerenderTargetHintBrowserTest,
                       CancelPrerenderWithTargetBlankWhenTimeout_Hidden) {
  TestCancelPrerenderWithTargetBlankWhenTimeout(Visibility::HIDDEN);
}

IN_PROC_BROWSER_TEST_F(PrerenderTargetHintBrowserTest,
                       CancelPrerenderWithTargetBlankWhenTimeout_Occluded) {
  TestCancelPrerenderWithTargetBlankWhenTimeout(Visibility::OCCLUDED);
}

enum class SSLPrerenderTestErrorBlockType { kClientCertRequested, kCertError };

std::string SSLPrerenderTestErrorBlockTypeToString(
    const testing::TestParamInfo<
        std::tuple<SSLPrerenderTestErrorBlockType, TriggerType, bool>>& info) {
  return base::StringPrintf(
      "%s_%s_%s",
      std::get<0>(info.param) ==
              SSLPrerenderTestErrorBlockType::kClientCertRequested
          ? "ClientCertRequested"
          : "CertError",
      std::get<1>(info.param) == TriggerType::kSpeculationRules
          ? "SpeculationRules"
          : "EmbedderWithoutPrefetchAheadOfPrerender",
      std::get<2>(info.param) ? "FallbackEnabled" : "FallbackDisabled");
}

class SSLPrerenderBrowserTest
    : public PrerenderBrowserTest,
      public testing::WithParamInterface<
          std::tuple<SSLPrerenderTestErrorBlockType, TriggerType, bool>> {
 public:
  SSLPrerenderBrowserTest() {
    if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
      scoped_feature_list_prerender2_fallback_.InitWithFeaturesAndParameters(
          {
              {
                  features::kPrerender2FallbackPrefetchSpecRules,
                  {
                      {
                          features::
                              kPrerender2FallbackPrefetchUseBlockUntilHeadTimetout
                                  .name,
                          "false",
                      },
                      {
                          features::kPrerender2FallbackPrefetchSchedulerPolicy
                              .name,
                          "NotUse",
                      },
                  },
              },
          },
          {});
    } else {
      scoped_feature_list_prerender2_fallback_.InitWithFeaturesAndParameters(
          {}, {
                  features::kPrerender2FallbackPrefetchSpecRules,
              });
    }
  }

  SSLPrerenderTestErrorBlockType GetSSLPrerenderTestErrorBlockType() const {
    return std::get<0>(GetParam());
  }

  TriggerType GetTriggerType() const { return std::get<1>(GetParam()); }

  bool IsPrerender2FallbackPrefetchSpecRulesEnabled() const {
    return std::get<2>(GetParam());
  }

  bool IsPrefetchAheadOfPrerenderTriggered() const {
    return GetTriggerType() == TriggerType::kSpeculationRules &&
           IsPrerender2FallbackPrefetchSpecRulesEnabled();
  }

  [[nodiscard]]
  std::unique_ptr<PrerenderHandle> TriggerPrerender(const GURL& url) {
    return PrerenderBrowserTest::TriggerPrerender(url, GetTriggerType());
  }

 protected:
  void RequireClientCertsOrSendExpiredCerts() {
    net::SSLServerConfig ssl_config;
    switch (GetSSLPrerenderTestErrorBlockType()) {
      case SSLPrerenderTestErrorBlockType::kClientCertRequested:
        ssl_config.client_cert_type =
            net::SSLServerConfig::ClientCertType::REQUIRE_CLIENT_CERT;
        ResetSSLConfig(net::test_server::EmbeddedTestServer::CERT_TEST_NAMES,
                       ssl_config);
        break;
      case SSLPrerenderTestErrorBlockType::kCertError:
        ResetSSLConfig(net::test_server::EmbeddedTestServer::CERT_EXPIRED,
                       ssl_config);
        break;
    }
  }
  PrerenderFinalStatus GetExpectedFinalStatus() {
    switch (GetSSLPrerenderTestErrorBlockType()) {
      case SSLPrerenderTestErrorBlockType::kClientCertRequested:
        return PrerenderFinalStatus::kClientCertRequested;
      case SSLPrerenderTestErrorBlockType::kCertError:
        return PrerenderFinalStatus::kSslCertificateError;
    }
  }
  int GetExpectedNetError() {
    switch (GetSSLPrerenderTestErrorBlockType()) {
      case SSLPrerenderTestErrorBlockType::kClientCertRequested:
        return net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
      case SSLPrerenderTestErrorBlockType::kCertError:
        return net::ERR_CERT_COMMON_NAME_INVALID;
    }
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_prerender2_fallback_;
};

INSTANTIATE_TEST_SUITE_P(
    /* no prefix */,
    SSLPrerenderBrowserTest,
    testing::Combine(
        testing::Values(SSLPrerenderTestErrorBlockType::kClientCertRequested,
                        SSLPrerenderTestErrorBlockType::kCertError),
        testing::Values(TriggerType::kSpeculationRules,
                        TriggerType::kEmbedderWithoutPrefetchAheadOfPrerender),
        testing::Bool()),
    SSLPrerenderTestErrorBlockTypeToString);

// For a prerendering navigation request, if the server requires a client
// certificate or responds to the request with an invalid certificate, the
// prernedering should be canceled.
IN_PROC_BROWSER_TEST_P(SSLPrerenderBrowserTest,
                       CertificateValidation_Navigation) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Reset the server's config.
  RequireClientCertsOrSendExpiredCerts();

  const GURL kPrerenderingUrl = GetUrl("/title1.html");

  // Start prerendering `kPrerenderingUrl`.
  test::PrerenderHostObserver host_observer(*web_contents(), kPrerenderingUrl);
  auto handle = TriggerPrerender(kPrerenderingUrl);

  // The prerender should be destroyed.
  host_observer.WaitForDestroyed();
  EXPECT_TRUE(prerender_helper()->GetHostForUrl(kPrerenderingUrl).is_null());

  PrerenderFinalStatus final_status = [&]() {
    if (IsPrefetchAheadOfPrerenderTriggered()) {
      return PrerenderFinalStatus::kPrerenderFailedDuringPrefetch;
    } else {
      switch (GetSSLPrerenderTestErrorBlockType()) {
        case SSLPrerenderTestErrorBlockType::kClientCertRequested:
          return PrerenderFinalStatus::kClientCertRequested;
        case SSLPrerenderTestErrorBlockType::kCertError:
          return PrerenderFinalStatus::kSslCertificateError;
      }
    }
  }();
  switch (GetTriggerType()) {
    case TriggerType::kSpeculationRules:
      histogram_tester().ExpectUniqueSample(
          "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
          final_status, 1);
      break;
    case TriggerType::kEmbedderWithoutPrefetchAheadOfPrerender:
      histogram_tester().ExpectUniqueSample(
          "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_"
          "EmbedderSuffixForTest",
          final_status, 1);
      break;
  }
}

// For a prerendering subresource request, if the server requires a client
// certificate or responds to the request with an invalid certificate, the
// prernedering should be canceled.
IN_PROC_BROWSER_TEST_P(SSLPrerenderBrowserTest,
                       CertificateValidation_Subresource) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering `kPrerenderingUrl`.
  const GURL kPrerenderingUrl = GetUrl("/title1.html");
  auto handle = TriggerPrerender(kPrerenderingUrl);
  prerender_helper()->WaitForPrerenderLoadCompletion(*web_contents(),
                                                     kPrerenderingUrl);
  PrerenderHostId host_id =
      prerender_helper()->GetHostForUrl(*web_contents(), kPrerenderingUrl);
  test::PrerenderHostObserver host_observer(*web_contents(), host_id);

  // Reset the server's config.
  RequireClientCertsOrSendExpiredCerts();

  ASSERT_TRUE(prerender_helper()->GetHostForUrl(kPrerenderingUrl));

  // Fetch a subresrouce.
  std::string fetch_subresource_script = R"(
        const imgElement = document.createElement('img');
        imgElement.src = '/load_image/image.png';
        document.body.appendChild(imgElement);
  )";
  std::ignore = ExecJs(prerender_helper()->GetPrerenderedMainFrameHost(host_id),
                       fetch_subresource_script);

  // The prerender should be destroyed.
  host_observer.WaitForDestroyed();
  EXPECT_TRUE(prerender_helper()->GetHostForUrl(kPrerenderingUrl).is_null());

  PrerenderFinalStatus final_status = [&]() {
    switch (GetSSLPrerenderTestErrorBlockType()) {
      case SSLPrerenderTestErrorBlockType::kClientCertRequested:
        return PrerenderFinalStatus::kClientCertRequested;
      case SSLPrerenderTestErrorBlockType::kCertError:
        return PrerenderFinalStatus::kSslCertificateError;
    }
  }();
  switch (GetTriggerType()) {
    case TriggerType::kSpeculationRules:
      histogram_tester().ExpectUniqueSample(
          "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
          final_status, 1);
      break;
    case TriggerType::kEmbedderWithoutPrefetchAheadOfPrerender:
      histogram_tester().ExpectUniqueSample(
          "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_"
          "EmbedderSuffixForTest",
          final_status, 1);
      break;
  }
}

// Tests that prerendering will be cancelled if the server asks for client
// certificates or responds with an expired certificate, even if the main
// resource request is intercepted and sent by a service worker.
IN_PROC_BROWSER_TEST_P(SSLPrerenderBrowserTest,
                       CertificateValidation_SWMainResource) {
  // Register a service worker that intercepts resource requests.
  const GURL kInitialUrl = GetUrl("/workers/service_worker_setup.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  EXPECT_EQ("ok", EvalJs(web_contents(), "setup();"));

  // Reset the server's config.
  RequireClientCertsOrSendExpiredCerts();

  const GURL kPrerenderingUrl = GetUrl("/workers/simple.html?intercept");

  // Start prerendering `kPrerenderingUrl`.
  test::PrerenderHostObserver host_observer(*web_contents(), kPrerenderingUrl);
  auto handle = TriggerPrerender(kPrerenderingUrl);

  // The prerender should be destroyed.
  host_observer.WaitForDestroyed();
  EXPECT_TRUE(prerender_helper()->GetHostForUrl(kPrerenderingUrl).is_null());

  // For the kCertError case, StoragePartitionImpl cannot locate any
  // WebContents. So, the certificate error does not cause any UI changes; it
  // just cancels the url request, and leads to the cancellation of
  // prerendering with kNavigationRequestNetworkError.
  PrerenderFinalStatus final_status = [&]() {
    if (IsPrefetchAheadOfPrerenderTriggered()) {
      return PrerenderFinalStatus::kPrerenderFailedDuringPrefetch;
    } else {
      switch (GetSSLPrerenderTestErrorBlockType()) {
        case SSLPrerenderTestErrorBlockType::kClientCertRequested:
          return PrerenderFinalStatus::kClientCertRequested;
        case SSLPrerenderTestErrorBlockType::kCertError:
          return PrerenderFinalStatus::kNavigationRequestNetworkError;
      }
    }
  }();
  switch (GetTriggerType()) {
    case TriggerType::kSpeculationRules:
      histogram_tester().ExpectUniqueSample(
          "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
          final_status, 1);
      break;
    case TriggerType::kEmbedderWithoutPrefetchAheadOfPrerender:
      histogram_tester().ExpectUniqueSample(
          "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_"
          "EmbedderSuffixForTest",
          final_status, 1);
      break;
  }
}

// Tests that prerendering will be cancelled if the server asks for client
// certificates or responds with an expired certificate, even if the subresource
// request is intercepted by a service worker.
IN_PROC_BROWSER_TEST_P(SSLPrerenderBrowserTest,
                       CertificateValidation_SWSubResource) {
  // Skip the test when the block type is kCertError. With the type, this test
  // times out due to https://crbug.com/1311887.
  // TODO(crbug.com/40220378): Enable the test with kCertError.
  if (GetSSLPrerenderTestErrorBlockType() ==
      SSLPrerenderTestErrorBlockType::kCertError) {
    return;
  }

  // Load an initial page and register a service worker that intercepts
  // resources requests.
  const GURL kInitialUrl = GetUrl("/workers/service_worker_setup.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  EXPECT_EQ("ok", EvalJs(current_frame_host(), "setup();"));

  // Prerender a page.
  const GURL kPrerenderingUrl = GetUrl("/workers/empty.html");
  auto handle = TriggerPrerender(kPrerenderingUrl);
  prerender_helper()->WaitForPrerenderLoadCompletion(*web_contents(),
                                                     kPrerenderingUrl);
  PrerenderHostId host_id =
      prerender_helper()->GetHostForUrl(*web_contents(), kPrerenderingUrl);
  test::PrerenderHostObserver host_observer(*web_contents(), host_id);
  RequireClientCertsOrSendExpiredCerts();

  // Try to fetch a sub resource through the registered service worker. The
  // server should ask for a client certificate or respond with an expired
  // certificate, which leads to the cancellation of prerendering.
  std::string resource_url = GetUrl("/workers/empty.js?intercept").spec();
  std::ignore = ExecJs(prerender_helper()->GetPrerenderedMainFrameHost(host_id),
                       JsReplace("fetch($1);", resource_url));

  // Check the prerender was destroyed.
  host_observer.WaitForDestroyed();
  EXPECT_TRUE(prerender_helper()->GetHostForUrl(kPrerenderingUrl).is_null());

  PrerenderFinalStatus final_status = [&]() {
    switch (GetSSLPrerenderTestErrorBlockType()) {
      case SSLPrerenderTestErrorBlockType::kClientCertRequested:
        return PrerenderFinalStatus::kClientCertRequested;
      case SSLPrerenderTestErrorBlockType::kCertError:
        return PrerenderFinalStatus::kSslCertificateError;
    }
  }();
  switch (GetTriggerType()) {
    case TriggerType::kSpeculationRules:
      histogram_tester().ExpectUniqueSample(
          "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
          final_status, 1);
      break;
    case TriggerType::kEmbedderWithoutPrefetchAheadOfPrerender:
      histogram_tester().ExpectUniqueSample(
          "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_"
          "EmbedderSuffixForTest",
          final_status, 1);
      break;
  }
}

// Prefetch requests should be canceled upon cert validation errors.
// See also the comment at `PrefetchCancelOnAuthRequested_*`.
IN_PROC_BROWSER_TEST_P(SSLPrerenderBrowserTest,
                       PrefetchCertificateValidation_NoServiceWorker) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Reset the server's config.
  RequireClientCertsOrSendExpiredCerts();

  test::TestPrefetchWatcher test_prefetch_watcher;
  const GURL prefetch_url = GetUrl("/title1.html");
  AddPrefetchAsync(prefetch_url);

  test_prefetch_watcher.WaitUntilPrefetchResponseCompleted(
      static_cast<RenderFrameHostImpl*>(
          shell()->web_contents()->GetPrimaryMainFrame())
          ->GetDocumentToken(),
      prefetch_url);

  // Check that the prefetch has failed.
  histogram_tester().ExpectUniqueSample(
      "PrefetchProxy.Prefetch.Mainframe.NetError",
      std::abs(GetExpectedNetError()), 1);
}

IN_PROC_BROWSER_TEST_P(SSLPrerenderBrowserTest,
                       PrefetchCertificateValidation_ServiceWorkerFallback) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  RegisterServiceWorker("/fetch_event_passthrough.js");

  // Reset the server's config.
  RequireClientCertsOrSendExpiredCerts();

  test::TestPrefetchWatcher test_prefetch_watcher;
  const GURL prefetch_url = GetUrl("/title1.html");
  AddPrefetchAsync(prefetch_url);

  test_prefetch_watcher.WaitUntilPrefetchResponseCompleted(
      static_cast<RenderFrameHostImpl*>(
          shell()->web_contents()->GetPrimaryMainFrame())
          ->GetDocumentToken(),
      prefetch_url);

  // Check that the prefetch has failed.
  histogram_tester().ExpectUniqueSample(
      "PrefetchProxy.Prefetch.Mainframe.NetError",
      std::abs(GetExpectedNetError()), 1);
}

IN_PROC_BROWSER_TEST_P(SSLPrerenderBrowserTest,
                       PrefetchCertificateValidation_ServiceWorkerSubresource) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  RegisterServiceWorker("/fetch_event_respond_with_fetch.js");

  // Reset the server's config.
  RequireClientCertsOrSendExpiredCerts();

  test::TestPrefetchWatcher test_prefetch_watcher;
  const GURL prefetch_url = GetUrl("/title1.html");
  AddPrefetchAsync(prefetch_url);

  test_prefetch_watcher.WaitUntilPrefetchResponseCompleted(
      static_cast<RenderFrameHostImpl*>(
          shell()->web_contents()->GetPrimaryMainFrame())
          ->GetDocumentToken(),
      prefetch_url);

  // Check that the prefetch has failed. Unlike other
  // `PrefetchCertificateValidation_*` tests above, as the fetch failure is
  // passed from the ServiceWorker fetch handler's JavaScript to the originating
  // prefetch request in the browser process, the detailed error code isn't
  // exposed and just a general network error is reported.
  histogram_tester().ExpectUniqueSample(
      "PrefetchProxy.Prefetch.Mainframe.NetError", std::abs(net::ERR_FAILED),
      1);
}

// Tests for feature restrictions in prerendered pages =========================

// Tests that window.open() in a prerendering page fails.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, FeatureRestriction_WindowOpen) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start a prerender.
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerendering");
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  auto* prerender_frame = GetPrerenderedMainFrameHost(host_id);
  EXPECT_TRUE(AddTestUtilJS(prerender_frame));

  // Attempt to open a window in the prerendered page. This should fail.
  const GURL kWindowOpenUrl = GetUrl("/empty.html?prerender");

  EXPECT_EQ("FAILED", EvalJs(prerender_frame,
                             JsReplace("open_window($1)", kWindowOpenUrl)));
  EXPECT_EQ(GetRequestCount(kWindowOpenUrl), 0);

  // Opening a window shouldn't cancel prerendering.
  EXPECT_EQ(GetHostForUrl(kPrerenderingUrl), host_id);
}

IN_PROC_BROWSER_TEST_P(PrerenderTargetAgnosticBrowserTest,
                       RenderFrameHostLifecycleState) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  EXPECT_EQ(current_frame_host()->lifecycle_state(),
            LifecycleStateImpl::kActive);

  // Start a prerender.
  PrerenderHostId host_id = prerender_helper()->AddPrerender(
      kPrerenderingUrl, /*eagerness=*/std::nullopt, GetTargetHint());
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);

  // Open an iframe in the prerendered page.
  auto* rfh_a = static_cast<RenderFrameHostImpl*>(
      test::PrerenderTestHelper::GetPrerenderedMainFrameHost(
          *prerender_web_contents, host_id));
  EXPECT_TRUE(AddTestUtilJS(rfh_a));
  EXPECT_EQ("LOADED",
            EvalJs(rfh_a, JsReplace("add_iframe($1)",
                                    GetUrl("/empty.html?prerender"))));
  RenderFrameHostImpl* rfh_b = rfh_a->child_at(0)->current_frame_host();

  // Both rfh_a and rfh_b lifecycle state's should be kPrerendering.
  EXPECT_EQ(LifecycleStateImpl::kPrerendering, rfh_a->lifecycle_state());
  EXPECT_EQ(LifecycleStateImpl::kPrerendering, rfh_b->lifecycle_state());
  EXPECT_FALSE(rfh_a->IsInPrimaryMainFrame());
  EXPECT_FALSE(rfh_b->IsInPrimaryMainFrame());

  // Activate the prerendered page.
  ActivatePrerenderedPage(*prerender_web_contents, kPrerenderingUrl);

  // Both rfh_a and rfh_b lifecycle state's should be kActive after activation.
  EXPECT_EQ(LifecycleStateImpl::kActive, rfh_a->lifecycle_state());
  EXPECT_EQ(LifecycleStateImpl::kActive, rfh_b->lifecycle_state());
  EXPECT_TRUE(rfh_a->IsInPrimaryMainFrame());
  EXPECT_FALSE(rfh_b->IsInPrimaryMainFrame());

  // "Navigation.TimeToActivatePrerender.SpeculationRule" histogram should be
  // recorded on every prerender activation.
  histogram_tester().ExpectTotalCount(
      "Navigation.TimeToActivatePrerender.SpeculationRule", 1u);
}

// Test that prerender activation is deferred and resumed after the ongoing
// (in-flight) main-frame navigation in the prerendering frame tree commits.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       SupportActivationWithOngoingMainFrameNavigation) {
  // Create a HTTP response to control prerendering main-frame navigation.
  net::test_server::ControllableHttpResponse main_document_response(
      embedded_test_server(), "/main_document");

  ASSERT_TRUE(embedded_test_server()->Start());

  const GURL kInitialUrl = embedded_test_server()->GetURL("/empty.html");
  const GURL kPrerenderingUrl =
      embedded_test_server()->GetURL("/main_document");

  // Navigate to an initial page in primary frame tree.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start a prerender, and navigate to a page that doesn't commit navigation.
  {
    test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());
    AddPrerenderAsync(kPrerenderingUrl);
    registry_observer.WaitForTrigger(kPrerenderingUrl);
    EXPECT_TRUE(HasHostForUrl(kPrerenderingUrl));
  }

  PrerenderHostId host_id = GetHostForUrl(kPrerenderingUrl);
  test::PrerenderHostObserver prerender_observer(*web_contents_impl(), host_id);
  EXPECT_FALSE(prerender_observer.was_activated());

  // Defer the activation until the ongoing main-frame navigation in prerender
  // frame tree commits.
  {
    // Start navigation in primary page to kPrerenderingUrl.
    TestActivationManager primary_page_manager(shell()->web_contents(),
                                               kPrerenderingUrl);
    ASSERT_TRUE(ExecJs(shell()->web_contents()->GetPrimaryMainFrame(),
                       JsReplace("location = $1", kPrerenderingUrl)));

    NavigationRequest* request =
        web_contents_impl()->GetPrimaryFrameTree().root()->navigation_request();

    // Wait until the navigation is deferred by CommitDeferringCondition.
    ASSERT_TRUE(primary_page_manager.WaitForBeforeChecks());
    primary_page_manager.ResumeActivation();

    // TODO(bokan): This could be any CommitDeferringCondition, we should have
    // a way to pause on a specific CommitDeferringCondition.
    EXPECT_TRUE(request->IsCommitDeferringConditionDeferredForTesting());

    // The navigation should not have proceeded past NOT_STARTED because the
    // PrerenderCommitDeferringCondition is deferring it.
    EXPECT_EQ(request->state(), NavigationRequest::NOT_STARTED);

    // Complete the prerender response and finish ongoing prerender main frame
    // navigation.
    main_document_response.WaitForRequest();
    main_document_response.Send(net::HTTP_OK, "main_document");
    main_document_response.Done();

    // The URL should still point to the kInitialUrl until the activation is
    // completed.
    EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), kInitialUrl);

    // Make sure that the prerender was not activated yet.
    EXPECT_FALSE(prerender_observer.was_activated());

    primary_page_manager.WaitForNavigationFinished();
    prerender_observer.WaitForActivation();
  }

  // Prerender should be activated and the URL should point to kPrerenderingUrl.
  {
    EXPECT_TRUE(prerender_observer.was_activated());
    EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));
    EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), kPrerenderingUrl);
  }

  // "Navigation.Prerender.ActivationCommitDeferTime" histogram should be
  // recorded as PrerenderCommitDeferringCondition defers the navigation.
  histogram_tester().ExpectTotalCount(
      "Navigation.Prerender.ActivationCommitDeferTime.SpeculationRule", 1u);
}

// TODO(crbug.com/40170624): Now the File System Access API is not
// supported on Android. Enable this browser test after
// https://crbug.com/1011535 is fixed.
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_DeferPrivateOriginFileSystem DISABLED_DeferPrivateOriginFileSystem
#else
#define MAYBE_DeferPrivateOriginFileSystem DeferPrivateOriginFileSystem
#endif
// Tests that access to the origin private file system via the File System
// Access API is deferred until activating the prerendered page.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       MAYBE_DeferPrivateOriginFileSystem) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl =
      GetUrl("/prerender/restriction_file_system.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Make a prerendered page.
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  auto* prerender_render_frame_host = GetPrerenderedMainFrameHost(host_id);

  EXPECT_EQ(
      true,
      ExecJs(prerender_render_frame_host, "accessOriginPrivateFileSystem();",
             EvalJsOptions::EXECUTE_SCRIPT_NO_USER_GESTURE |
                 EvalJsOptions::EXECUTE_SCRIPT_NO_RESOLVE_PROMISES));
  // Run a event loop so the page can fail the test.
  EXPECT_TRUE(ExecJs(prerender_render_frame_host, "runLoop();"));

  // Activate the page.
  NavigatePrimaryPage(kPrerenderingUrl);

  // Wait for the completion of `accessOriginPrivateFileSystem`.
  EXPECT_EQ(true, EvalJs(prerender_render_frame_host, "result;"));
  // Check the event sequence seen in the prerendered page.
  base::ListValue results_list =
      EvalJs(prerender_render_frame_host, "eventsSeen").TakeValue().TakeList();
  std::vector<std::string> eventsSeen;
  for (auto& result : results_list) {
    eventsSeen.push_back(result.GetString());
  }
  EXPECT_THAT(eventsSeen,
              testing::ElementsAreArray(
                  {"accessOriginPrivateFileSystem (prerendering: true)",
                   "prerenderingchange (prerendering: false)",
                   "getDirectory (prerendering: false)"}));
}

// Tests that DocumentUserData object is not cleared on activating a
// prerendered page.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DocumentUserData) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Start a prerender.
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  auto* prerender_render_frame_host = GetPrerenderedMainFrameHost(host_id);

  // Get the DocumentData associated with prerender RenderFrameHost.
  DocumentData::CreateForCurrentDocument(prerender_render_frame_host);
  base::WeakPtr<DocumentData> data =
      DocumentData::GetForCurrentDocument(prerender_render_frame_host)
          ->GetWeakPtr();
  EXPECT_TRUE(data);

  // Activate the prerendered page.
  NavigatePrimaryPage(kPrerenderingUrl);
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);

  // The prerender host should be consumed.
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));

  // DocumentData associated with document shouldn't have been cleared on
  // activating prerendered page.
  base::WeakPtr<DocumentData> data_after_activation =
      DocumentData::GetForCurrentDocument(current_frame_host())->GetWeakPtr();
  EXPECT_TRUE(data_after_activation);

  // Both the instances of DocumentData before and after activation should point
  // to the same object and make sure they aren't null.
  EXPECT_EQ(data_after_activation.get(), data.get());
}

// Tests that executing the GamepadMonitor API on a prerendering before
// navigating to the prerendered page causes cancel prerendering.
// This test cannot be a web test because web tests handles the GamepadMonitor
// interface on the renderer side. See GamepadController::Install().
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, GamepadMonitorCancelPrerendering) {
  const GURL initial_url = GetUrl("/empty.html");
  const GURL prerender_url = GetUrl("/empty.html?prerender");
  GURL url_ping(GetUrl(kPagehideEventPath));

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Make a prerendered page.
  PrerenderHostId host_id = AddPrerender(prerender_url);
  auto* prerender_render_frame_host = GetPrerenderedMainFrameHost(host_id);
  // Call fetchLater() to record that the pagehide event is fired.
  std::string js = R"(
        addEventListener('pagehide', () => {
          fetchLater($1);
        });)";
  EXPECT_TRUE(ExecJs(prerender_render_frame_host, JsReplace(js, url_ping)));
  EXPECT_FALSE(PageHideReceived());

  // Executing `navigator.getGamepads()` to start binding the GamepadMonitor
  // interface.
  std::ignore = EvalJs(prerender_render_frame_host, "navigator.getGamepads()",
                       EvalJsOptions::EXECUTE_SCRIPT_NO_USER_GESTURE);
  // Verify Mojo capability control cancels prerendering.
  EXPECT_FALSE(HasHostForUrl(prerender_url));
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kMojoBinderPolicy);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderCancelledInterface.SpeculationRule",
      PrerenderCancelledInterface::kGamepadMonitor, 1);
  // Non-intentional prerender cancellation should not receive page hide.
  EXPECT_FALSE(PageHideReceived());
}

// Tests that requesting to bind the GamepadMonitor interface after the
// prerenderingchange event dispatched does not cancel prerendering.
// This test cannot be a web test because web tests handles the GamepadMonitor
// interface on the renderer side. See GamepadController::Install().
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, GamepadMonitorAfterNavigation) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/prerender/restriction-gamepad.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Make a prerendered page.
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 0);
  AddPrerender(kPrerenderingUrl);
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 1);

  // Activate the prerendered page to dispatch the prerenderingchange event and
  // run the Gamepad API in the event.
  NavigatePrimaryPage(kPrerenderingUrl);
  EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), kPrerenderingUrl);
  // Wait for the completion of the prerenderingchange event to make sure the
  // API is called.
  EXPECT_EQ(true, EvalJs(shell()->web_contents(), "prerenderingChanged"));
  // The API call shouldn't discard the prerendered page and shouldn't restart
  // navigation.
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
}

// Tests that accessing the clipboard via the execCommand API fails because the
// page does not has any user activation.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, ClipboardByExecCommandFail) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Make a prerendered page.
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  auto* prerender_render_frame_host = GetPrerenderedMainFrameHost(host_id);

  // Access the clipboard and fail.
  EXPECT_EQ(false,
            EvalJs(prerender_render_frame_host, "document.execCommand('copy');",
                   EvalJsOptions::EXECUTE_SCRIPT_NO_USER_GESTURE));
  EXPECT_EQ(false, EvalJs(prerender_render_frame_host,
                          "document.execCommand('paste');",
                          EvalJsOptions::EXECUTE_SCRIPT_NO_USER_GESTURE));
}

void LoadAndWaitForPrerenderDestroyed(test::PrerenderTestHelper* helper,
                                      const GURL prerendering_url,
                                      const std::string& target_hint) {
  test::PrerenderHostCreationWaiter host_creation_waiter;
  helper->AddPrerendersAsync({prerendering_url}, /*eagerness=*/std::nullopt,
                             target_hint);
  PrerenderHostId host_id = host_creation_waiter.Wait();
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  test::PrerenderHostObserver host_observer(*prerender_web_contents, host_id);
  host_observer.WaitForDestroyed();
  if (target_hint == "_blank") {
    EXPECT_FALSE(helper->HasNewTabHandle(host_id));
  } else {
    EXPECT_TRUE(helper->GetHostForUrl(*prerender_web_contents, prerendering_url)
                    .is_null());
  }
}

#if BUILDFLAG(IS_ANDROID)
// On Android the Notification constructor throws an exception regardless of
// whether the page is being prerendered.
// Tests that we will get the exception from the prerendering if the
// prerendering page attempts to use notification.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, NotificationConstructorAndroid) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Make a prerendered page.
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  auto* prerender_render_frame_host = GetPrerenderedMainFrameHost(host_id);

  // Create the Notification and fail.
  EXPECT_EQ(false, EvalJs(prerender_render_frame_host, R"(
    (() => {
      try { new Notification('My Notification'); return true;
      } catch(e) { return false; }
    })();
  )"));
}
#endif  // BUILDFLAG(IS_ANDROID)

// TODO(crbug.com/40184233): Make a WPT when we have a stable way to wait
// cancellation runs.
IN_PROC_BROWSER_TEST_P(PrerenderTargetAgnosticBrowserTest, DownloadByScript) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerendering");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Make a prerendered page.
  test::PrerenderHostCreationWaiter host_creation_waiter;
  prerender_helper()->AddPrerendersAsync(
      {kPrerenderingUrl}, /*eagerness=*/std::nullopt, GetTargetHint());
  PrerenderHostId host_id = host_creation_waiter.Wait();
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  test::PrerenderTestHelper::WaitForPrerenderLoadCompletion(
      *prerender_web_contents, kPrerenderingUrl);

  test::PrerenderHostObserver host_observer(*prerender_web_contents, host_id);
  auto* prerender_host = test::PrerenderTestHelper::GetPrerenderedMainFrameHost(
      *prerender_web_contents, host_id);
  const std::string js_string = R"(
      document.body.innerHTML =
          "<a id='target' download='download-link' href='cache.txt'>here</a>";
      document.getElementById('target').click();
  )";
  ExecuteScriptAsync(prerender_host, js_string);

  host_observer.WaitForDestroyed();
  if (GetTargetHint() == "_blank") {
    EXPECT_FALSE(prerender_helper()->HasNewTabHandle(host_id));
  } else {
    EXPECT_TRUE(prerender_helper()
                    ->GetHostForUrl(*prerender_web_contents, kPrerenderingUrl)
                    .is_null());
  }

  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kDownload);
}

IN_PROC_BROWSER_TEST_P(PrerenderTargetAgnosticBrowserTest,
                       DownloadInMainFrame) {
  const GURL kInitialUrl = GetUrl("/empty.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // TODO(crbug.com/40184233): Make a WPT for the content-disposition WPT test.
  const GURL kDownloadUrl =
      GetUrl("/set-header?Content-Disposition: attachment");

  LoadAndWaitForPrerenderDestroyed(prerender_helper(), kDownloadUrl,
                                   GetTargetHint());

  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kDownload);
}

IN_PROC_BROWSER_TEST_P(PrerenderTargetAgnosticBrowserTest, DownloadInSubframe) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerendering");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Make a prerendered page.
  test::PrerenderHostCreationWaiter host_creation_waiter;
  prerender_helper()->AddPrerendersAsync(
      {kPrerenderingUrl}, /*eagerness=*/std::nullopt, GetTargetHint());
  PrerenderHostId host_id = host_creation_waiter.Wait();
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  test::PrerenderTestHelper::WaitForPrerenderLoadCompletion(
      *prerender_web_contents, kPrerenderingUrl);

  test::PrerenderHostObserver host_observer(*prerender_web_contents, host_id);
  auto* prerender_host = test::PrerenderTestHelper::GetPrerenderedMainFrameHost(
      *prerender_web_contents, host_id);
  EXPECT_TRUE(AddTestUtilJS(prerender_host));

  // TODO(crbug.com/40184233): Make a WPT for the content-disposition WPT test.
  const GURL kDownloadUrl =
      GetUrl("/set-header?Content-Disposition: attachment");
  ExecuteScriptAsync(prerender_host,
                     JsReplace("add_iframe_async($1)", kDownloadUrl));

  host_observer.WaitForDestroyed();
  if (GetTargetHint() == "_blank") {
    EXPECT_FALSE(prerender_helper()->HasNewTabHandle(host_id));
  } else {
    EXPECT_TRUE(prerender_helper()
                    ->GetHostForUrl(*prerender_web_contents, kPrerenderingUrl)
                    .is_null());
  }

  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kDownload);
}

// The viewport meta tag is only enabled on Android.
#if BUILDFLAG(IS_ANDROID)
namespace {

// Used to observe the viewport change in the WebContents.
class TestViewportWebContentsObserver : public WebContentsObserver {
 public:
  TestViewportWebContentsObserver(WebContents* web_contents,
                                  blink::mojom::ViewportFit wanted_value)
      : WebContentsObserver(web_contents), wanted_value_(wanted_value) {}

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

  // WebContentsObserver implementation.
  void ViewportFitChanged(blink::mojom::ViewportFit value) override {
    value_ = value;
    if (waiting_for_wanted_value_ && value == wanted_value_) {
      std::move(waiting_for_wanted_value_).Run();
    }
  }

  void WaitForWantedValue() {
    if (value_.has_value() && value_.value() == wanted_value_) {
      return;
    }
    base::RunLoop loop;
    waiting_for_wanted_value_ = loop.QuitClosure();
    loop.Run();
  }

 private:
  base::OnceClosure waiting_for_wanted_value_;
  std::optional<blink::mojom::ViewportFit> value_;
  const blink::mojom::ViewportFit wanted_value_;
};

}  // namespace

// Tests that the viewport-fit property works well on prerendering page:
// * The property in prerendering page shouldn't affect the primary page.
// * After activating the prerendered page, WebContents's viewport property can
//   be updated.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, ViewportFit) {
  const GURL kInitialUrl = GetUrl("/prerender/viewport.html");
  const GURL kPrerenderingUrl = GetUrl("/prerender/viewport.html?prerendering");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  test::PrerenderHostObserver host_observer(*web_contents(), host_id);
  RenderFrameHostImpl* prerender_rfh = GetPrerenderedMainFrameHost(host_id);
  RenderFrameHostImpl* primary_rfh = web_contents_impl()->GetPrimaryMainFrame();

  {
    // Set viewport-fit property in the primary page and the prerendering page.
    // Prerendering shouldn't be cancelled, nor should its property affect the
    // corresponding WebContents's property.
    TestViewportWebContentsObserver observer(web_contents_impl(),
                                             blink::mojom::ViewportFit::kCover);
    EXPECT_TRUE(ExecJs(prerender_rfh, "setViewportFit('contain')"));
    EXPECT_TRUE(ExecJs(primary_rfh, "setViewportFit('cover')"));
    web_contents_impl()->FullscreenStateChanged(
        primary_rfh, true, blink::mojom::FullscreenOptions::New());
    observer.WaitForWantedValue();
  }
  {
    // After the prerendering page is activated, the WebContents's property
    // should be updated.
    TestViewportWebContentsObserver observer(
        web_contents_impl(), blink::mojom::ViewportFit::kContain);
    prerender_helper()->NavigatePrimaryPage(kPrerenderingUrl);
    web_contents_impl()->FullscreenStateChanged(
        prerender_rfh, true, blink::mojom::FullscreenOptions::New());
    observer.WaitForWantedValue();
  }
  EXPECT_TRUE(host_observer.was_activated());
}
#endif  // BUILDFLAG(IS_ANDROID)

// End: Tests for feature restrictions in prerendered pages ====================

// Tests prerendering for low-end devices.
class PrerenderLowMemoryBrowserTest
    : public PrerenderBrowserTest,
      public ::testing::WithParamInterface<bool> {
 public:
  PrerenderLowMemoryBrowserTest() {
    // Set the value of memory threshold more than the physical memory.  The
    // test will expect that prerendering does not occur.
    std::string memory_threshold = base::NumberToString(
        base::SysInfo::AmountOfPhysicalMemory().InMiB() + 1);
    feature_list_.InitWithFeaturesAndParameters(
        {{blink::features::kPrerender2MemoryControls,
          {{blink::features::kPrerender2MemoryThresholdParamName,
            memory_threshold}}}},
        {});

    if (GetParam()) {
      scoped_feature_list_prerender2_fallback_.InitWithFeaturesAndParameters(
          {
              {
                  features::kPrerender2FallbackPrefetchSpecRules,
                  {
                      {
                          features::
                              kPrerender2FallbackPrefetchUseBlockUntilHeadTimetout
                                  .name,
                          "false",
                      },
                      {
                          features::kPrerender2FallbackPrefetchSchedulerPolicy
                              .name,
                          "NotUse",
                      },
                  },
              },
          },
          {});
    } else {
      scoped_feature_list_prerender2_fallback_.InitWithFeaturesAndParameters(
          {}, {
                  features::kPrerender2FallbackPrefetchSpecRules,
              });
    }
  }

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

INSTANTIATE_TEST_SUITE_P(
    /* no prefix */,
    PrerenderLowMemoryBrowserTest,
    ::testing::Bool());

// Tests that prerendering doesn't run for low-end devices.
IN_PROC_BROWSER_TEST_P(PrerenderLowMemoryBrowserTest, NoPrerender) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");

  // Attempt to prerender.
  test::PrerenderHostRegistryObserver observer(*web_contents_impl());
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  AddPrerenderAsync(kPrerenderingUrl);
  observer.WaitForTrigger(kPrerenderingUrl);

  // It should fail.
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kLowEndDevice);

  // Navigate primary page to flush the metrics.
  NavigatePrimaryPage(kPrerenderingUrl);
  // Cross-check that in case of low memory the eligibility reason points to
  // kLowMemory.
  if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
    ExpectPreloadingAttemptUkm(
        {attempt_ukm_entry_builder().BuildEntry(
             PrimaryPageSourceId(), PreloadingType::kPrefetch,
             PreloadingEligibility::kEligible,
             PreloadingHoldbackStatus::kAllowed,
             PreloadingTriggeringOutcome::kSuccess,
             PreloadingFailureReason::kUnspecified,
             /*accurate=*/true,
             /*ready_time=*/kMockElapsedTime,
             blink::mojom::SpeculationEagerness::kImmediate),
         attempt_ukm_entry_builder().BuildEntry(
             PrimaryPageSourceId(), PreloadingType::kPrerender,
             PreloadingEligibility::kLowMemory,
             PreloadingHoldbackStatus::kUnspecified,
             PreloadingTriggeringOutcome::kUnspecified,
             PreloadingFailureReason::kUnspecified,
             /*accurate=*/true,
             /*ready_time=*/std::nullopt,
             blink::mojom::SpeculationEagerness::kImmediate)});

  } else {
    ExpectPreloadingAttemptUkm({attempt_ukm_entry_builder().BuildEntry(
        PrimaryPageSourceId(), PreloadingType::kPrerender,
        PreloadingEligibility::kLowMemory,
        PreloadingHoldbackStatus::kUnspecified,
        PreloadingTriggeringOutcome::kUnspecified,
        PreloadingFailureReason::kUnspecified,
        /*accurate=*/true,
        /*ready_time=*/std::nullopt,
        blink::mojom::SpeculationEagerness::kImmediate)});
  }
}

namespace {

// Records all the navigation start and finish events until the navigation to
// `target_url` finished.
class SequentialPrerenderObserver : public WebContentsObserver {
 public:
  enum class EventType {
    kStart,
    kFinish,
  };

  SequentialPrerenderObserver(WebContents& web_contents, const GURL& target_url)
      : WebContentsObserver(&web_contents), target_url_(target_url) {}

  const std::vector<std::pair<GURL, EventType>>& events_sequence() const {
    return events_sequence_;
  }

  void WaitForTargetNavigationFinished() {
    if (target_navigation_finished_) {
      return;
    }
    base::RunLoop loop;
    quit_closure_ = loop.QuitClosure();
    loop.Run();
  }

 private:
  void DidStartNavigation(NavigationHandle* handle) override {
    events_sequence_.emplace_back(handle->GetURL(), EventType::kStart);
  }

  void DidFinishNavigation(NavigationHandle* handle) override {
    events_sequence_.emplace_back(handle->GetURL(), EventType::kFinish);
    if (handle->GetURL() != target_url_) {
      return;
    }
    target_navigation_finished_ = true;
    if (quit_closure_) {
      std::move(quit_closure_).Run();
    }
  }

  const GURL target_url_;
  base::OnceClosure quit_closure_;
  bool target_navigation_finished_ = false;

  std::vector<std::pair<GURL, EventType>> events_sequence_;
};

}  // namespace

// Tests that multiple prerenderings should be enqueued and the pending request
// starts right after the previous prerender calls DidFinishNavigation.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, SequentialPrerendering) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  std::vector<GURL> prerender_urls;
  for (int i = 0; i < 3; i++) {
    prerender_urls.push_back(
        GetUrl("/empty.html?prerender" + base::NumberToString(i)));
  }

  SequentialPrerenderObserver observer(*web_contents(), prerender_urls[2]);

  // Insert 3 URLs into the speculation rules at the same time.
  AddPrerendersAsync(prerender_urls);

  // Wait for DidFinishNavigation on the last URL.
  observer.WaitForTargetNavigationFinished();

  // Check if all the prerender requests are handled sequentially.
  std::vector<std::pair<GURL, SequentialPrerenderObserver::EventType>>
      expected_sequence = {
          {prerender_urls[0], SequentialPrerenderObserver::EventType::kStart},
          {prerender_urls[1], SequentialPrerenderObserver::EventType::kStart},
          {prerender_urls[0], SequentialPrerenderObserver::EventType::kFinish},
          {prerender_urls[2], SequentialPrerenderObserver::EventType::kStart},
          {prerender_urls[1], SequentialPrerenderObserver::EventType::kFinish},
          {prerender_urls[2], SequentialPrerenderObserver::EventType::kFinish},
      };
  EXPECT_EQ(observer.events_sequence(), expected_sequence);

  // Make sure if the activation succeeds and other prerender hosts are
  // destroyed.
  std::vector<std::unique_ptr<test::PrerenderHostObserver>> prerender_observers;
  for (int i = 0; i < 3; i++) {
    prerender_observers.push_back(std::make_unique<test::PrerenderHostObserver>(
        *web_contents(), GetHostForUrl(prerender_urls[i])));
  }
  NavigatePrimaryPage(prerender_urls[1]);
  prerender_observers[0]->WaitForDestroyed();
  prerender_observers[1]->WaitForActivation();
  prerender_observers[2]->WaitForDestroyed();

  EXPECT_TRUE(prerender_observers[1]->was_activated());
  EXPECT_FALSE(HasHostForUrl(prerender_urls[1]));
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), prerender_urls[1]);
  histogram_tester().ExpectBucketCount(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kActivated, 1);
  histogram_tester().ExpectBucketCount(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kOtherPrerenderedPageActivated, 2);
}

// Tests that a cancelled request in the pending queue is skipped and the next
// prerender starts.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       SkipCancelledPrerenderAndStartNextPrerender) {
  net::test_server::ControllableHttpResponse response1(
      embedded_test_server(), "/empty.html?prerender1");
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL kInitialUrl = embedded_test_server()->GetURL("/empty.html");
  const GURL kPrerender1 =
      embedded_test_server()->GetURL("/empty.html?prerender1");
  const GURL kPrerender2 =
      embedded_test_server()->GetURL("/empty.html?prerender2");
  const GURL kPrerender3 =
      embedded_test_server()->GetURL("/empty.html?prerender3");

  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());

  // Insert 3 URLs into the speculation rules at the same time. The first
  // prerender should start immediately, and the other two requests enqueued.
  AddPrerendersAsync({kPrerender1, kPrerender2, kPrerender3});

  registry_observer.WaitForTrigger(kPrerender3);
  test::PrerenderHostObserver prerender3_observer(*web_contents(),
                                                  GetHostForUrl(kPrerender3));

  // Stop the first prerendering initial navigation.
  response1.WaitForRequest();

  // Cancel the second prerender, and this cancellation shouldn't prevent the
  // incoming third prerender from starting.
  web_contents_impl()->GetPrerenderHostRegistry()->CancelHost(
      GetHostForUrl(kPrerender2), PrerenderFinalStatus::kDestroyed);

  // Resume the first prerender. The second one doesn't send
  // request as the host has been already destroyed.
  response1.Send(net::HTTP_OK, "");
  response1.Done();

  // Wait for the third prerender completes its initial navigation.
  WaitForPrerenderLoadCompletion(kPrerender3);

  // Activate the third prerender and it should succeed.
  NavigatePrimaryPage(kPrerender3);
  prerender3_observer.WaitForActivation();
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerender3);
  EXPECT_TRUE(prerender3_observer.was_activated());

  // The first prerender is destroyed during activation.
  histogram_tester().ExpectBucketCount(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kOtherPrerenderedPageActivated, 1);

  // The second prerender is destroyed directly.
  histogram_tester().ExpectBucketCount(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kDestroyed, 1);

  // The third prerender is successfully activated.
  histogram_tester().ExpectBucketCount(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kActivated, 1);
}

// Test to make sure that the completion of iframe navigation in a prerendering
// page doesn't start another pending prerender request.
IN_PROC_BROWSER_TEST_F(
    PrerenderBrowserTest,
    IframeNavigationFinishDontDisruptPrerenderNavigationFinish) {
  net::test_server::ControllableHttpResponse response2(
      embedded_test_server(), "/empty.html?prerender2");
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL kInitialUrl = embedded_test_server()->GetURL("/empty.html");
  const GURL kPrerender1 =
      embedded_test_server()->GetURL("/empty.html?prerender1");
  const GURL kPrerender2 =
      embedded_test_server()->GetURL("/empty.html?prerender2");
  const GURL kPrerender3 =
      embedded_test_server()->GetURL("/empty.html?prerender3");
  const GURL kIframeUrl = embedded_test_server()->GetURL("/empty.html?iframe");

  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Insert 3 URLs into the speculation rules at the same time. The first
  // prerender should start immediately.
  AddPrerendersAsync({kPrerender1, kPrerender2, kPrerender3});

  // Stop the second prerendering initial navigation.
  response2.WaitForRequest();

  WaitForPrerenderLoadCompletion(kPrerender1);
  PrerenderHostId host_id = GetHostForUrl(kPrerender1);
  ASSERT_TRUE(host_id);

  // Insert an iframe into the first prerender's main frame host.
  RenderFrameHost* prerender_frame_host = GetPrerenderedMainFrameHost(host_id);
  EXPECT_TRUE(AddTestUtilJS(prerender_frame_host));
  EXPECT_EQ("LOADED", EvalJs(prerender_frame_host,
                             JsReplace("add_iframe($1)", kIframeUrl)));
  RenderFrameHost* child_frame_host = ChildFrameAt(prerender_frame_host, 0);
  ASSERT_NE(child_frame_host, nullptr);
  ASSERT_EQ(child_frame_host->GetLastCommittedURL(), kIframeUrl);

  // Confirm that the third prerender doesn't start even if the iframe
  // navigation within the prerendered main frame has finished.
  PrerenderHost* prerender3_host =
      web_contents_impl()->GetPrerenderHostRegistry()->FindHostByUrlForTesting(
          kPrerender3);
  EXPECT_FALSE(prerender3_host->GetInitialNavigationId().has_value());
}

// Tests that if PrerenderHostRegistry is attempting to activate a pending
// prerender host, it will be successfully canceled with the final status of
// `kActivatedBeforeStarted`.
// TODO(crbug.com/496452657): This test is flaky.
IN_PROC_BROWSER_TEST_P(PrerenderBrowserTestFallbackEnabledDisabled,
                       DISABLED_ActivateBeforePrerenderStarts) {
  net::test_server::ControllableHttpResponse response(embedded_test_server(),
                                                      "/empty.html?prerender1");
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL kInitialUrl = embedded_test_server()->GetURL("/empty.html");
  const GURL kPrerender1 =
      embedded_test_server()->GetURL("/empty.html?prerender1");
  const GURL kPrerender2 =
      embedded_test_server()->GetURL("/empty.html?prerender2");

  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());

  // Insert 2 URLs into the speculation rules at the same time.
  AddPrerendersAsync({kPrerender1, kPrerender2});

  registry_observer.WaitForTrigger(kPrerender2);
  test::PrerenderHostObserver prerender2_observer(*web_contents(),
                                                  GetHostForUrl(kPrerender2));

  // Stop the first prerendering initial navigation.
  response.WaitForRequest();

  // Activate the page with pending prerender.
  NavigatePrimaryPage(kPrerender2);
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerender2);
  EXPECT_FALSE(prerender2_observer.was_activated());

  // The first prerender was destroyed by SpeculationHostImpl.
  histogram_tester().ExpectBucketCount(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kTriggerDestroyed, 1);
  // The second prerender is destroyed since activation navigation is requested
  // while it's still pending.
  histogram_tester().ExpectBucketCount(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kActivatedBeforeStarted, 1);

  ukm::SourceId ukm_source_id = PrimaryPageSourceId();
  if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
    // We don't have a nice way to wait prefetch in this case. Check only UKMs for prerender.
    auto attempt_entries = test_ukm_recorder()->GetEntries(
      Preloading_Attempt::kEntryName, test::kPreloadingAttemptUkmMetrics);
    EXPECT_EQ(attempt_entries.size(), 4);
    std::vector<ukm::TestUkmRecorder::HumanReadableUkmEntry> prerender_entries = {};
    prerender_entries.push_back(attempt_entries[1]);
    prerender_entries.push_back(attempt_entries[3]);
    EXPECT_THAT(prerender_entries,
                testing::UnorderedElementsAreArray({
         attempt_ukm_entry_builder().BuildEntry(
             ukm_source_id, PreloadingType::kPrerender,
             PreloadingEligibility::kEligible,
             PreloadingHoldbackStatus::kAllowed,
             PreloadingTriggeringOutcome::kRunning,
             PreloadingFailureReason::kUnspecified,
             /*accurate=*/false,
             /*ready_time=*/std::nullopt,
             blink::mojom::SpeculationEagerness::kImmediate),
         attempt_ukm_entry_builder().BuildEntry(
             ukm_source_id, PreloadingType::kPrerender,
             PreloadingEligibility::kEligible,
             PreloadingHoldbackStatus::kAllowed,
             PreloadingTriggeringOutcome::kTriggeredButPending,
             PreloadingFailureReason::kUnspecified,
             /*accurate=*/true,
             /*ready_time=*/std::nullopt,
             blink::mojom::SpeculationEagerness::kImmediate)}));
  } else {
    ExpectPreloadingAttemptUkm({
        attempt_ukm_entry_builder().BuildEntry(
            ukm_source_id, PreloadingType::kPrerender,
            PreloadingEligibility::kEligible,
            PreloadingHoldbackStatus::kAllowed,
            PreloadingTriggeringOutcome::kRunning,
            PreloadingFailureReason::kUnspecified,
            /*accurate=*/false,
            /*ready_time=*/std::nullopt,
            blink::mojom::SpeculationEagerness::kImmediate),
        attempt_ukm_entry_builder().BuildEntry(
            ukm_source_id, PreloadingType::kPrerender,
            PreloadingEligibility::kEligible,
            PreloadingHoldbackStatus::kAllowed,
            PreloadingTriggeringOutcome::kTriggeredButPending,
            PreloadingFailureReason::kUnspecified,
            /*accurate=*/true,
            /*ready_time=*/std::nullopt,
            blink::mojom::SpeculationEagerness::kImmediate),
    });
  }
}

// Test that if 1 more than the limit number of URLs are specified in the
// speculation rule, the final one prerender is cancelled.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, ExceedTheRequestNumberLimit) {
  net::test_server::ControllableHttpResponse response(embedded_test_server(),
                                                      "/empty.html?prerender1");
  ASSERT_TRUE(embedded_test_server()->Start());

  const GURL kInitialUrl = embedded_test_server()->GetURL("/empty.html");

  std::vector<GURL> prerender_urls;

  for (int i = 0;
       i <
       PrerenderHostRegistry::kMaxRunningSpeculationRulesImmediatePrerenders +
           1;
       i++) {
    prerender_urls.push_back(embedded_test_server()->GetURL(
        "/empty.html?prerender" + base::NumberToString(i)));
  }

  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());

  // Insert 1 more than the limit URLs into the speculation rules at the same
  // time.
  AddPrerendersAsync(prerender_urls);

  // Stop the first prerendering initial navigation.
  response.WaitForRequest();

  // Wait for the last prerender request will be triggered.
  registry_observer.WaitForTrigger(prerender_urls.back());

  // The last prerender is destroyed since the number of prerender requests
  // from speculation rules exceeds its limit.
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kMaxNumOfRunningImmediatePrerendersExceeded, 1);
}

// Test that the requests from embedder are handled immediately regardless of
// the requests from speculation rules.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       EmbedderPrerenderHandledImmediately) {
  net::test_server::ControllableHttpResponse prerender1_response(
      embedded_test_server(), "/empty.html?prerender1");
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL kInitialUrl = embedded_test_server()->GetURL("/empty.html");
  const GURL kPrerender1 =
      embedded_test_server()->GetURL("/empty.html?prerender1");
  const GURL kPrerender2 =
      embedded_test_server()->GetURL("/empty.html?prerender2");
  const GURL kEmbedderPrerender =
      embedded_test_server()->GetURL("/empty.html?embedder");

  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Insert 2 URLs into the speculation rules at the same time.
  AddPrerendersAsync({kPrerender1, kPrerender2});

  // Stop the first prerender's initial navigation.
  prerender1_response.WaitForRequest();

  // Start prerendering by embedder triggered prerendering; this should start
  // immediately instead of being enqueued.
  std::unique_ptr<PrerenderHandle> prerender_handle =
      AddEmbedderTriggeredPrerender(kEmbedderPrerender);
  EXPECT_TRUE(prerender_handle);

  // Confirm that embedder triggered prerender does not affect the pending
  // prerender triggered by speculation rules.
  PrerenderHost* prerender2_host =
      web_contents_impl()->GetPrerenderHostRegistry()->FindHostByUrlForTesting(
          kPrerender2);
  EXPECT_FALSE(prerender2_host->GetInitialNavigationId());

  // Also confirm the remaining request triggered by speculation rules can
  // resume if the first prerender finish its navigation, to make sure the
  // prioritized embedder request doesn't break conditions of other requests.
  prerender1_response.Send(net::HTTP_OK, "");
  prerender1_response.Done();
  WaitForPrerenderLoadCompletion(kPrerender2);
  EXPECT_TRUE(HasHostForUrl(kPrerender2));

  // Activate the embedder triggered prerender.
  test::PrerenderHostObserver embedder_observer(
      *web_contents(), GetHostForUrl(kEmbedderPrerender));
  prerender_helper()->NavigatePrimaryPageAsync(
      kEmbedderPrerender,
      ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
                                ui::PAGE_TRANSITION_FROM_ADDRESS_BAR));

  embedder_observer.WaitForActivation();
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kEmbedderPrerender);
  EXPECT_TRUE(embedder_observer.was_activated());
}

// Tests that if the running prerender is cancelled by
// PrerenderHostRegistry::CancelHost(), the next pending prerender starts its
// navigation.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       RunningHostCancellationStartPendingPrerender) {
  net::test_server::ControllableHttpResponse response(embedded_test_server(),
                                                      "/empty.html?prerender1");
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL kInitialUrl = embedded_test_server()->GetURL("/empty.html");
  const GURL kPrerender1 =
      embedded_test_server()->GetURL("/empty.html?prerender1");
  const GURL kPrerender2 =
      embedded_test_server()->GetURL("/empty.html?prerender2");

  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());

  // Insert 2 URLs into the speculation rules at the same time.
  AddPrerendersAsync({kPrerender1, kPrerender2});

  registry_observer.WaitForTrigger(kPrerender2);
  test::PrerenderHostObserver prerender2_observer(*web_contents(),
                                                  GetHostForUrl(kPrerender2));

  // Stop the first prerendering initial navigation.
  response.WaitForRequest();

  // Cancel the running prerender. The next pending prerender should start upon
  // this cancellation.
  web_contents_impl()->GetPrerenderHostRegistry()->CancelHost(
      GetHostForUrl(kPrerender1), PrerenderFinalStatus::kDestroyed);
  WaitForPrerenderLoadCompletion(kPrerender2);

  // Activate the page with the prerender that was pending.
  NavigatePrimaryPage(kPrerender2);
  prerender2_observer.WaitForActivation();
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerender2);
  EXPECT_TRUE(prerender2_observer.was_activated());

  // The first prerender should be manually destroyed.
  histogram_tester().ExpectBucketCount(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kDestroyed, 1);
  // The second prerender should be successfully activated.
  histogram_tester().ExpectBucketCount(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kActivated, 1);
}

// Tests that if the running prerender is cancelled by
// PrerenderHostRegistry::CancelHosts(), the next pending prerender
// starts its navigation.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       SpeculationRulesUpdateStartPendingPrerender) {
  net::test_server::ControllableHttpResponse response(embedded_test_server(),
                                                      "/empty.html?prerender1");
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL kInitialUrl = embedded_test_server()->GetURL("/empty.html");
  const GURL kPrerender1 =
      embedded_test_server()->GetURL("/empty.html?prerender1");
  const GURL kPrerender2 =
      embedded_test_server()->GetURL("/empty.html?prerender2");

  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());

  // Insert 2 URLs into the speculation rules in order. The prerender for
  // `kPrerender1` should start first.
  std::string script = R"(
                        let sc = document.createElement('script');
                        sc.type = 'speculationrules';
                        sc.id = $1;
                        sc.textContent = JSON.stringify({
                          prerender: [
                            {source: "list", urls: [$2]}
                          ]
                        });
                        document.head.appendChild(sc);
                        )";
  ASSERT_TRUE(ExecJs(web_contents_impl()->GetPrimaryMainFrame(),
                     JsReplace(script, "prerender1", kPrerender1)));
  ASSERT_TRUE(ExecJs(web_contents_impl()->GetPrimaryMainFrame(),
                     JsReplace(script, "prerender2", kPrerender2)));

  registry_observer.WaitForTrigger(kPrerender2);
  test::PrerenderHostObserver prerender2_observer(*web_contents(),
                                                  GetHostForUrl(kPrerender2));

  // Stop the first prerendering initial navigation.
  response.WaitForRequest();

  // Delete the first speculation rule. This speculation rules removal invokes
  // the PrerenderHostRegistry::CancelHosts(), and the next pending
  // prerender should start upon the cancellation.
  ASSERT_TRUE(ExecJs(web_contents_impl()->GetPrimaryMainFrame(),
                     "document.querySelector('#prerender1').remove()"));
  WaitForPrerenderLoadCompletion(kPrerender2);

  // Activate the page with the prerender that was pending.
  NavigatePrimaryPage(kPrerender2);
  prerender2_observer.WaitForActivation();
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerender2);
  EXPECT_TRUE(prerender2_observer.was_activated());

  // The first prerender should be cancelled by the trigger.
  histogram_tester().ExpectBucketCount(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kSpeculationRuleRemoved, 1);
  // The second prerender should be successfully activated.
  histogram_tester().ExpectBucketCount(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kActivated, 1);
}

#if BUILDFLAG(IS_FUCHSIA)
#define MAYBE_PreloadingTriggeringOutcomeForPendingPrerender \
  DISABLED_PreloadingTriggeringOutcomeForPendingPrerender
#else
#define MAYBE_PreloadingTriggeringOutcomeForPendingPrerender \
  PreloadingTriggeringOutcomeForPendingPrerender
#endif
// Test that a pending prerender should have the
// `PreloadingTriggeringOutcome::kTriggeredButPending`.
IN_PROC_BROWSER_TEST_P(PrerenderBrowserTestFallbackEnabledDisabled,
                       MAYBE_PreloadingTriggeringOutcomeForPendingPrerender) {
  net::test_server::ControllableHttpResponse response1(
      embedded_test_server(), "/empty.html?prerender1");
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL kInitialUrl = embedded_test_server()->GetURL("/empty.html");
  const GURL kPrerender1 =
      embedded_test_server()->GetURL("/empty.html?prerender1");
  const GURL kPrerender2 =
      embedded_test_server()->GetURL("/empty.html?prerender2");

  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());

  // Insert 2 URLs into the speculation rules at the same time.
  AddPrerendersAsync({kPrerender1, kPrerender2});
  registry_observer.WaitForTrigger(kPrerender2);

  // Stop the first prerendering initial navigation.
  response1.WaitForRequest();

  // The pending host should have
  // `PreloadingTriggeringOutcome::kTriggeredButPending`.
  PrerenderHost* prerender2_host =
      web_contents_impl()->GetPrerenderHostRegistry()->FindHostByUrlForTesting(
          kPrerender2);
  auto* preloading_attempt_impl = static_cast<PreloadingAttemptImpl*>(
      prerender2_host->preloading_attempt().get());
  EXPECT_EQ(test::PreloadingAttemptAccessor(preloading_attempt_impl)
                .GetTriggeringOutcome(),
            PreloadingTriggeringOutcome::kTriggeredButPending);

  NavigationHandleObserver activation_observer(web_contents(), kPrerender1);
  test::PrerenderHostObserver prerender1_observer(*web_contents(),
                                                  GetHostForUrl(kPrerender1));

  // Defer the activation until the ongoing initial navigation in prerender
  // frame tree commits.
  TestActivationManager primary_page_manager(shell()->web_contents(),
                                             kPrerender1);
  ASSERT_TRUE(ExecJs(shell()->web_contents()->GetPrimaryMainFrame(),
                     JsReplace("location = $1", kPrerender1)));

  NavigationRequest* request =
      web_contents_impl()->GetPrimaryFrameTree().root()->navigation_request();

  // Wait until the activation navigation is deferred by
  // CommitDeferringCondition.
  ASSERT_TRUE(primary_page_manager.WaitForBeforeChecks());
  primary_page_manager.ResumeActivation();

  // Confirm that the activation navigation is deferred.
  EXPECT_TRUE(request->IsCommitDeferringConditionDeferredForTesting());

  // Complete the first prerender response and finish its initial navigation.
  response1.Send(net::HTTP_OK, "");
  response1.Done();

  primary_page_manager.WaitForNavigationFinished();
  prerender1_observer.WaitForActivation();

  // The prerender1 should succeed in activation and have kSuccess outcome. The
  // prerender2 should start right after the activation but get destroyed by the
  // change of the primary page soon, so it should result in the kRunning
  // outcome.
  ukm::SourceId ukm_source_id = activation_observer.next_page_ukm_source_id();
  if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
    ExpectPreloadingAttemptUkm({
        // kPrerender1 successful activation (prefetch part).
        attempt_ukm_entry_builder().BuildEntry(
            ukm_source_id, PreloadingType::kPrefetch,
            PreloadingEligibility::kEligible,
            PreloadingHoldbackStatus::kAllowed,
            PreloadingTriggeringOutcome::kSuccess,
            PreloadingFailureReason::kUnspecified,
            /*accurate=*/true,
            /*ready_time=*/kMockElapsedTime,
            blink::mojom::SpeculationEagerness::kImmediate),
        // kPrerender1 successful activation (prerender part).
        attempt_ukm_entry_builder().BuildEntry(
            ukm_source_id, PreloadingType::kPrerender,
            PreloadingEligibility::kEligible,
            PreloadingHoldbackStatus::kAllowed,
            PreloadingTriggeringOutcome::kSuccess,
            PreloadingFailureReason::kUnspecified,
            /*accurate=*/true,
            /*ready_time=*/kMockElapsedTime,
            blink::mojom::SpeculationEagerness::kImmediate),
        // kPrerender2 cancellation (prefetch part).
        attempt_ukm_entry_builder().BuildEntry(
            ukm_source_id, PreloadingType::kPrefetch,
            PreloadingEligibility::kEligible,
            PreloadingHoldbackStatus::kAllowed,
            PreloadingTriggeringOutcome::kReady,
            PreloadingFailureReason::kUnspecified,
            /*accurate=*/false,
            /*ready_time=*/kMockElapsedTime,
            blink::mojom::SpeculationEagerness::kImmediate),
        // kPrerender2 cancellation (prerender part).
        attempt_ukm_entry_builder().BuildEntry(
            ukm_source_id, PreloadingType::kPrerender,
            PreloadingEligibility::kEligible,
            PreloadingHoldbackStatus::kAllowed,
            PreloadingTriggeringOutcome::kTriggeredButPending,
            PreloadingFailureReason::kUnspecified,
            /*accurate=*/false,
            /*ready_time=*/std::nullopt,
            blink::mojom::SpeculationEagerness::kImmediate),
    });
  } else {
    ExpectPreloadingAttemptUkm({
        attempt_ukm_entry_builder().BuildEntry(
            ukm_source_id, PreloadingType::kPrerender,
            PreloadingEligibility::kEligible,
            PreloadingHoldbackStatus::kAllowed,
            PreloadingTriggeringOutcome::kSuccess,
            PreloadingFailureReason::kUnspecified,
            /*accurate=*/true,
            /*ready_time=*/kMockElapsedTime,
            blink::mojom::SpeculationEagerness::kImmediate),
        attempt_ukm_entry_builder().BuildEntry(
            ukm_source_id, PreloadingType::kPrerender,
            PreloadingEligibility::kEligible,
            PreloadingHoldbackStatus::kAllowed,
            PreloadingTriggeringOutcome::kTriggeredButPending,
            PreloadingFailureReason::kUnspecified,
            /*accurate=*/false,
            /*ready_time=*/std::nullopt,
            blink::mojom::SpeculationEagerness::kImmediate),
    });
  }
}

// Test that when the running prerender is destroyed due to the activation of
// another already prerendered page, other pending prerender's outcome is
// recorded as `kTriggeredButPending`.
//
// Rationale for `PrerenderBrowserTestFallbackDisabled`: This test triggers
// multiple prerenders. It's hard to control both prefetch/prerender states, as
// they progress asynchronously. The aspect to be tested is unrelated to
// prefetch ahead of prerender.
IN_PROC_BROWSER_TEST_F(
    PrerenderBrowserTestFallbackDisabled,
    PreloadingTriggeringOutcomeForStartingPrerenderBeforeDestruction) {
  net::test_server::ControllableHttpResponse response2(
      embedded_test_server(), "/empty.html?prerender2");
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL kInitialUrl = embedded_test_server()->GetURL("/empty.html");
  const GURL kPrerender1 =
      embedded_test_server()->GetURL("/empty.html?prerender1");
  const GURL kPrerender2 =
      embedded_test_server()->GetURL("/empty.html?prerender2");
  const GURL kPrerender3 =
      embedded_test_server()->GetURL("/empty.html?prerender3");

  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());

  // Insert 3 URLs into the speculation rules at the same time.
  AddPrerendersAsync({kPrerender1, kPrerender2, kPrerender3});
  registry_observer.WaitForTrigger(kPrerender3);
  test::PrerenderHostObserver prerender1_observer(*web_contents(),
                                                  GetHostForUrl(kPrerender1));

  // Stop the second prerendering initial navigation.
  response2.WaitForRequest();

  NavigationHandleObserver activation_observer(web_contents(), kPrerender1);

  // Activate prerender1. The trigger should destroy all the other prerender
  // hosts.
  NavigatePrimaryPage(kPrerender1);
  prerender1_observer.WaitForActivation();
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerender1);
  EXPECT_TRUE(prerender1_observer.was_activated());

  ukm::SourceId ukm_source_id = activation_observer.next_page_ukm_source_id();
  ExpectPreloadingAttemptUkm({
      attempt_ukm_entry_builder().BuildEntry(
          ukm_source_id, PreloadingType::kPrerender,
          PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed,
          PreloadingTriggeringOutcome::kSuccess,
          PreloadingFailureReason::kUnspecified,
          /*accurate=*/true,
          /*ready_time=*/kMockElapsedTime,
          blink::mojom::SpeculationEagerness::kImmediate),
      attempt_ukm_entry_builder().BuildEntry(
          ukm_source_id, PreloadingType::kPrerender,
          PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed,
          PreloadingTriggeringOutcome::kRunning,
          PreloadingFailureReason::kUnspecified,
          /*accurate=*/false,
          /*ready_time=*/std::nullopt,
          blink::mojom::SpeculationEagerness::kImmediate),
      attempt_ukm_entry_builder().BuildEntry(
          ukm_source_id, PreloadingType::kPrerender,
          PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed,
          PreloadingTriggeringOutcome::kTriggeredButPending,
          PreloadingFailureReason::kUnspecified,
          /*accurate=*/false,
          /*ready_time=*/std::nullopt,
          blink::mojom::SpeculationEagerness::kImmediate),
  });
}

// Test that all the prerender hosts except the one to be activated are
// cancelled regardless of their status right after the PrerenderHostRegistry
// receives the activation request.
//
// Rationale for `PrerenderBrowserTestFallbackDisabled`: This test triggers
// multiple prerenders. It's hard to control both prefetch/prerender states, as
// they progress asynchronously. The aspect to be tested is unrelated to
// prefetch ahead of prerender.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestFallbackDisabled,
                       CancelAllPrerenderUponActivationRequestArrival) {
  net::test_server::ControllableHttpResponse response3(
      embedded_test_server(), "/empty.html?prerender3");
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL kInitialUrl = embedded_test_server()->GetURL("/empty.html");

  // This test only makes sense if we don't hit the limit.
  ASSERT_GE(
      PrerenderHostRegistry::kMaxRunningSpeculationRulesImmediatePrerenders, 4);

  std::vector<GURL> prerender_urls;
  for (int i = 1; i <= 4; i++) {
    prerender_urls.push_back(embedded_test_server()->GetURL(
        "/empty.html?prerender" + base::NumberToString(i)));
  }

  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());

  // Insert 4 URLs into the speculation rules at the same time.
  AddPrerendersAsync(prerender_urls);
  registry_observer.WaitForTrigger(prerender_urls[3]);

  // Stop the third prerendering initial navigation.
  response3.WaitForRequest();

  NavigationHandleObserver activation_observer(web_contents(),
                                               prerender_urls[0]);
  test::PrerenderHostObserver prerender1_observer(
      *web_contents(), GetHostForUrl(prerender_urls[0]));

  // Defer the activation of the first prerender.
  TestActivationManager primary_page_manager(shell()->web_contents(),
                                             prerender_urls[0]);
  ASSERT_TRUE(ExecJs(shell()->web_contents()->GetPrimaryMainFrame(),
                     JsReplace("location = $1", prerender_urls[0])));

  ASSERT_TRUE(primary_page_manager.WaitForBeforeChecks());
  NavigationRequest* request =
      web_contents_impl()->GetPrimaryFrameTree().root()->navigation_request();
  ASSERT_EQ(request->GetURL(), prerender_urls[0]);

  // Confirm that all the other prerender hosts are successfully cancelled.
  for (auto& url : prerender_urls) {
    if (url == prerender_urls[0]) {
      continue;
    }
    EXPECT_TRUE(GetHostForUrl(url).is_null());
  }

  // Resume the activation.
  primary_page_manager.ResumeActivation();
  prerender1_observer.WaitForActivation();

  // When the PrerenderHostRegistry received the activation request, the status
  // of each prerender host is:
  // 1. Ready for activation,
  // 2. Ready for activation,
  // 3. Running,
  // 4. Pending.
  // We activated the first prerender, so all the other prerender hosts should
  // be cancelled with each corresponding status.
  ukm::SourceId ukm_source_id = activation_observer.next_page_ukm_source_id();
  ExpectPreloadingAttemptUkm({
      attempt_ukm_entry_builder().BuildEntry(
          ukm_source_id, PreloadingType::kPrerender,
          PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed,
          PreloadingTriggeringOutcome::kSuccess,
          PreloadingFailureReason::kUnspecified,
          /*accurate=*/true,
          /*ready_time=*/kMockElapsedTime,
          blink::mojom::SpeculationEagerness::kImmediate),
      attempt_ukm_entry_builder().BuildEntry(
          ukm_source_id, PreloadingType::kPrerender,
          PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed,
          PreloadingTriggeringOutcome::kReady,
          PreloadingFailureReason::kUnspecified,
          /*accurate=*/false,
          /*ready_time=*/kMockElapsedTime,
          blink::mojom::SpeculationEagerness::kImmediate),
      attempt_ukm_entry_builder().BuildEntry(
          ukm_source_id, PreloadingType::kPrerender,
          PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed,
          PreloadingTriggeringOutcome::kRunning,
          PreloadingFailureReason::kUnspecified,
          /*accurate=*/false,
          /*ready_time=*/std::nullopt,
          blink::mojom::SpeculationEagerness::kImmediate),
      attempt_ukm_entry_builder().BuildEntry(
          ukm_source_id, PreloadingType::kPrerender,
          PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed,
          PreloadingTriggeringOutcome::kTriggeredButPending,
          PreloadingFailureReason::kUnspecified,
          /*accurate=*/false,
          /*ready_time=*/std::nullopt,
          blink::mojom::SpeculationEagerness::kImmediate),
  });
}

// Tests that prerendering in a new tab multiple times and activating one of
// them succeed.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MultipleNewTabPrerendering) {
  GURL initial_url = GetUrl("/simple_links.html");
  std::vector<GURL> prerendering_urls = {GetUrl("/title2.html"),
                                         GetUrl("/title2.html?2"),
                                         GetUrl("/title2.html?3")};

  // Navigate to an initial page which has a link to `prerendering_urls[0]`.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Start prerendering.
  std::vector<PrerenderHostId> prerender_host_ids;
  std::vector<WebContents*> prerender_web_contents_list;
  for (const GURL& prerendering_url : prerendering_urls) {
    PrerenderHostId host_id = prerender_helper()->AddPrerender(
        prerendering_url, /*eagerness=*/std::nullopt, "_blank");

    EXPECT_FALSE(std::ranges::contains(prerender_host_ids, host_id));
    prerender_host_ids.push_back(host_id);

    // Make sure that prerendering in a new tab creates new WebContentsImpl, not
    // reuse existing WebContentsImpl.
    auto* prerender_web_contents =
        test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
    ASSERT_TRUE(prerender_web_contents);
    EXPECT_NE(prerender_web_contents, web_contents_impl());
    ExpectWebContentsIsForNewTabPrerendering(*prerender_web_contents);
    EXPECT_FALSE(std::ranges::contains(prerender_web_contents_list,
                                       prerender_web_contents));
    prerender_web_contents_list.push_back(prerender_web_contents);
  }

  // Click the link to prerendering_urls[0]. This should activate
  // prerender_host_ids[0].
  test::PrerenderHostObserver prerender_observer(
      *prerender_web_contents_list[0], prerender_host_ids[0]);
  const std::string kLinkClickScript = R"(
      clickSameSiteNewWindowLink();
  )";
  EXPECT_TRUE(ExecJs(web_contents(), kLinkClickScript));
  prerender_observer.WaitForActivation();
  EXPECT_EQ(prerender_web_contents_list[0]->GetLastCommittedURL(),
            prerendering_urls[0]);
  EXPECT_TRUE(prerender_observer.was_activated());

  // prerendering_urls[0] was consumed for activation, but others were not.
  EXPECT_FALSE(
      HasHostForUrl(*prerender_web_contents_list[0], prerendering_urls[0]));
  EXPECT_TRUE(
      HasHostForUrl(*prerender_web_contents_list[1], prerendering_urls[1]));
  EXPECT_TRUE(
      HasHostForUrl(*prerender_web_contents_list[2], prerendering_urls[2]));

  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kActivated);

  // The navigation occurred in a new WebContents, so the original WebContents
  // should still be showing the initial trigger page.
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), initial_url);
}

// Test that the prerender request is handled and stored regardless of the
// initial visibility of the current tab, and when the current tab goes
// background (in the cases where HIDDEN or OCCLUDED is specified by
// `next_visibility`) then the prerender sequence is terminated, and when
// the current tab gets visible then we start the next prerender if we have some
// pending prerender hosts. Note that if the initial visibility is background,
// there is still one prerender allowed to be running.
void PrerenderBrowserTest::TestSequentialPrerenderingVisibilityStateTransition(
    Visibility initial_visibility,
    Visibility next_visibility) {
  net::test_server::ControllableHttpResponse response1(
      embedded_test_server(), "/empty.html?prerender1");
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL initial_url = embedded_test_server()->GetURL("/empty.html");
  const GURL prerender_url1 =
      embedded_test_server()->GetURL("/empty.html?prerender1");
  const GURL prerender_url2 =
      embedded_test_server()->GetURL("/empty.html?prerender2");

  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Set the initial visibility.
  switch (initial_visibility) {
    case Visibility::VISIBLE:
      web_contents()->WasShown();
      break;
    case Visibility::HIDDEN:
      web_contents()->WasHidden();
      break;
    case Visibility::OCCLUDED:
      web_contents()->WasOccluded();
      break;
  }

  test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());

  // Insert 2 URLs into the speculation rules at the same time.
  AddPrerendersAsync({prerender_url1, prerender_url2});
  registry_observer.WaitForTrigger(prerender_url2);

  test::PrerenderHostObserver prerender2_observer(
      *web_contents(), GetHostForUrl(prerender_url2));

  // Stop the first prerendering initial navigation.
  response1.WaitForRequest();

  // Change the visibility status to HIDDEN/OCCLUDED.
  switch (next_visibility) {
    case Visibility::HIDDEN:
      web_contents()->WasHidden();
      break;
    case Visibility::OCCLUDED:
      web_contents()->WasOccluded();
      break;
    case Visibility::VISIBLE:
      // The timing of `next_visibility`=Visibility::VISIBLE is delayed until a
      // later point.
      break;
  }

  // Complete the first prerender response and finish its initial navigation.
  // This shouldn't start the pending prerender.
  response1.Send(net::HTTP_OK, "");
  response1.Done();
  WaitForPrerenderLoadCompletion(prerender_url1);

  // Check the prerender host is already ready.
  PrerenderHost* prerender_host =
      web_contents_impl()->GetPrerenderHostRegistry()->FindHostByUrlForTesting(
          prerender_url1);
  auto* preloading_attempt_impl = static_cast<PreloadingAttemptImpl*>(
      prerender_host->preloading_attempt().get());
  EXPECT_EQ(test::PreloadingAttemptAccessor(preloading_attempt_impl)
                .GetTriggeringOutcome(),
            PreloadingTriggeringOutcome::kReady);

  // Check the next prerender host is still pending.
  PrerenderHost* prerender2_host =
      web_contents_impl()->GetPrerenderHostRegistry()->FindHostByUrlForTesting(
          prerender_url2);
  auto* preloading_attempt_impl2 = static_cast<PreloadingAttemptImpl*>(
      prerender2_host->preloading_attempt().get());
  EXPECT_EQ(test::PreloadingAttemptAccessor(preloading_attempt_impl2)
                .GetTriggeringOutcome(),
            PreloadingTriggeringOutcome::kTriggeredButPending);

  // The hidden/occluded page gets back to the foreground. The next pending
  // prerender should start. The case of `next_visibility`=Visibility::VISIBLE
  // is delayed until now.
  web_contents()->WasShown();
  WaitForPrerenderLoadCompletion(prerender_url2);

  // Check the next prerender host is already ready.
  auto* preloading_attempt_impl2_2 = static_cast<PreloadingAttemptImpl*>(
      prerender2_host->preloading_attempt().get());
  EXPECT_EQ(test::PreloadingAttemptAccessor(preloading_attempt_impl2_2)
                .GetTriggeringOutcome(),
            PreloadingTriggeringOutcome::kReady);

  // Activate the second prerender.
  NavigatePrimaryPage(prerender_url2);
  prerender2_observer.WaitForActivation();
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), prerender_url2);
  EXPECT_TRUE(prerender2_observer.was_activated());
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestFallbackDisabled,
                       PrerenderInBackground_InitialyVisible_Hidden) {
  TestSequentialPrerenderingVisibilityStateTransition(Visibility::VISIBLE,
                                                      Visibility::HIDDEN);
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestFallbackDisabled,
                       PrerenderInBackground_InitialyVisible_Occluded) {
  TestSequentialPrerenderingVisibilityStateTransition(Visibility::VISIBLE,
                                                      Visibility::OCCLUDED);
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestFallbackDisabled,
                       PrerenderInBackground_InitialyOccluded_Hidden) {
  TestSequentialPrerenderingVisibilityStateTransition(Visibility::OCCLUDED,
                                                      Visibility::HIDDEN);
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestFallbackDisabled,
                       PrerenderInBackground_InitialyOccluded_Occluded) {
  TestSequentialPrerenderingVisibilityStateTransition(Visibility::OCCLUDED,
                                                      Visibility::OCCLUDED);
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestFallbackDisabled,
                       PrerenderInBackground_InitialyHidden_Hidden) {
  TestSequentialPrerenderingVisibilityStateTransition(Visibility::HIDDEN,
                                                      Visibility::HIDDEN);
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestFallbackDisabled,
                       PrerenderInBackground_InitialyHidden_Occluded) {
  TestSequentialPrerenderingVisibilityStateTransition(Visibility::HIDDEN,
                                                      Visibility::OCCLUDED);
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestFallbackDisabled,
                       PrerenderInBackground_InitialyHidden_Visible) {
  TestSequentialPrerenderingVisibilityStateTransition(Visibility::HIDDEN,
                                                      Visibility::VISIBLE);
}

// TODO(b/40234240): Flaky on win.
//
// Rationale for `PrerenderBrowserTestFallbackDisabled`: If
// `kPreneder2FallbackPrefetchSpecRules` is enabled, prefetch ahead of prerender
// is triggered and it blocks prerender. Prefetch in a background tab is not
// scheduled. So, the prerender is never unblocked. Skip the test as it is not
// testable.
#if BUILDFLAG(IS_WIN)
#define MAYBE_PrerenderWhenInitiatorInBackground_Queue_Processing \
  DISABLED_PrerenderWhenInitiatorInBackground_Queue_Processing
#else
#define MAYBE_PrerenderWhenInitiatorInBackground_Queue_Processing \
  PrerenderWhenInitiatorInBackground_Queue_Processing
#endif
IN_PROC_BROWSER_TEST_F(
    PrerenderBrowserTestFallbackDisabled,
    MAYBE_PrerenderWhenInitiatorInBackground_Queue_Processing) {
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL initial_url = embedded_test_server()->GetURL("/empty.html");
  const GURL prerender_url1 =
      embedded_test_server()->GetURL("/empty.html?prerender1");
  const GURL prerender_url2 =
      embedded_test_server()->GetURL("/empty.html?prerender2");

  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  web_contents()->WasHidden();

  test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());

  // Insert 2 URLs into the speculation rules at the same time.
  AddPrerendersAsync({prerender_url1, prerender_url2});
  registry_observer.WaitForTrigger(prerender_url2);
  WaitForPrerenderLoadCompletion(prerender_url1);

  // Check the prerender host is already ready.
  PrerenderHost* prerender_host =
      web_contents_impl()->GetPrerenderHostRegistry()->FindHostByUrlForTesting(
          prerender_url1);
  auto* preloading_attempt_impl = static_cast<PreloadingAttemptImpl*>(
      prerender_host->preloading_attempt().get());
  EXPECT_EQ(test::PreloadingAttemptAccessor(preloading_attempt_impl)
                .GetTriggeringOutcome(),
            PreloadingTriggeringOutcome::kReady);

  // Check the next prerender host is still pending.
  PrerenderHost* prerender2_host =
      web_contents_impl()->GetPrerenderHostRegistry()->FindHostByUrlForTesting(
          prerender_url2);
  auto* preloading_attempt_impl2 = static_cast<PreloadingAttemptImpl*>(
      prerender2_host->preloading_attempt().get());
  EXPECT_EQ(test::PreloadingAttemptAccessor(preloading_attempt_impl2)
                .GetTriggeringOutcome(),
            PreloadingTriggeringOutcome::kTriggeredButPending);

  // Test if prerender_url1 is cancelled, the prerender host of prerender_url2
  // should be processed.
  web_contents_impl()->GetPrerenderHostRegistry()->CancelHost(
      GetHostForUrl(prerender_url1), PrerenderFinalStatus::kDestroyed);
  WaitForPrerenderLoadCompletion(prerender_url2);

  // Check the next prerender host is already ready.
  test::PrerenderHostObserver prerender2_observer(
      *web_contents(), GetHostForUrl(prerender_url2));
  auto* preloading_attempt_impl2_2 = static_cast<PreloadingAttemptImpl*>(
      prerender2_host->preloading_attempt().get());
  EXPECT_EQ(test::PreloadingAttemptAccessor(preloading_attempt_impl2_2)
                .GetTriggeringOutcome(),
            PreloadingTriggeringOutcome::kReady);

  // Activate the second prerender.
  web_contents()->WasShown();
  NavigatePrimaryPage(prerender_url2);
  prerender2_observer.WaitForActivation();
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), prerender_url2);
  EXPECT_TRUE(prerender2_observer.was_activated());
}

IN_PROC_BROWSER_TEST_P(PrerenderBrowserTestFallbackEnabledDisabled,
                       IsInactiveAndDisallowActivationCancelsPrerendering) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Start prerendering `kPrerenderingUrl`.
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  auto* prerender_render_frame_host = GetPrerenderedMainFrameHost(host_id);

  // Invoke IsInactiveAndDisallowActivation for the prerendered document.
  EXPECT_EQ(prerender_render_frame_host->lifecycle_state(),
            RenderFrameHostImpl::LifecycleStateImpl::kPrerendering);
  EXPECT_TRUE(prerender_render_frame_host->IsInactiveAndDisallowActivation(
      DisallowActivationReasonId::kForTesting));

  // The prerender host for the URL should be destroyed as
  // RenderFrameHost::IsInactiveAndDisallowActivation cancels prerendering in
  // LifecycleStateImpl::kPrerendering state.
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));

  // Cancelling the prerendering disables the activation. The navigation
  // should issue a request again.
  NavigatePrimaryPage(kPrerenderingUrl);

  if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
    // It uses prefetch ahead of prerender and doesn't fallback to a network
    // request.
    EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  } else {
    // Otherwise, it falls back to a network request.
    EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 2);
  }

  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::kInactivePageRestriction);
  histogram_tester().ExpectUniqueSample(
      "Prerender.CanceledForInactivePageRestriction.DisallowActivationReason."
      "SpeculationRule",
      DisallowActivationReasonId::kForTesting, 1);
}

// Make sure input events are routed to the primary FrameTree not the prerender
// one. See https://crbug.com/1197136
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, InputRoutedToPrimaryFrameTree) {
  const GURL kInitialUrl = GetUrl("/prerender/simple_prerender.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  WaitForPrerenderLoadCompletion(kPrerenderingUrl);

  // Touch / click the link and wait for the navigation to complete.
  TestNavigationObserver navigation_observer(web_contents());
  SyntheticTapGestureParams params;
  params.gesture_source_type = mojom::GestureSourceType::kTouchInput;
  params.position = GetCenterCoordinatesOfElementWithId(web_contents(), "link");
  web_contents_impl()->GetRenderViewHost()->GetWidget()->QueueSyntheticGesture(
      std::make_unique<SyntheticTapGesture>(params), base::DoNothing());
  navigation_observer.Wait();

  EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), kPrerenderingUrl);
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, VisibilityWhilePrerendering) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(shell()->web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Start prerendering `kPrerenderingUrl`.
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  auto* prerendered_render_frame_host = GetPrerenderedMainFrameHost(host_id);

  // The visibility state must be "hidden" while prerendering.
  auto* rvh = static_cast<RenderViewHostImpl*>(
      prerendered_render_frame_host->GetRenderViewHost());
  EXPECT_EQ(rvh->GetPageLifecycleStateManager()
                ->CalculatePageLifecycleState()
                ->visibility,
            PageVisibilityState::kHidden);
  EXPECT_EQ(prerendered_render_frame_host->GetVisibilityState(),
            PageVisibilityState::kHidden);

  // Activate prerendering page.
  NavigatePrimaryPage(kPrerenderingUrl);

  // The visibility state should be "visible" after activation.
  EXPECT_EQ(rvh->GetPageLifecycleStateManager()
                ->CalculatePageLifecycleState()
                ->visibility,
            PageVisibilityState::kVisible);
  EXPECT_EQ(prerendered_render_frame_host->GetVisibilityState(),
            PageVisibilityState::kVisible);
}

// Tests that prerendering doesn't affect WebContents::GetTitle().
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, TitleWhilePrerendering) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/simple_page.html");
  const std::u16string kInitialTitle(u"title");
  const std::u16string kPrerenderingTitle(u"OK");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  EXPECT_TRUE(ExecJs(shell()->web_contents(),
                     JsReplace("document.title = $1", kInitialTitle)));
  EXPECT_EQ(shell()->web_contents()->GetTitle(), kInitialTitle);

  // Start a prerender to `kPrerenderUrl` that has title `kPrerenderingTitle`.
  ASSERT_TRUE(AddPrerender(kPrerenderingUrl));

  // Make sure that WebContents::GetTitle() returns the current title from the
  // primary page.
  EXPECT_EQ(shell()->web_contents()->GetTitle(), kInitialTitle);

  NavigatePrimaryPage(kPrerenderingUrl);
  EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), kPrerenderingUrl);
  // The title should be updated with the activated page.
  EXPECT_EQ(shell()->web_contents()->GetTitle(), kPrerenderingTitle);
}

// Tests that WebContentsObserver::TitleWasSet is not dispatched when title is
// set during prerendering, but is later dispatched after activation.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, TitleWasSetWithPrerendering) {
  const GURL kInitialUrl = GetUrl("/title2.html");
  const GURL kPrerenderingUrlWithTitle = GetUrl("/simple_page.html");
  const GURL kPrerenderingUrlWithoutTitle = GetUrl("/title1.html");
  const std::u16string kInitialTitle(u"Title Of Awesomeness");
  const std::u16string kPrerenderingTitle(u"OK");

  // Navigate to an initial page; TitleWasSet should be called when page sets
  // its title.
  {
    testing::NiceMock<MockWebContentsObserver> mock_observer(
        shell()->web_contents());
    EXPECT_CALL(mock_observer, TitleWasSet(testing::_));
    ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
    EXPECT_EQ(shell()->web_contents()->GetTitle(), kInitialTitle);
  }

  // Prerender a page; TitleWasSet should not be called despite the page setting
  // a title.
  {
    testing::NiceMock<MockWebContentsObserver> mock_observer(
        shell()->web_contents());
    EXPECT_CALL(mock_observer, TitleWasSet(testing::_)).Times(0);
    ASSERT_TRUE(AddPrerender(kPrerenderingUrlWithTitle));
  }

  // Activate prerendered page; TitleWasSet should now be called.
  {
    testing::NiceMock<MockWebContentsObserver> mock_observer(
        shell()->web_contents());
    EXPECT_CALL(mock_observer, TitleWasSet(testing::_))
        .WillOnce([kPrerenderingTitle](NavigationEntry* entry) {
          EXPECT_EQ(entry->GetTitleForDisplay(), kPrerenderingTitle);
        });
    NavigatePrimaryPage(kPrerenderingUrlWithTitle);
  }

  // Prerender a page without a title and then activate it; TitleWasSet should
  // not be called.
  {
    testing::NiceMock<MockWebContentsObserver> mock_observer(
        shell()->web_contents());
    EXPECT_CALL(mock_observer, TitleWasSet(testing::_)).Times(0);
    ASSERT_TRUE(AddPrerender(kPrerenderingUrlWithoutTitle));
    NavigatePrimaryPage(kPrerenderingUrlWithoutTitle);
  }
}

// Test that the prerender request from embedder to non-HTTP(S) scheme URL
// should fail because `PrerenderNavigationThrottle` discards the request. This
// is a regression test for https://crbug.com/1361210.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, EmbedderPrerenderToNonHttpUrl) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderUrl = GURL("file://example.txt");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(shell()->web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Start prerendering by embedder triggered prerendering.
  std::unique_ptr<PrerenderHandle> prerender_handle =
      AddEmbedderTriggeredPrerenderAsync(kPrerenderUrl);

  // Both the creation of PrerenderHandle and PrerenderHost should fail.
  EXPECT_FALSE(prerender_handle);
  EXPECT_TRUE(GetHostForUrl(kPrerenderUrl).is_null());
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_"
      "EmbedderSuffixForTest",
      PrerenderFinalStatus::kInvalidSchemeNavigation, 1);
}

// Ensures WebContents::OpenURL targeting a frame in a prerendered host will
// successfully navigate that frame.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, OpenURLInPrerenderingFrame) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/page_with_blank_iframe.html");
  const GURL kNewIframeUrl = GetUrl("/simple_page.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(shell()->web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Start prerendering `kPrerenderingUrl`.
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  auto* prerendered_render_frame_host = GetPrerenderedMainFrameHost(host_id);
  auto* child_frame = ChildFrameAt(prerendered_render_frame_host, 0);
  ASSERT_TRUE(child_frame);

  // Navigate the iframe's FrameTreeNode in the prerendering frame tree. This
  // should successfully navigate.
  TestNavigationManager iframe_observer(shell()->web_contents(), kNewIframeUrl);
  shell()->web_contents()->OpenURL(
      OpenURLParams(
          kNewIframeUrl, Referrer(), child_frame->GetFrameTreeNodeId(),
          WindowOpenDisposition::CURRENT_TAB, ui::PAGE_TRANSITION_AUTO_SUBFRAME,
          /*is_renderer_initiated=*/false),
      /*navigation_handle_callback=*/{});
  ASSERT_TRUE(iframe_observer.WaitForNavigationFinished());
  EXPECT_TRUE(iframe_observer.was_committed());
  EXPECT_TRUE(iframe_observer.was_successful());
  EXPECT_EQ(child_frame->GetLastCommittedURL(), kNewIframeUrl);
}

// Ensure that WebContentsObserver::DidFailLoad is not invoked and cancels
// prerendering when invoked on the prerendering main frame.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DidFailLoadCancelsPrerendering) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/page_with_iframe.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Initialize a MockWebContentsObserver and ensure that DidFailLoad is not
  // invoked inside prerender frame tree.
  testing::NiceMock<MockWebContentsObserver> observer(shell()->web_contents());
  EXPECT_CALL(observer, DidFailLoad(testing::_, testing::_, testing::_))
      .Times(0);

  // Start a prerender.
  PrerenderHostId prerender_host_id = AddPrerender(kPrerenderingUrl);
  RenderFrameHostImpl* prerender_frame_host =
      GetPrerenderedMainFrameHost(prerender_host_id);

  // Trigger DidFailLoad, this should cancel prerendering.
  prerender_frame_host->DidFailLoadWithError(kPrerenderingUrl, net::ERR_FAILED);

  // The prerender host for the URL should be deleted as DidFailLoad cancels
  // prerendering.
  test::PrerenderHostObserver prerender_observer(*web_contents(),
                                                 kPrerenderingUrl);
  TestNavigationManager navigation_observer(shell()->web_contents(),
                                            kPrerenderingUrl);
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));

  // Now navigate the primary page to the prerendered URL. Cancelling the
  // prerender disables the activation due to DidFailLoad.
  ASSERT_TRUE(ExecJs(web_contents()->GetPrimaryMainFrame(),
                     JsReplace("location = $1", kPrerenderingUrl)));
  ASSERT_TRUE(navigation_observer.WaitForNavigationFinished());
  EXPECT_FALSE(prerender_observer.was_activated());

  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kDidFailLoad);
}

class DidFailLoadWebContentsObserver : public WebContentsObserver {
 public:
  explicit DidFailLoadWebContentsObserver(WebContents* web_contents)
      : WebContentsObserver(web_contents) {}
  bool WasDidFailLoadCalled() { return was_did_fail_load_called_; }
  int GetErrorCode() const { return error_code_; }
  const GURL& GetUrl() const { return url_; }

 private:
  void DidFailLoad(RenderFrameHost* rfh,
                   const GURL& url,
                   int error_code) override {
    was_did_fail_load_called_ = true;
    url_ = url;
    error_code_ = error_code;

    EXPECT_FALSE(rfh->IsErrorDocument());
    EXPECT_TRUE(rfh->IsInLifecycleState(
        RenderFrameHost::LifecycleState::kPrerendering));
  }

  bool was_did_fail_load_called_ = false;
  int error_code_ = net::OK;
  GURL url_;
};

// Ensure that RenderFrameHost::DidFailLoad on subframes don't cancel
// prerendering. This happens when JavaScript calls `window.stop()` in a
// frame, for instance.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       DidFailLoadSubframesDoesNotCancelPrerendering) {
  DidFailLoadWebContentsObserver observer(web_contents());

  TestHostPrerenderingState(GetUrl("/page_with_stop_iframe.html"));

  EXPECT_TRUE(observer.WasDidFailLoadCalled());
  EXPECT_EQ(net::ERR_ABORTED, observer.GetErrorCode());
  EXPECT_EQ(GetUrl("/stop.html"), observer.GetUrl());
}

// Ensure that RenderFrameHost::DidFailLoad on the main frame cancels
// prerendering. This happens when JavaScript calls `window.stop()` in the
// main frame, for instance.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       DidFailLoadMainFrameCancelsPrerendering) {
  DidFailLoadWebContentsObserver observer(web_contents());

  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/stop.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start a prerender and wait until it is canceled.
  test::PrerenderHostObserver host_observer(*web_contents_impl(),
                                            kPrerenderingUrl);
  AddPrerenderAsync(kPrerenderingUrl);
  host_observer.WaitForDestroyed();

  // DidFailLoad callback should not be called.
  EXPECT_FALSE(observer.WasDidFailLoadCalled());

  // Prerendering should be canceled for kDidFailLoad.
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kDidFailLoad);
}

// Ensures WebContents::OpenURL with a cross-origin URL targeting a frame in a
// prerendered host will successfully navigate that frame, though it should be
// deferred until activation.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       OpenURLCrossOriginInPrerenderingFrame) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/page_with_blank_iframe.html");
  const GURL kNewIframeUrl = GetCrossSiteUrl("/simple_page.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(shell()->web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Start prerendering `kPrerenderingUrl`.
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  auto* prerendered_render_frame_host = GetPrerenderedMainFrameHost(host_id);
  auto* child_frame = ChildFrameAt(prerendered_render_frame_host, 0);
  ASSERT_TRUE(child_frame);

  TestNavigationManager iframe_observer(shell()->web_contents(), kNewIframeUrl);

  // Navigate the iframe's FrameTreeNode in the prerendering frame tree. This
  // should successfully navigate but the navigation will be deferred until the
  // prerendering page is activated.
  {
    shell()->web_contents()->OpenURL(
        OpenURLParams(kNewIframeUrl, Referrer(),
                      child_frame->GetFrameTreeNodeId(),
                      WindowOpenDisposition::CURRENT_TAB,
                      ui::PAGE_TRANSITION_AUTO_SUBFRAME,
                      /*is_renderer_initiated=*/false),
        /*navigation_handle_callback=*/{});
    ASSERT_TRUE(iframe_observer.WaitForFirstYieldAfterDidStartNavigation());
    NavigationRequest* request =
        static_cast<NavigationRequest*>(iframe_observer.GetNavigationHandle());
    EXPECT_EQ(request->state(), NavigationRequest::WILL_START_REQUEST);
    EXPECT_TRUE(request->IsDeferredForTesting());
  }

  // Now navigate the primary page to the prerendered URL so that we activate
  // the prerender.
  {
    test::PrerenderHostObserver prerender_observer(*web_contents(),
                                                   kPrerenderingUrl);
    ASSERT_TRUE(ExecJs(web_contents()->GetPrimaryMainFrame(),
                       JsReplace("location = $1", kPrerenderingUrl)));
    prerender_observer.WaitForActivation();
  }

  // Now that we're activated, the iframe navigation should be able to finish.
  // Ensure the navigation completes in the iframe.
  {
    ASSERT_TRUE(iframe_observer.WaitForNavigationFinished());
    child_frame = ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0);
    ASSERT_TRUE(child_frame);
    EXPECT_EQ(child_frame->GetLastCommittedURL(), kNewIframeUrl);
  }
}

// Test that the main frame navigation after the initial prerender navigation
// when the activation has already started doesn't cancel an ongoing
// prerendering.
// Testing steps:
// 1. prerender navigation starts/finishes
// 2. activation starts and suspends on CommitDeferringCondition
// 3. navigation in the prerendered page starts
// 4. navigation in the prerendered page finishes
// 5. activation resumes/finishes
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       MainFrameNavigationDuringActivation) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?1");
  const GURL kPrerenderingUrl2 = GetUrl("/empty.html?2");
  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start a prerender.
  PrerenderHostId prerender_host_id = AddPrerender(kPrerenderingUrl);
  RenderFrameHostImpl* prerendered_rfh =
      GetPrerenderedMainFrameHost(prerender_host_id);
  test::PrerenderHostObserver prerender_observer(*web_contents(),
                                                 prerender_host_id);
  auto* prerender_ftn = prerendered_rfh->frame_tree_node();
  EXPECT_FALSE(prerender_ftn->HasNavigation());

  // Start an activation navigation for the prerender and pause it before it
  // completes.
  TestActivationManager activation_observer(shell()->web_contents(),
                                            kPrerenderingUrl);
  {
    ASSERT_TRUE(ExecJs(web_contents()->GetPrimaryMainFrame(),
                       JsReplace("location = $1", kPrerenderingUrl)));

    // Pause the activation before it's committed.
    EXPECT_TRUE(activation_observer.WaitForBeforeChecks());
    EXPECT_TRUE(activation_observer.GetNavigationHandle()
                    ->IsCommitDeferringConditionDeferredForTesting());
    EXPECT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);
  }

  // Make a navigation in the prerendered page. This navigation should succeed.
  TestNavigationManager navigation_observer(web_contents(), kPrerenderingUrl2);
  NavigatePrerenderedPage(prerender_host_id, kPrerenderingUrl2);
  ASSERT_TRUE(navigation_observer.WaitForNavigationFinished());
  EXPECT_TRUE(navigation_observer.was_successful());

  // Verify that all RenderFrameHostImpls are the prerendering state.
  EXPECT_TRUE(prerender_helper()->VerifyPrerenderingState(kPrerenderingUrl));

  // The activation isn't cancelled because there is no ongoing navigation.
  activation_observer.ResumeActivation();

  // Wait for the completion of the navigation. This should be the prerendered
  // page activation.
  activation_observer.WaitForNavigationFinished();

  // The prerender host should have been consumed since the activation was
  // completed.
  EXPECT_FALSE(
      web_contents_impl()->GetPrerenderHostRegistry()->FindNonReservedHostById(
          prerender_host_id));
  EXPECT_FALSE(
      web_contents_impl()->GetPrerenderHostRegistry()->HasReservedHost());

  EXPECT_TRUE(activation_observer.was_activated());
  EXPECT_TRUE(activation_observer.was_successful());
  EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), kPrerenderingUrl2);
}

// Test that a main frame navigation after the initial prerender navigation
// doesn't cancel an ongoing prerendering. The main frame navigation runs
// concurrent with the activation.
// 1. prerender navigation starts/finishes
// 2. activation starts and suspends on CommitDeferringCondition
// 3. navigation in the prerendered page starts
// 4. activation resumes
// 5. navigation in the prerendered page finishes
// 6. activation finishes
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       MainFrameNavigationConcurrentWithActivation) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?1");
  const GURL kPrerenderingUrl2 = GetUrl("/empty.html?2");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start a prerender.
  PrerenderHostId prerender_host_id = AddPrerender(kPrerenderingUrl);
  RenderFrameHostImpl* prerendered_rfh =
      GetPrerenderedMainFrameHost(prerender_host_id);
  test::PrerenderHostObserver prerender_observer(*web_contents(),
                                                 prerender_host_id);
  auto* prerender_ftn = prerendered_rfh->frame_tree_node();
  EXPECT_FALSE(prerender_ftn->HasNavigation());

  // Start an activation navigation for the prerender and pause it before it
  // completes.
  TestActivationManager activation_observer(shell()->web_contents(),
                                            kPrerenderingUrl);
  {
    ASSERT_TRUE(ExecJs(web_contents()->GetPrimaryMainFrame(),
                       JsReplace("location = $1", kPrerenderingUrl)));

    // Pause the activation before it's committed.
    EXPECT_TRUE(activation_observer.WaitForBeforeChecks());
    EXPECT_TRUE(activation_observer.GetNavigationHandle()
                    ->IsCommitDeferringConditionDeferredForTesting());
    EXPECT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);
  }

  // Make a navigation in the prerendered page. This navigation should succeed.
  TestNavigationManager navigation_observer(web_contents(), kPrerenderingUrl2);
  NavigatePrerenderedPage(prerender_host_id, kPrerenderingUrl2);

  // Resume an activation navigation before completing the navigation in the
  // prerendered page. The activation isn't cancelled because
  // PrerenderCommitDeferringCondition defers the activation until the ongoing
  // main frame navigation is completed.
  activation_observer.ResumeActivation();

  // Wait for the completion of the navigation in the prerendered page.
  ASSERT_TRUE(navigation_observer.WaitForNavigationFinished());
  EXPECT_TRUE(navigation_observer.was_successful());

  // Verify that all RenderFrameHostImpls are the prerendering state.
  EXPECT_TRUE(prerender_helper()->VerifyPrerenderingState(kPrerenderingUrl));

  // Wait for the completion of the navigation. This should be the prerendered
  // page activation.
  activation_observer.WaitForNavigationFinished();

  // The prerender host should have been consumed since the activation was
  // completed.
  EXPECT_FALSE(
      web_contents_impl()->GetPrerenderHostRegistry()->FindNonReservedHostById(
          prerender_host_id));
  EXPECT_FALSE(
      web_contents_impl()->GetPrerenderHostRegistry()->HasReservedHost());

  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl2);
  EXPECT_TRUE(activation_observer.was_activated());
  EXPECT_TRUE(activation_observer.was_successful());
  EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), kPrerenderingUrl2);
}

// Test that a main frame navigation after the initial prerender navigation and
// the activation is resumed cancels prerendering. This is the edge case that
// PrerenderCommitDeferringCondition posts a task to resume activation
// (https://source.chromium.org/chromium/chromium/src/+/main:content/browser/preloading/prerender/prerender_commit_deferring_condition.cc;l=105-106;drc=86ba45ef0be48fc81656da31dd4952857963485c)
// and a main frame navigation starts before activation is completed.
// 1. prerender navigation starts/finishes
// 2. activation starts and suspends on CommitDeferringCondition
// 3. navigation in the prerendered page starts
// 4. activation resumes
// 5. navigation in the prerendered page finishes
// 6. another navigation in the prerendered page starts but the server never
//    respond to the navigation
// 7. activation is canceled
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       MainFrameNavigationAfterActivationIsResumed) {
  embedded_test_server()->RegisterRequestHandler(base::BindLambdaForTesting(
      [&](const net::test_server::HttpRequest& request)
          -> std::unique_ptr<net::test_server::HttpResponse> {
        if (request.relative_url != "/empty.html?3") {
          return nullptr;
        }
        return std::make_unique<net::test_server::HungResponse>();
      }));
  ASSERT_TRUE(embedded_test_server()->Start());

  const GURL kInitialUrl = embedded_test_server()->GetURL("/empty.html");
  const GURL kPrerenderingUrl = embedded_test_server()->GetURL("/empty.html?1");
  const GURL kPrerenderingUrl2 =
      embedded_test_server()->GetURL("/empty.html?2");
  // The server returns a HungResponse to the request to kPrerenderingUrl3,
  // which doesn't actually respond until the server is destroyed.
  const GURL kPrerenderingUrl3 =
      embedded_test_server()->GetURL("/empty.html?3");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start a prerender.
  PrerenderHostId prerender_host_id = AddPrerender(kPrerenderingUrl);
  RenderFrameHostImpl* prerendered_rfh =
      GetPrerenderedMainFrameHost(prerender_host_id);
  test::PrerenderHostObserver prerender_observer(*web_contents(),
                                                 prerender_host_id);
  auto* prerender_ftn = prerendered_rfh->frame_tree_node();
  EXPECT_FALSE(prerender_ftn->HasNavigation());

  TestActivationManager activation_observer(shell()->web_contents(),
                                            kPrerenderingUrl);

  // Set a callback that will be called after the last commit deferring
  // condition is executed. The callback starts a main frame navigation in a
  // prerendered page after activation is resumed.
  activation_observer.SetCallbackCalledAfterActivationIsReady(base::BindOnce(
      &PrerenderBrowserTest::NavigatePrerenderedPage, base::Unretained(this),
      prerender_host_id, kPrerenderingUrl3));

  // Start an activation.
  {
    ASSERT_TRUE(ExecJs(web_contents()->GetPrimaryMainFrame(),
                       JsReplace("location = $1", kPrerenderingUrl)));

    // Pause the activation before it's committed.
    EXPECT_TRUE(activation_observer.WaitForBeforeChecks());
    EXPECT_TRUE(activation_observer.GetNavigationHandle()
                    ->IsCommitDeferringConditionDeferredForTesting());
    EXPECT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);
  }

  // Start a main frame navigation in a prerendered page. It defers the
  // activation commit.
  TestNavigationManager navigation_observer(web_contents(), kPrerenderingUrl2);
  NavigatePrerenderedPage(prerender_host_id, kPrerenderingUrl2);

  // Verify that all RenderFrameHostImpls are the prerendering state.
  EXPECT_TRUE(prerender_helper()->VerifyPrerenderingState(kPrerenderingUrl));

  // Resume an activation navigation before completing the navigation in the
  // prerendered page. The activation isn't cancelled because
  // PrerenderCommitDeferringCondition defers the activation until the ongoing
  // main frame navigation is completed.
  activation_observer.ResumeActivation();

  // Wait for the completion of the navigation in the prerendered page.
  ASSERT_TRUE(navigation_observer.WaitForNavigationFinished());
  EXPECT_TRUE(navigation_observer.was_successful());

  // Wait for the completion of the navigation. This shouldn't be the
  // prerendered page activation.
  activation_observer.WaitForNavigationFinished();

  // The prerender host should have been abandoned.
  EXPECT_FALSE(
      web_contents_impl()->GetPrerenderHostRegistry()->FindNonReservedHostById(
          prerender_host_id));
  EXPECT_FALSE(
      web_contents_impl()->GetPrerenderHostRegistry()->HasReservedHost());

  EXPECT_FALSE(activation_observer.was_activated());
  EXPECT_TRUE(activation_observer.was_successful());
  EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), kPrerenderingUrl);

  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::kActivatedDuringMainFrameNavigation);
}

// Test the following scenario: a prerender initial navigation is pending and an
// activation navigation is deferred due to that, and then if prerender is
// canceled, the activation navigation will fall back to a normal navigation
// with no crash and hang.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       CancelPrerenderWhenDeferringActivationNavigation) {
  const char prerendering_url_c[] = "/empty.html?prerender";
  net::test_server::ControllableHttpResponse response_for_initial_navigation(
      embedded_test_server(), prerendering_url_c);
  net::test_server::ControllableHttpResponse response_for_activation_navigation(
      embedded_test_server(), prerendering_url_c);

  ASSERT_TRUE(embedded_test_server()->Start());

  const GURL initial_url = embedded_test_server()->GetURL("/empty.html");
  const GURL prerendering_url =
      embedded_test_server()->GetURL(prerendering_url_c);

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Start prerendering.
  content::test::PrerenderHostCreationWaiter host_creation_waiter;
  AddPrerenderAsync(prerendering_url);
  PrerenderHostId host_id = host_creation_waiter.Wait();

  response_for_initial_navigation.WaitForRequest();
  // Not sending the response so that the prerender initial navigation will be
  // pending.

  test::PrerenderHostObserver prerender_observer(*web_contents(), host_id);
  TestActivationManager activation_observer(web_contents(), prerendering_url);

  // Start prerender activation. This will be deferred because initial
  // navigation is not finished.
  test::PrerenderTestHelper::NavigatePrimaryPageAsync(*web_contents_impl(),
                                                      prerendering_url);
  NavigationRequest* request =
      web_contents_impl()->GetPrimaryFrameTree().root()->navigation_request();
  ASSERT_TRUE(activation_observer.WaitForBeforeChecks());
  activation_observer.ResumeActivation();
  ASSERT_TRUE(request->IsCommitDeferringConditionDeferredForTesting());
  ASSERT_EQ(request->state(), NavigationRequest::NOT_STARTED);

  // Cancel prerendering.
  CancelPrerenderedPage(host_id);
  prerender_observer.WaitForDestroyed();

  // Activation navigation will fall back to normal navigation.
  response_for_activation_navigation.WaitForRequest();
  response_for_activation_navigation.Send(net::HTTP_OK, "");
  response_for_activation_navigation.Done();
  activation_observer.WaitForNavigationFinished();
  EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), prerendering_url);
  EXPECT_FALSE(activation_observer.was_activated());
}

// Test that WebContentsObserver::DidFinishLoad is not invoked when the page
// gets loaded while prerendering but it is deferred and invoked on prerender
// activation.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       DidFinishLoadInvokedAfterActivation) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/simple_page.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Initialize a MockWebContentsObserver and ensure that DidFinishLoad is not
  // invoked while prerendering.
  testing::NiceMock<MockWebContentsObserver> observer(shell()->web_contents());
  EXPECT_CALL(observer, DidFinishLoad(testing::_, testing::_)).Times(0);

  // Start a prerender.
  PrerenderHostId prerender_host_id = AddPrerender(kPrerenderingUrl);
  RenderFrameHostImpl* prerender_frame_host =
      GetPrerenderedMainFrameHost(prerender_host_id);
  EXPECT_EQ(0u, prerender_frame_host->child_count());

  // Verify and clear all expectations on the mock observer before setting new
  // ones.
  testing::Mock::VerifyAndClearExpectations(&observer);
  testing::InSequence s;

  // Activate the prerendered page. This should result in invoking DidFinishLoad
  // once for root RenderFrameHost `prerender_frame_host`.
  {
    // Verify that DidFinishNavigation is invoked before DidFinishLoad on
    // activation.
    EXPECT_CALL(observer, DidFinishNavigation(testing::_));

    EXPECT_CALL(observer,
                DidFinishLoad(prerender_frame_host, kPrerenderingUrl));
  }
  NavigatePrimaryPage(kPrerenderingUrl);
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);
}

// Test that WebContentsObserver::DidFinishLoad is not invoked when the page
// gets loaded while prerendering but it is deferred and invoked on prerender
// activation for both main and sub-frames.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       DidFinishLoadInvokedAfterActivationWithSubframes) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/page_with_iframe.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Initialize a MockWebContentsObserver and ensure that DidFinishLoad is not
  // invoked while prerendering.
  testing::NiceMock<MockWebContentsObserver> observer(shell()->web_contents());
  testing::InSequence s;
  EXPECT_CALL(observer, DidFinishLoad(testing::_, testing::_)).Times(0);

  // Start a prerender.
  PrerenderHostId prerender_host_id = AddPrerender(kPrerenderingUrl);
  RenderFrameHostImpl* prerender_main_frame_host =
      GetPrerenderedMainFrameHost(prerender_host_id);
  RenderFrameHost* child_frame = ChildFrameAt(prerender_main_frame_host, 0);
  EXPECT_EQ(1u, prerender_main_frame_host->child_count());

  // Verify and clear all expectations on the mock observer before setting new
  // ones.
  testing::Mock::VerifyAndClearExpectations(&observer);

  // Activate the prerendered page. This should result in invoking DidFinishLoad
  // twice once for root and once for child RenderFrameHosts.
  {
    // Verify that DidFinishNavigation is invoked before DidFinishLoad.
    EXPECT_CALL(observer, DidFinishNavigation(testing::_));

    EXPECT_CALL(observer,
                DidFinishLoad(prerender_main_frame_host, kPrerenderingUrl));

    EXPECT_CALL(observer,
                DidFinishLoad(child_frame, child_frame->GetLastCommittedURL()));
  }
  NavigatePrimaryPage(kPrerenderingUrl);
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);
}

// Test that WebContentsObserver::DOMContentLoaded is not invoked while
// prerendering but it is deferred and invoked on prerender activation for both
// main and sub-frames.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       DOMContentLoadedInvokedAfterActivationWithSubframes) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/page_with_iframe.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Initialize a MockWebContentsObserver and ensure that DOMContentLoaded is
  // not invoked while prerendering.
  testing::NiceMock<MockWebContentsObserver> observer(shell()->web_contents());
  EXPECT_CALL(observer, DOMContentLoaded(testing::_)).Times(0);

  // Start a prerender.
  PrerenderHostId prerender_host_id = AddPrerender(kPrerenderingUrl);
  RenderFrameHostImpl* prerender_main_frame_host =
      GetPrerenderedMainFrameHost(prerender_host_id);
  RenderFrameHost* child_frame = ChildFrameAt(prerender_main_frame_host, 0);
  EXPECT_EQ(prerender_main_frame_host->child_count(), 1u);
  ASSERT_TRUE(prerender_host_id);

  // Verify and clear all expectations on the mock observer before setting new
  // ones.
  testing::Mock::VerifyAndClearExpectations(&observer);
  testing::InSequence s;

  // Activate the prerendered page. This should result in invoking
  // DOMContentLoaded twice once for root and once for child RenderFrameHost.
  {
    // Verify that DidFinishNavigation is invoked before DOMContentLoaded on
    // activation.
    EXPECT_CALL(observer, DidFinishNavigation(testing::_));

    EXPECT_CALL(observer, DOMContentLoaded(prerender_main_frame_host)).Times(1);

    EXPECT_CALL(observer, DOMContentLoaded(child_frame)).Times(1);
  }
  NavigatePrimaryPage(kPrerenderingUrl);
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);
}

// Test that WebContentsObserver::DocumentOnLoadCompletedInPrimaryMainFrame is
// not invoked when the page gets loaded while prerendering but it is deferred
// and invoked on prerender activation.
IN_PROC_BROWSER_TEST_F(
    PrerenderBrowserTest,
    DocumentOnLoadCompletedInPrimaryMainFrameInvokedAfterActivation) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/page_with_iframe.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Initialize a MockWebContentsObserver and ensure that
  // DocumentOnLoadCompletedInPrimaryMainFrame is not invoked while
  // prerendering.
  testing::NiceMock<MockWebContentsObserver> observer(shell()->web_contents());
  EXPECT_CALL(observer, DocumentOnLoadCompletedInPrimaryMainFrame()).Times(0);

  // Start a prerender.
  PrerenderHostId prerender_host_id = AddPrerender(kPrerenderingUrl);
  RenderFrameHostImpl* prerender_frame_host =
      GetPrerenderedMainFrameHost(prerender_host_id);
  EXPECT_EQ(prerender_frame_host->child_count(), 1u);
  ASSERT_TRUE(prerender_host_id);

  // Verify and clear all expectations on the mock observer before setting new
  // ones.
  testing::Mock::VerifyAndClearExpectations(&observer);
  testing::InSequence s;

  // Activate the prerendered page. This should result in invoking
  // DocumentOnLoadCompletedInPrimaryMainFrame only for main RenderFrameHost.
  {
    // Verify that DidFinishNavigation is invoked before
    // DocumentOnLoadCompletedInPrimaryMainFrame on activation.
    EXPECT_CALL(observer, DidFinishNavigation(testing::_));

    EXPECT_CALL(observer, DocumentOnLoadCompletedInPrimaryMainFrame()).Times(1);
  }
  NavigatePrimaryPage(kPrerenderingUrl);
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);
}

// Test that WebContentsObserver::PrimaryMainDocumentElementAvailable is not
// invoked when the page gets loaded while prerendering but it is deferred and
// invoked on prerender activation.
IN_PROC_BROWSER_TEST_F(
    PrerenderBrowserTest,
    PrimaryMainDocumentElementAvailableInvokedAfterActivation) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/page_with_iframe.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Initialize a MockWebContentsObserver and ensure that
  // PrimaryMainDocumentElementAvailable is not invoked while prerendering.
  testing::NiceMock<MockWebContentsObserver> observer(shell()->web_contents());
  EXPECT_CALL(observer, PrimaryMainDocumentElementAvailable()).Times(0);

  // AddPrerender() below waits until WebContentsObserver::DidStopLoading() is
  // called and RenderFrameHostImpl::PrimaryMainDocumentElementAvailable() call
  // is expected before it returns.
  PrerenderHostId prerender_host_id = AddPrerender(kPrerenderingUrl);
  RenderFrameHostImpl* prerender_frame_host =
      GetPrerenderedMainFrameHost(prerender_host_id);
  EXPECT_EQ(prerender_frame_host->child_count(), 1u);
  ASSERT_TRUE(prerender_host_id);

  // Verify and clear all expectations on the mock observer before setting new
  // ones.
  testing::Mock::VerifyAndClearExpectations(&observer);
  testing::InSequence s;

  // Activate the prerendered page. This should result in invoking
  // PrimaryMainDocumentElementAvailable only for main RenderFrameHost.
  // Verify that DidFinishNavigation is invoked before
  // PrimaryMainDocumentElementAvailable on activation.
  EXPECT_CALL(observer, DidFinishNavigation(testing::_));

  EXPECT_CALL(observer, PrimaryMainDocumentElementAvailable()).Times(1);
  NavigatePrimaryPage(kPrerenderingUrl);
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);
}

// Test that WebContentsObserver::LoadProgressChanged is not invoked when the
// page gets loaded while prerendering but is invoked on prerender activation.
// Check that LoadProgressChanged is only called once for
// blink::kFinalLoadProgress if the prerender page completes loading on
// activation.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       LoadProgressChangedInvokedOnActivation) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/simple_page.html");

  web_contents_impl()->set_minimum_delay_between_loading_updates_for_testing(
      base::Milliseconds(0));

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Initialize a MockWebContentsObserver and ensure that LoadProgressChanged is
  // not invoked while prerendering.
  testing::NiceMock<MockWebContentsObserver> observer(shell()->web_contents());
  testing::InSequence s;
  EXPECT_CALL(observer, LoadProgressChanged(testing::_)).Times(0);

  // Start a prerender.
  PrerenderHostId prerender_host_id = AddPrerender(kPrerenderingUrl);
  ASSERT_TRUE(prerender_host_id);
  RenderFrameHostImpl* prerender_frame_host =
      GetPrerenderedMainFrameHost(prerender_host_id);

  // Verify and clear all expectations on the mock observer before setting new
  // ones.
  testing::Mock::VerifyAndClearExpectations(&observer);

  // Activate the prerendered page. This should result in invoking
  // LoadProgressChanged for the following cases:
  {
    // 1) During DidStartLoading LoadProgressChanged is invoked with
    // kInitialLoadProgress value.
    EXPECT_CALL(observer, LoadProgressChanged(blink::kInitialLoadProgress));

    // Verify that DidFinishNavigation is invoked before final load progress
    // notification.
    EXPECT_CALL(observer, DidFinishNavigation(testing::_));

    // 2) During DidStopLoading LoadProgressChanged is invoked with
    // kFinalLoadProgress.
    EXPECT_CALL(observer, LoadProgressChanged(blink::kFinalLoadProgress))
        .Times(1);
  }

  // Set the prerender load progress value to blink::kFinalLoadProgress, this
  // should result in invoking LoadProgressChanged(blink::kFinalLoadProgress)
  // only once on activation during call to DidStopLoading.
  prerender_frame_host->GetPage().set_load_progress(blink::kFinalLoadProgress);
  NavigatePrimaryPage(kPrerenderingUrl);
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);
}

// Test that WebContentsObserver::DidStopLoading is not invoked when the page
// gets loaded while prerendering but is invoked on prerender activation.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       DidStopLoadingInvokedOnActivation) {
  const GURL initial_url = GetUrl("/empty.html");
  const GURL prerendering_url = GetUrl("/simple_page.html");

  web_contents_impl()->set_minimum_delay_between_loading_updates_for_testing(
      base::Milliseconds(0));

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Initialize a MockWebContentsObserver and ensure that DidStopLoading is
  // not invoked while prerendering.
  testing::NiceMock<MockWebContentsObserver> observer(shell()->web_contents());
  EXPECT_CALL(observer, DidStopLoading()).Times(0);

  // Start a prerender.
  PrerenderHostId prerender_host_id = AddPrerender(prerendering_url);
  ASSERT_TRUE(prerender_host_id);

  // Verify and clear all expectations on the mock observer before setting new
  // ones.
  testing::Mock::VerifyAndClearExpectations(&observer);

  // Activate the prerendered page. This should result in invoking
  // DidStopLoading.
  EXPECT_CALL(observer, DidStopLoading()).Times(1);
  test::PrerenderHostObserver host_observer(*web_contents(), prerender_host_id);
  NavigatePrimaryPage(prerendering_url);
  EXPECT_TRUE(host_observer.was_activated());
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), prerendering_url);
}

// Test that WebContentsObserver::DidStopLoading is invoked when the page gets
// loaded after activation.
//
// This is a regression test for https://crbug.com/40256454. Previously,
// DidStopLoading was invoked regardless of the current loading state on
// activation, which was obviously wrong. This test makes sure that
// DidStopLoading is invoked after the page actually gets loaded.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       DidStopLoadingInvokedAfterActivation) {
  // Use ControllableHttpResponse to control the timing to serve for delaying
  // page loading.
  net::test_server::ControllableHttpResponse response(embedded_test_server(),
                                                      "/simple_page.html");
  ASSERT_TRUE(embedded_test_server()->Start());

  const GURL initial_url = embedded_test_server()->GetURL("/empty.html");
  const GURL prerendering_url =
      embedded_test_server()->GetURL("/simple_page.html");

  web_contents_impl()->set_minimum_delay_between_loading_updates_for_testing(
      base::Milliseconds(0));

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Initialize a MockWebContentsObserver and ensure that DidStopLoading is
  // not invoked while prerendering.
  testing::NiceMock<MockWebContentsObserver> observer(shell()->web_contents());
  EXPECT_CALL(observer, DidStopLoading()).Times(0);

  // Start a prerender.
  AddPrerenderAsync(prerendering_url);

  // Send only a header. This prevents the prerendered page from being fully
  // loaded.
  const char kHttpResponseHeader[] =
      "HTTP/1.1 200 OK\r\n"
      "Content-Type: text/html; charset=utf-8\r\n"
      "\r\n";
  response.WaitForRequest();
  response.Send(kHttpResponseHeader);

  // Activate the prerendered page. The response for the prerendered page is not
  // finalized yet, so this should not invoke DidStopLoading.
  EXPECT_CALL(observer, DidStopLoading()).Times(0);
  test::PrerenderHostObserver host_observer(*web_contents(), prerendering_url);
  prerender_helper()->NavigatePrimaryPageAsync(prerendering_url);
  host_observer.WaitForActivation();
  EXPECT_TRUE(host_observer.was_activated());
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), prerendering_url);

  // Verify and clear all expectations on the mock observer before setting new
  // ones. The activated page is not loaded yet, so DidStopLoading should not be
  // invoked yet.
  testing::Mock::VerifyAndClearExpectations(&observer);

  // Finalize the response for the activated page. This should result in
  // invoking DidStopLoading.
  base::RunLoop run_loop;
  EXPECT_CALL(observer, DidStopLoading()).WillOnce([&]() { run_loop.Quit(); });
  response.Send("0\r\n");
  response.Send("\r\n");
  response.Done();
  run_loop.Run();
}

// Test the dispatch order of various load events on prerender activation.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, OrderingOfDifferentLoadEvents) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/simple_page.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Initialize a MockWebContentsObserver to check order of different load
  // events.
  testing::NiceMock<MockWebContentsObserver> observer(shell()->web_contents());

  // Start a prerender.
  PrerenderHostId prerender_host_id = AddPrerender(kPrerenderingUrl);
  ASSERT_TRUE(prerender_host_id);

  // Verify and clear all expectations on the mock observer before setting new
  // ones.
  testing::Mock::VerifyAndClearExpectations(&observer);
  testing::InSequence s;

  // Activate the prerendered page. This should result in invoking various
  // WebContentsObserver events in the following order.
  {
    EXPECT_CALL(observer, DidStartLoading()).Times(1);

    // Verify that DidFinishNavigation is invoked before any finish load events
    // are dispatched.
    EXPECT_CALL(observer, DidFinishNavigation(testing::_)).Times(1);

    EXPECT_CALL(observer, DOMContentLoaded(testing::_)).Times(1);

    EXPECT_CALL(observer, DocumentOnLoadCompletedInPrimaryMainFrame()).Times(1);

    EXPECT_CALL(observer, DidFinishLoad(testing::_, testing::_)).Times(1);

    EXPECT_CALL(observer, DidStopLoading()).Times(1);
  }
  NavigatePrimaryPage(kPrerenderingUrl);
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);
}

// Tests that cross-origin subframe navigations in a prerendered page are
// deferred even if they start after the a navigation starts that will
// attempt to activate the prerendered page.
//
// Regression test for https://crbug.com/1190262.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       CrossOriginSubframeNavigationDuringActivation) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/page_with_blank_iframe.html");
  const GURL kCrossOriginUrl = GetCrossSiteUrl("/simple_page.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(shell()->web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Start prerendering `kPrerenderingUrl`.
  PrerenderHostId prerender_host_id;
  RenderFrameHost* prerender_main_frame = nullptr;
  {
    prerender_host_id = AddPrerender(kPrerenderingUrl);
    prerender_main_frame = GetPrerenderedMainFrameHost(prerender_host_id);
    RenderFrameHost* child_frame = ChildFrameAt(prerender_main_frame, 0);
    ASSERT_TRUE(child_frame);
  }

  // Start an activation navigation for the prerender. Pause activation before
  // it completes.
  test::PrerenderHostObserver prerender_observer(*web_contents(),
                                                 kPrerenderingUrl);
  TestActivationManager activation_observer(shell()->web_contents(),
                                            kPrerenderingUrl);
  {
    ASSERT_TRUE(ExecJs(web_contents()->GetPrimaryMainFrame(),
                       JsReplace("location = $1", kPrerenderingUrl)));

    EXPECT_TRUE(activation_observer.WaitForBeforeChecks());
    EXPECT_TRUE(activation_observer.GetNavigationHandle()
                    ->IsCommitDeferringConditionDeferredForTesting());
    EXPECT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);
  }

  // Start a cross-origin subframe navigation in the prerendered page. It
  // should be deferred.
  std::string kNavigateScript = R"(
    document.querySelector('iframe').src = $1;
  )";
  TestNavigationManager iframe_nav_observer(shell()->web_contents(),
                                            kCrossOriginUrl);
  ASSERT_TRUE(ExecJs(prerender_main_frame,
                     JsReplace(kNavigateScript, kCrossOriginUrl)));

  ASSERT_TRUE(iframe_nav_observer.WaitForFirstYieldAfterDidStartNavigation());

  // The PrerenderSubframeNavigationThrottle should defer it until activation.
  auto* child_ftn =
      FrameTreeNode::GloballyFindByID(
          PrerenderHost::GetFrameTreeNodeIdForId(prerender_host_id))
          ->child_at(0);
  auto* child_navigation = child_ftn->navigation_request();
  ASSERT_NE(child_navigation, nullptr);
  EXPECT_TRUE(child_navigation->IsDeferredForTesting());

  // Allow the activation navigation to complete.
  activation_observer.WaitForNavigationFinished();
  EXPECT_TRUE(activation_observer.was_activated());

  // The iframe navigation should finish.
  ASSERT_TRUE(iframe_nav_observer.WaitForNavigationFinished());
  EXPECT_EQ(ChildFrameAt(prerender_main_frame, 0)->GetLastCommittedURL(),
            kCrossOriginUrl);
}

// Tests WebContents::OpenURL to a frame in a prerendered page when a
// navigation that will attempt to activate the page has already started. The
// subframe navigation should succeed.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       OpenURLInSubframeDuringActivation) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/page_with_blank_iframe.html");
  const GURL kNewIframeUrl = GetUrl("/simple_page.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(shell()->web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Start prerendering `kPrerenderingUrl`.
  PrerenderHostId prerender_host_id;
  RenderFrameHost* child_frame = nullptr;
  {
    prerender_host_id = AddPrerender(kPrerenderingUrl);
    auto* prerendered_render_frame_host =
        GetPrerenderedMainFrameHost(prerender_host_id);
    child_frame = ChildFrameAt(prerendered_render_frame_host, 0);
    ASSERT_TRUE(child_frame);
  }

  // Start an activation navigation for the prerender and pause before it
  // completes.
  test::PrerenderHostObserver prerender_observer(*web_contents(),
                                                 kPrerenderingUrl);
  TestActivationManager activation_observer(shell()->web_contents(),
                                            kPrerenderingUrl);
  {
    ASSERT_TRUE(ExecJs(web_contents()->GetPrimaryMainFrame(),
                       JsReplace("location = $1", kPrerenderingUrl)));

    EXPECT_TRUE(activation_observer.WaitForBeforeChecks());
    EXPECT_TRUE(activation_observer.GetNavigationHandle()
                    ->IsCommitDeferringConditionDeferredForTesting());
    EXPECT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);
  }

  // Use the OpenURL API to navigate the iframe in the prerendering frame tree.
  // This navigation should succeed.
  {
    TestNavigationManager iframe_observer(shell()->web_contents(),
                                          kNewIframeUrl);
    shell()->web_contents()->OpenURL(
        OpenURLParams(kNewIframeUrl, Referrer(),
                      child_frame->GetFrameTreeNodeId(),
                      WindowOpenDisposition::CURRENT_TAB,
                      ui::PAGE_TRANSITION_AUTO_SUBFRAME,
                      /*is_renderer_initiated=*/false),
        /*navigation_handle_callback=*/{});
    ASSERT_TRUE(iframe_observer.WaitForNavigationFinished());
    EXPECT_EQ(child_frame->GetLastCommittedURL(), kNewIframeUrl);
  }

  // Allow the activation navigation to complete.
  activation_observer.WaitForNavigationFinished();
  EXPECT_TRUE(activation_observer.was_activated());
}

class InvisiblePageLazyLoadingImageBrowserTest
    : public PrerenderBrowserTest,
      public testing::WithParamInterface<
          blink::features::EnableLazyLoadImageForInvisiblePageType> {
 public:
  static std::string GetFieldTrialParamName(
      blink::features::EnableLazyLoadImageForInvisiblePageType
          target_page_type) {
    switch (target_page_type) {
      case blink::features::EnableLazyLoadImageForInvisiblePageType::
          kAllInvisiblePage:
        return "all_invisible_page";
      case blink::features::EnableLazyLoadImageForInvisiblePageType::
          kPrerenderPage:
        return "prerender_page";
    }
  }

  InvisiblePageLazyLoadingImageBrowserTest() {
    feature_list_.InitWithFeaturesAndParameters(
        {{blink::features::kEnableLazyLoadImageForInvisiblePage,
          {
              {"enabled_page_type", GetFieldTrialParamName(GetParam())},
          }}},
        {});
  }

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

INSTANTIATE_TEST_SUITE_P(
    All,
    InvisiblePageLazyLoadingImageBrowserTest,
    testing::Values(blink::features::EnableLazyLoadImageForInvisiblePageType::
                        kAllInvisiblePage,
                    blink::features::EnableLazyLoadImageForInvisiblePageType::
                        kPrerenderPage),
    [](const testing::TestParamInfo<
        blink::features::EnableLazyLoadImageForInvisiblePageType>& info) {
      return InvisiblePageLazyLoadingImageBrowserTest::GetFieldTrialParamName(
          info.param);
    });

// Tests that loading=lazy can prevent image load in a prerendered page.
// TODO(https://crbug.com/381110833): The image, positioned in the top-left
// corner of the page, should be visible in the initial viewport after the page
// gets activated. Ideally it should be loaded during prerendering, and we need
// to figure out how to make that happen.
IN_PROC_BROWSER_TEST_P(InvisiblePageLazyLoadingImageBrowserTest, LazyLoading) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/prerender/image_loading_lazy.html");
  const GURL kImageUrl = GetUrl("/blank.jpg");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(shell()->web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Start prerendering `kPrerenderingUrl`.
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 0);
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  RenderFrameHost* prerender_frame_host = GetPrerenderedMainFrameHost(host_id);

  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);

  // A request for the image in the prerendered page should be prevented by
  // loading=lazy.
  EXPECT_EQ(GetRequestCount(kImageUrl), 0);
  EXPECT_TRUE(ExecJs(prerender_frame_host, "runLoop()"));

  EXPECT_EQ(EvalJs(prerender_frame_host, "image_loaded"), false);

  test::PrerenderHostObserver host_observer(*web_contents(), kPrerenderingUrl);
  NavigatePrimaryPage(kPrerenderingUrl);
  EXPECT_TRUE(host_observer.was_activated());
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);

  EXPECT_TRUE(ExecJs(prerender_frame_host, "promise_with_resolvers.promise"));
  EXPECT_EQ(EvalJs(prerender_frame_host, "image_loaded"), true);
}

class DisabledInvisiblePageLazyLoadingImageBrowserTest
    : public PrerenderBrowserTest {
 public:
  DisabledInvisiblePageLazyLoadingImageBrowserTest() {
    feature_list_.InitAndDisableFeature(
        blink::features::kEnableLazyLoadImageForInvisiblePage);
  }

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

// Tests that loading=lazy doesn't prevent image load in a prerendered page.
// This test is tested under the condition that
// blink::features::kEnableLazyLoadImageForInvisiblePage is disabled.
IN_PROC_BROWSER_TEST_F(DisabledInvisiblePageLazyLoadingImageBrowserTest,
                       LazyLoading) {
  ASSERT_FALSE(base::FeatureList::IsEnabled(
      blink::features::kEnableLazyLoadImageForInvisiblePage));
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/prerender/image_loading_lazy.html");
  const GURL kImageUrl = GetUrl("/blank.jpg");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(shell()->web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Start prerendering `kPrerenderingUrl`.
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 0);
  AddPrerender(kPrerenderingUrl);
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);

  // A request for the image in the prerendered page shouldn't be prevented by
  // loading=lazy.
  EXPECT_EQ(GetRequestCount(kImageUrl), 1);
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       SessionStorageAfterBackNavigation_NoProcessReuse) {
  // When BackForwardCache feature is enabled, this test doesn't work, because
  // this test is checking the behavior of a new renderer process which is
  // created for a back forward navigation from a prerendered page.
  DisableBackForwardCacheForTesting(shell()->web_contents(),
                                    BackForwardCache::TEST_REQUIRES_NO_CACHING);

  const GURL kInitialUrl = GetUrl("/prerender/session_storage.html");
  const GURL kPrerenderingUrl =
      GetUrl("/prerender/session_storage.html?prerendering=");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  std::unique_ptr<RenderProcessHostWatcher> process_host_watcher =
      std::make_unique<RenderProcessHostWatcher>(
          current_frame_host()->GetProcess(),
          RenderProcessHostWatcher::WATCH_FOR_HOST_DESTRUCTION);

  AddPrerender(kPrerenderingUrl);
  NavigatePrimaryPage(kPrerenderingUrl);

  EXPECT_EQ("initial", EvalJs(current_frame_host(),
                              "window.sessionKeysInPrerenderingchange")
                           .ExtractString());
  EXPECT_EQ(
      "activated, initial",
      EvalJs(current_frame_host(), "getSessionStorageKeys()").ExtractString());

  // Speculative fix for the test flakiness (crbug.com/1216038), which may be
  // caused by the delayed async IPC of Session Storage (StorageArea.Put()).
  EXPECT_TRUE(ExecJs(shell()->web_contents(),
                     "new Promise(resolve => requestIdleCallback(resolve));"));

  // Make sure that the initial renderer process is destroyed. So that the
  // initial renderer process will not be reused after the back forward
  // navigation below.
  process_host_watcher->Wait();

  // Navigate back to the initial page.
  TestNavigationObserver observer(shell()->web_contents());
  shell()->GoBackOrForward(-1);
  observer.Wait();
  EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), kInitialUrl);

  EXPECT_EQ(
      "activated, initial",
      EvalJs(current_frame_host(), "getSessionStorageKeys()").ExtractString());
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       SessionStorageAfterBackNavigation_KeepInitialProcess) {
  const GURL kInitialUrl = GetUrl("/prerender/session_storage.html");
  const GURL kPrerenderingUrl =
      GetUrl("/prerender/session_storage.html?prerendering=");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  RenderProcessHostImpl* initial_process_host =
      static_cast<RenderProcessHostImpl*>(current_frame_host()->GetProcess());
  // Increment the worker ref count of the renderer process to keep it alive
  // so it is reused on the back navigation below. The test checks that the
  // session storage state changed in the activated page is correctly propagated
  // after a back navigation that uses an existing renderer process.
  initial_process_host->IncrementWorkerRefCount();

  AddPrerender(kPrerenderingUrl);
  NavigatePrimaryPage(kPrerenderingUrl);

  EXPECT_EQ("initial", EvalJs(current_frame_host(),
                              "window.sessionKeysInPrerenderingchange")
                           .ExtractString());
  EXPECT_EQ(
      "activated, initial",
      EvalJs(current_frame_host(), "getSessionStorageKeys()").ExtractString());

  // Speculative fix for the test flakiness (crbug.com/1216038), which may be
  // caused by the delayed async IPC of Session Storage (StorageArea.Put()).
  EXPECT_TRUE(ExecJs(shell()->web_contents(),
                     "new Promise(resolve => requestIdleCallback(resolve));"));

  // Navigate back to the initial page.
  TestNavigationObserver observer(shell()->web_contents());
  shell()->GoBackOrForward(-1);
  observer.Wait();
  EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), kInitialUrl);

  EXPECT_EQ(
      "activated, initial",
      EvalJs(current_frame_host(), "getSessionStorageKeys()").ExtractString());
}

// Tests that prerender whose target_hint is "_blank" is using the same session
// storage across prerender navigations, and the initiator doesn't share the
// same storage.
IN_PROC_BROWSER_TEST_F(PrerenderTargetHintBrowserTest,
                       SessionStorage_TargetBlank_WithTargetHintBlank) {
  const GURL kInitialUrl = GetUrl("/prerender/session_storage.html");
  const GURL kPrerenderingUrl =
      GetUrl("/prerender/session_storage.html?prerendering=");

  // Navigate to an initial page which has a link to `kPrerenderingUrl`.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering `kPrerenderingUrl`.
  PrerenderHostId host_id = prerender_helper()->AddPrerender(
      kPrerenderingUrl, /*eagerness=*/std::nullopt, "_blank");
  auto* prerender_web_contents = static_cast<WebContentsImpl*>(
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id));
  ExpectWebContentsIsForNewTabPrerendering(*prerender_web_contents);
  auto* initiator_web_contents = web_contents_impl();
  ASSERT_NE(prerender_web_contents, initiator_web_contents);

  std::string prerender_session_storage_id_before_activation =
      FrameTreeNode::GloballyFindByID(
          PrerenderHost::GetFrameTreeNodeIdForId(host_id))
          ->frame_tree()
          .controller()
          .GetSessionStorageNamespace(prerender_web_contents->GetSiteInstance()
                                          ->GetSecurityPrincipal()
                                          .GetStoragePartitionConfig())
          ->id();
  EXPECT_EQ(
      "prerendering",
      EvalJs(content::test::PrerenderTestHelper::GetPrerenderedMainFrameHost(
                 *prerender_web_contents, host_id),
             "getSessionStorageKeys()")
          .ExtractString());

  // Click the link annotated with "target=_blank". This should activate the
  // prerendered page.
  TestNavigationObserver activation_observer(kPrerenderingUrl);
  activation_observer.WatchExistingWebContents();
  test::PrerenderHostObserver prerender_observer(*prerender_web_contents,
                                                 host_id);
  const std::string kLinkClickScript = R"(
      clickSameSiteNewWindowLink();
  )";
  EXPECT_TRUE(ExecJs(web_contents(), kLinkClickScript));
  activation_observer.WaitForNavigationFinished();
  EXPECT_EQ(prerender_web_contents->GetLastCommittedURL(), kPrerenderingUrl);
  EXPECT_EQ(activation_observer.last_navigation_url(), kPrerenderingUrl);
  EXPECT_TRUE(prerender_observer.was_activated());
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));

  // The initiator's session storage is expected to be different from the
  // prerender's.
  EXPECT_EQ("initial", EvalJs(initiator_web_contents->GetPrimaryMainFrame(),
                              "getSessionStorageKeys()")
                           .ExtractString());
  EXPECT_EQ("activated", EvalJs(prerender_web_contents->GetPrimaryMainFrame(),
                                "getSessionStorageKeys()")
                             .ExtractString());

  // The prerender session storage is expected to be the same across prerender
  // activation.
  EXPECT_EQ(
      prerender_session_storage_id_before_activation,
      prerender_web_contents->GetPrimaryFrameTree()
          .controller()
          .GetSessionStorageNamespace(prerender_web_contents->GetSiteInstance()
                                          ->GetSecurityPrincipal()
                                          .GetStoragePartitionConfig())
          ->id());
  EXPECT_NE(
      prerender_session_storage_id_before_activation,
      initiator_web_contents->GetPrimaryFrameTree()
          .controller()
          .GetSessionStorageNamespace(prerender_web_contents->GetSiteInstance()
                                          ->GetSecurityPrincipal()
                                          .GetStoragePartitionConfig())
          ->id());

  // The navigation occurred in a new WebContents, so the original WebContents
  // should still be showing the initial trigger page.
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);
}

// Test if the host is abandoned when the renderer page crashes.
IN_PROC_BROWSER_TEST_P(PrerenderBrowserTestFallbackEnabledDisabled,
                       AbandonIfRendererProcessCrashes) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start a prerender.
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);

  // Crash the relevant renderer.
  {
    test::PrerenderHostObserver host_observer(*web_contents_impl(), host_id);
    RenderProcessHost* process =
        GetPrerenderedMainFrameHost(host_id)->GetProcess();
    ScopedAllowRendererCrashes allow_renderer_crashes(process);
    process->ForceCrash();
    host_observer.WaitForDestroyed();
  }
  ExpectFinalStatusForSpeculationRule(
#if BUILDFLAG(IS_ANDROID)
      PrerenderFinalStatus::kRendererProcessKilled);
#else
      PrerenderFinalStatus::kRendererProcessCrashed);
#endif  // BUILDFLAG(IS_ANDROID)
}

// Test if the host is abandoned when the renderer page is killed.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, AbandonIfRendererProcessIsKilled) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start a prerender.
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);

  // Shut down the relevant renderer.
  {
    test::PrerenderHostObserver host_observer(*web_contents_impl(), host_id);
    RenderProcessHost* process =
        GetPrerenderedMainFrameHost(host_id)->GetProcess();
    ScopedAllowRendererCrashes allow_renderer_crashes(process);
    EXPECT_TRUE(process->Shutdown(0));
    host_observer.WaitForDestroyed();
  }

  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::kRendererProcessKilled);
}

// Test if the host is abandoned when the primary main page that triggers a
// prerendering is killed.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       AbandonIfPrimaryMainFrameRendererProcessIsKilled) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start a prerender.
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);

  // Shut down the current renderer.
  {
    test::PrerenderHostObserver host_observer(*web_contents_impl(), host_id);
    RenderProcessHost* process = current_frame_host()->GetProcess();
    ScopedAllowRendererCrashes allow_renderer_crashes(process);
    EXPECT_TRUE(process->Shutdown(0));
    host_observer.WaitForDestroyed();
  }

  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::kPrimaryMainFrameRendererProcessKilled);
}

class PrerenderBackForwardCacheBrowserTest : public PrerenderBrowserTest {
 public:
  PrerenderBackForwardCacheBrowserTest() {
    feature_list_.InitWithFeaturesAndParameters(
        {{::features::kBackForwardCache, {}},
         {kBackForwardCacheNoTimeEviction, {}}},
        // Allow BackForwardCache for all devices regardless of their memory.
        {::features::kBackForwardCacheMemoryControls});
  }

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

IN_PROC_BROWSER_TEST_F(PrerenderBackForwardCacheBrowserTest,
                       SessionStorageAfterBackNavigation) {
  const GURL kInitialUrl = GetUrl("/prerender/session_storage.html");
  const GURL kPrerenderingUrl =
      GetUrl("/prerender/session_storage.html?prerendering=");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  RenderFrameHostWrapper main_frame(
      shell()->web_contents()->GetPrimaryMainFrame());

  AddPrerender(kPrerenderingUrl);
  NavigatePrimaryPage(kPrerenderingUrl);

  EXPECT_EQ("initial", EvalJs(current_frame_host(),
                              "window.sessionKeysInPrerenderingchange")
                           .ExtractString());
  EXPECT_EQ(
      "activated, initial",
      EvalJs(current_frame_host(), "getSessionStorageKeys()").ExtractString());

  // Speculative fix for the test flakiness (crbug.com/1216038), which may be
  // caused by the delayed async IPC of Session Storage (StorageArea.Put()).
  EXPECT_TRUE(ExecJs(shell()->web_contents(),
                     "new Promise(resolve => requestIdleCallback(resolve));"));

  // Navigate back to the initial page.
  shell()->GoBackOrForward(-1);
  WaitForLoadStop(shell()->web_contents());

  // Expect the navigation to be served from the back-forward cache to verify
  // the test is testing what is intended.
  ASSERT_EQ(shell()->web_contents()->GetPrimaryMainFrame(), main_frame.get());

  EXPECT_EQ(
      "activated, initial",
      EvalJs(current_frame_host(), "getSessionStorageKeys()").ExtractString());
}

#if !BUILDFLAG(IS_ANDROID)
// The out-of-process StorageService is not implemented on Android. Also as
// commented below, test_api->CrashNow() won't work on x86 and x86_64 Android.

class PrerenderRestartStorageServiceBrowserTest : public PrerenderBrowserTest {
 public:
  PrerenderRestartStorageServiceBrowserTest() = default;

 protected:
  void CrashStorageServiceAndWaitForRestart() {
    mojo::Remote<storage::mojom::StorageService>& service =
        StoragePartitionImpl::GetStorageService();
    base::RunLoop loop;
    service.set_disconnect_handler(base::BindLambdaForTesting([&] {
      loop.Quit();
      service.reset();
    }));
    mojo::Remote<storage::mojom::TestApi> test_api;
    StoragePartitionImpl::GetStorageService()->BindTestApi(
        test_api.BindNewPipeAndPassReceiver().PassPipe());
    // On x86 and x86_64 Android, base::ImmediateCrash() macro used in
    // CrashNow() does not seem to work as expected. (See
    // https://crbug.com/1211655)
    test_api->CrashNow();
    loop.Run();
  }
};

IN_PROC_BROWSER_TEST_F(PrerenderRestartStorageServiceBrowserTest,
                       RestartStorageServiceBeforePrerendering) {
  const GURL kInitialUrl = GetUrl("/prerender/session_storage.html");
  const GURL kPrerenderingUrl =
      GetUrl("/prerender/session_storage.html?prerendering=");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  CrashStorageServiceAndWaitForRestart();

  EXPECT_EQ(
      "initial",
      EvalJs(current_frame_host(), "getSessionStorageKeys()").ExtractString());

  AddPrerender(kPrerenderingUrl);
  NavigatePrimaryPage(kPrerenderingUrl);

  EXPECT_EQ("initial", EvalJs(current_frame_host(),
                              "window.sessionKeysInPrerenderingchange")
                           .ExtractString());
  EXPECT_EQ(
      "activated, initial",
      EvalJs(current_frame_host(), "getSessionStorageKeys()").ExtractString());
}

IN_PROC_BROWSER_TEST_F(PrerenderRestartStorageServiceBrowserTest,
                       RestartStorageServiceWhilePrerendering) {
  const GURL kInitialUrl = GetUrl("/prerender/session_storage.html");
  const GURL kPrerenderingUrl =
      GetUrl("/prerender/session_storage.html?prerendering=");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);

  CrashStorageServiceAndWaitForRestart();

  EXPECT_EQ(
      "initial",
      EvalJs(current_frame_host(), "getSessionStorageKeys()").ExtractString());
  EXPECT_EQ(
      "initial, prerendering",
      EvalJs(GetPrerenderedMainFrameHost(host_id), "getSessionStorageKeys()")
          .ExtractString());

  NavigatePrimaryPage(kPrerenderingUrl);

  EXPECT_EQ("initial", EvalJs(current_frame_host(),
                              "window.sessionKeysInPrerenderingchange")
                           .ExtractString());
  EXPECT_EQ(
      "activated, initial",
      EvalJs(current_frame_host(), "getSessionStorageKeys()").ExtractString());
}
#endif

// Make sure that we can deal with the speculative RFH that is created during
// the activation navigation.
// TODO(crbug.com/40174053): We should try to avoid creating the
// speculative RFH (redirects allowing). Once that is done we should either
// change this test (if redirects allowed) or remove it completely.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, SpeculationRulesScript) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);

  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 0);
  AddPrerender(kPrerenderingUrl);
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);

  // A prerender host for the URL should be registered.
  EXPECT_TRUE(HasHostForUrl(kPrerenderingUrl));

  // Activate the prerendered page.
  // The test passes if we don't crash while cleaning up speculative render
  // frame host.
  NavigatePrimaryPage(kPrerenderingUrl);
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);

  // The prerender host should be consumed.
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));

  // Activating the prerendered page should not issue a request.
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
}

class PrerenderEagernessBrowserTest : public PrerenderBrowserTest {
 public:
  void SetUp() override {
#if !BUILDFLAG(IS_ANDROID)
    sub_feature_list_.InitAndEnableFeatureWithParameters(
        blink::features::kPreloadingEagerHoverHeuristics,
        {{"hover_dwell_time", "50ms"}});
    PrerenderBrowserTest::SetUp();
#else
    // TODO(crbug.com/453705264): Add browser tests for viewport-based
    // predictors.
    // TODO(crbug.com/40269669): Add the implementation of pointer interaction
    // on Android to the function below.
    GTEST_SKIP();
#endif  // BUILDFLAG(IS_ANDROID)
  }

  void TearDown() override {
    PrerenderBrowserTest::TearDown();
    sub_feature_list_.Reset();
  }

 private:
  base::test::ScopedFeatureList sub_feature_list_;
};

namespace {

class PreloadingDeciderObserverForPrerenderTesting
    : public PreloadingDeciderObserverForTesting {
 public:
  explicit PreloadingDeciderObserverForPrerenderTesting(
      RenderFrameHostImpl& rfh)
      : rfh_(rfh.GetWeakPtr()) {
    auto* preloading_decider =
        PreloadingDecider::GetOrCreateForCurrentDocument(rfh_.get());
    old_observer_ = preloading_decider->SetObserverForTesting(this);
    events_called_.fill(false);
  }
  ~PreloadingDeciderObserverForPrerenderTesting() override {
    if (!rfh_) {
      // The old document (the initiator document) has been destroyed, and the
      // associated data has been destroyed as well. Also reset old_observer_ to
      // avoid hanging pointer.
      old_observer_ = nullptr;
      return;
    }
    auto* preloading_decider =
        PreloadingDecider::GetOrCreateForCurrentDocument(rfh_.get());
    EXPECT_EQ(this, preloading_decider->SetObserverForTesting(old_observer_));
  }

  void UpdateSpeculationCandidates(
      const std::vector<blink::mojom::SpeculationCandidatePtr>& candidates)
      override {
    OnEventCalled(Events::kUpdateSpeculationCandidates);
  }

  void OnPointerHover(
      const GURL& url,
      blink::mojom::SpeculationEagerness target_eagerness) override {
    OnEventCalled(Events::kOnPointerHover);
  }

  void OnPointerDown(const GURL& url) override {
    OnEventCalled(Events::kOnPointerDown);
  }

  void WaitUpdateSpeculationCandidates() {
    WaitEvent(Events::kUpdateSpeculationCandidates);
  }

  void WaitOnPointerHover() { WaitEvent(Events::kOnPointerHover); }

  void WaitOnPointerDown() { WaitEvent(Events::kOnPointerDown); }

 private:
  enum Events {
    kUpdateSpeculationCandidates = 0,
    kOnPointerHover,
    kOnPointerDown,
    kMaxValue = kOnPointerDown,
  };

  void WaitEvent(Events event) {
    if (events_called_[event]) {
      return;
    }
    ASSERT_FALSE(quit_closures_[event]);
    base::RunLoop loop;
    quit_closures_[event] = loop.QuitClosure();
    loop.Run();
  }

  void OnEventCalled(Events event) {
    events_called_[event] = true;
    if (quit_closures_[event]) {
      base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
          FROM_HERE, std::move(quit_closures_[event]));
    }
  }

  base::WeakPtr<RenderFrameHostImpl> rfh_;
  raw_ptr<PreloadingDeciderObserverForTesting> old_observer_;

  std::array<base::OnceClosure, Events::kMaxValue + 1> quit_closures_;
  std::array<bool, Events::kMaxValue + 1> events_called_;
};

}  // namespace

// Tests speculation rules prerendering where the eagerness is "immediate".
// The default eagerness of list rules is "immediate", so its behavior should be
// same to normal speculation rules prerendering.
IN_PROC_BROWSER_TEST_F(PrerenderEagernessBrowserTest, kImmediate) {
  const GURL initial_url = GetUrl("/empty.html");
  const GURL prerendering_url = GetUrl("/empty.html?prerender");

  // Navigate to an initial page, insert an anchor to the prerender page.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  InsertAnchor(prerendering_url);

  RenderFrameHostImpl* rfh = current_frame_host();
  auto* preloading_decider =
      PreloadingDecider::GetOrCreateForCurrentDocument(rfh);

  // Add speculation rules with the eagerness.
  // When the eagerness is "immediate", speculation candidates will never be
  // kept in the |on_standby_candidates_| on |PreloadingDecider|, and
  // |PrerenderHost| will be created immediately.
  AddPrerenderWithEagernessAsync(
      prerendering_url, blink::mojom::SpeculationEagerness::kImmediate);
  WaitForPrerenderLoadCompletion(prerendering_url);
  EXPECT_TRUE(HasHostForUrl(prerendering_url));
  EXPECT_FALSE(preloading_decider->IsOnStandByForTesting(
      prerendering_url, blink::mojom::SpeculationAction::kPrerender));

  // Activate the prerendered page by clicking the anchor.
  PrerenderHostId host_id = GetHostForUrl(prerendering_url);
  test::PrerenderHostObserver prerender_observer(*web_contents(), host_id);
  PointerDownToAnchor(prerendering_url);
  PointerUpToAnchor(prerendering_url);
  prerender_observer.WaitForActivation();
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), prerendering_url);
  EXPECT_TRUE(prerender_observer.was_activated());
}

// Tests speculation rules prerendering where the eagerness is "eager".
// Unless `kPreloadingEagerHoverHeuristics` is enabled, its behavior is the same
// as that of "immediate"; otherwise, there are dedicated rules to activate
// speculative loads.
IN_PROC_BROWSER_TEST_F(PrerenderEagernessBrowserTest, kEager) {
  const GURL initial_url = GetUrl("/empty.html");
  const GURL prerendering_url = GetUrl("/empty.html?prerender");

  // Navigate to an initial page, insert an anchor to the prerender page.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  InsertAnchor(prerendering_url);

  if (base::FeatureList::IsEnabled(
          blink::features::kPreloadingEagerHoverHeuristics)) {
    const base::TimeDelta moderate_hover_time = base::Milliseconds(200);
    const base::TimeDelta eager_hover_time =
        blink::features::kPreloadingEagerHoverHeuristicsDwellTime.Get();
    ASSERT_LE(eager_hover_time, moderate_hover_time);
    // Use `eager_hover_time` + eps. The median time can cause flakiness.
    const base::TimeDelta mid_hover_time =
        eager_hover_time + (moderate_hover_time - eager_hover_time) / 10;

    RenderFrameHostImpl* rfh = current_frame_host();
    ASSERT_TRUE(rfh);
    PreloadingDeciderObserverForPrerenderTesting preloading_decider_observer(
        *rfh);
    auto* preloading_decider =
        PreloadingDecider::GetOrCreateForCurrentDocument(rfh);
    // Add speculation rules with the "eager" eagerness.
    // When the eagerness is not "immediate", speculation candidates will be
    // kept in the |on_standby_candidates_| on |PreloadingDecider|.
    // |PrerenderHost| will not be created at this time, waiting for user
    // interaction(pointer hovering for the "eager").
    AddPrerenderWithEagernessAsync(prerendering_url,
                                   blink::mojom::SpeculationEagerness::kEager);
    preloading_decider_observer.WaitUpdateSpeculationCandidates();
    EXPECT_FALSE(HasHostForUrl(prerendering_url));
    EXPECT_TRUE(preloading_decider->IsOnStandByForTesting(
        prerendering_url, blink::mojom::SpeculationAction::kPrerender));
    // Hover the anchor of the prerendering page. When eagerness is "eager" with
    // `kPreloadingEagerHoverHeuristics` enabled, this interaction invokes the
    // creation of |PrerenderHost|.
    // TODO(crbug.com/435622290): Test this on Mac
#if !BUILDFLAG(IS_MAC)
    ASSERT_GT(eager_hover_time, base::Milliseconds(0));
    // Hover very briefly so that prerender is not triggered.
    PointerHoverToAnchor(prerendering_url, eager_hover_time / 10);
    EXPECT_TRUE(preloading_decider->IsOnStandByForTesting(
        prerendering_url, blink::mojom::SpeculationAction::kPrerender));
#endif  // !BUILDFLAG(IS_MAC)
    // Hover enough time so that prerender is triggered for "eager".
    PointerHoverToAnchor(prerendering_url, mid_hover_time);
    preloading_decider_observer.WaitOnPointerHover();
    WaitForPrerenderLoadCompletion(prerendering_url);
    EXPECT_TRUE(HasHostForUrl(prerendering_url));
    EXPECT_FALSE(preloading_decider->IsOnStandByForTesting(
        prerendering_url, blink::mojom::SpeculationAction::kPrerender));
  } else {
    RenderFrameHostImpl* rfh = current_frame_host();
    auto* preloading_decider =
        PreloadingDecider::GetOrCreateForCurrentDocument(rfh);
    // Add speculation rules with the "eager" eagerness.
    // With `kPreloadingEagerHoverHeuristics` disabled, the eagerness is the
    // same as "immediate", speculation candidates will never be kept in the
    // |on_standby_candidates_| on |PreloadingDecider|, and |PrerenderHost| will
    // be created immediately.
    AddPrerenderWithEagernessAsync(prerendering_url,
                                   blink::mojom::SpeculationEagerness::kEager);
    WaitForPrerenderLoadCompletion(prerendering_url);
    EXPECT_TRUE(HasHostForUrl(prerendering_url));
    EXPECT_FALSE(preloading_decider->IsOnStandByForTesting(
        prerendering_url, blink::mojom::SpeculationAction::kPrerender));
  }

  // Activate the prerendered page by clicking the anchor.
  PrerenderHostId host_id = GetHostForUrl(prerendering_url);
  test::PrerenderHostObserver prerender_observer(*web_contents(), host_id);
  PointerDownToAnchor(prerendering_url);
  PointerUpToAnchor(prerendering_url);
  prerender_observer.WaitForActivation();
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), prerendering_url);
  EXPECT_TRUE(prerender_observer.was_activated());
}

// Tests speculation rules prerendering where the eagerness is "moderate".
IN_PROC_BROWSER_TEST_F(PrerenderEagernessBrowserTest, kModerate) {
  const GURL initial_url = GetUrl("/empty.html");
  const GURL prerendering_url = GetUrl("/empty.html?prerender");

  // Navigate to an initial page, insert an anchor to the prerender page.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  InsertAnchor(prerendering_url);

  RenderFrameHostImpl* rfh = current_frame_host();
  ASSERT_TRUE(rfh);
  PreloadingDeciderObserverForPrerenderTesting preloading_decider_observer(
      *rfh);
  auto* preloading_decider =
      PreloadingDecider::GetOrCreateForCurrentDocument(rfh);

  // Add speculation rules with the eagerness.
  // When the eagerness is not "immediate", speculation candidates will be kept
  // in the |on_standby_candidates_| on |PreloadingDecider|. |PrerenderHost|
  // will not be created at this time, waiting for user interaction(pointer
  // hovering for the "moderate").
  AddPrerenderWithEagernessAsync(prerendering_url,
                                 blink::mojom::SpeculationEagerness::kModerate);
  preloading_decider_observer.WaitUpdateSpeculationCandidates();
  EXPECT_FALSE(HasHostForUrl(prerendering_url));
  EXPECT_TRUE(preloading_decider->IsOnStandByForTesting(
      prerendering_url, blink::mojom::SpeculationAction::kPrerender));

  // Hover the anchor of the prerendering page so briefly that only the hover
  // event for "eager" is triggered but not triggered for "moderate".
  // TODO(crbug.com/490489040): Test this on Mac. Hovering on Mac is flaky now.
#if !BUILDFLAG(IS_MAC)
  if (base::FeatureList::IsEnabled(
          blink::features::kPreloadingEagerHoverHeuristics)) {
    const base::TimeDelta moderate_hover_time = base::Milliseconds(200);
    const base::TimeDelta eager_hover_time =
        blink::features::kPreloadingEagerHoverHeuristicsDwellTime.Get();
    // Use `eager_hover_time` + eps. The median time can cause flakiness.
    const base::TimeDelta mid_hover_time =
        eager_hover_time + (moderate_hover_time - eager_hover_time) / 10;
    ASSERT_LT(mid_hover_time, moderate_hover_time);
    PointerHoverToAnchor(prerendering_url, mid_hover_time);
    preloading_decider_observer.WaitOnPointerHover();
    EXPECT_FALSE(HasHostForUrl(prerendering_url));
    EXPECT_TRUE(preloading_decider->IsOnStandByForTesting(
        prerendering_url, blink::mojom::SpeculationAction::kPrerender));
  }
#endif  // !BUILDFLAG(IS_MAC)

  // Hover the anchor of the prerendering page for a long enough time. When
  // eagerness is "moderate", this interaction invokes the creation of
  // |PrerenderHost|.
  PointerHoverToAnchor(prerendering_url);
  preloading_decider_observer.WaitOnPointerHover();
  WaitForPrerenderLoadCompletion(prerendering_url);
  EXPECT_TRUE(HasHostForUrl(prerendering_url));
  EXPECT_FALSE(preloading_decider->IsOnStandByForTesting(
      prerendering_url, blink::mojom::SpeculationAction::kPrerender));

  // Activate the prerendered page by clicking the anchor.
  PrerenderHostId host_id = GetHostForUrl(prerendering_url);
  test::PrerenderHostObserver prerender_observer(*web_contents(), host_id);
  PointerDownToAnchor(prerendering_url);
  PointerUpToAnchor(prerendering_url);
  prerender_observer.WaitForActivation();
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), prerendering_url);
  EXPECT_TRUE(prerender_observer.was_activated());
}

// Tests speculation rules prerendering where the eagerness is "conservative".
IN_PROC_BROWSER_TEST_F(PrerenderEagernessBrowserTest, kConservative) {
  const GURL initial_url = GetUrl("/empty.html");
  const GURL prerendering_url = GetUrl("/empty.html?prerender");

  // Navigate to an initial page, insert an anchor to the prerender page.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  InsertAnchor(prerendering_url);

  RenderFrameHostImpl* rfh = current_frame_host();
  ASSERT_TRUE(rfh);
  PreloadingDeciderObserverForPrerenderTesting preloading_decider_observer(
      *rfh);
  auto* preloading_decider =
      PreloadingDecider::GetOrCreateForCurrentDocument(rfh);

  // Add speculation rules with the eagerness.
  // When the eagerness is not "immediate", speculation candidates will be kept
  // in the |on_standby_candidates_| on |PreloadingDecider|. |PrerenderHost|
  // will not be created at this time, waiting for user interaction(pointer
  // clicking for the "conservative").
  AddPrerenderWithEagernessAsync(
      prerendering_url, blink::mojom::SpeculationEagerness::kConservative);
  preloading_decider_observer.WaitUpdateSpeculationCandidates();
  EXPECT_FALSE(HasHostForUrl(prerendering_url));
  EXPECT_TRUE(preloading_decider->IsOnStandByForTesting(
      prerendering_url, blink::mojom::SpeculationAction::kPrerender));

  // Click the anchor of the prerendering page. When eagerness is
  // "conservative", PointerDown interaction invokes the creation of
  // |PrerenderHost| and this host will be activated on the navigation triggered
  // by the series of actions(PointerDown, PointerUp) on clicking.
  PointerDownToAnchor(prerendering_url);
  preloading_decider_observer.WaitOnPointerDown();
  WaitForPrerenderLoadCompletion(prerendering_url);
  EXPECT_TRUE(HasHostForUrl(prerendering_url));
  EXPECT_FALSE(preloading_decider->IsOnStandByForTesting(
      prerendering_url, blink::mojom::SpeculationAction::kPrerender));

  PrerenderHostId host_id = GetHostForUrl(prerendering_url);
  test::PrerenderHostObserver prerender_observer(*web_contents(), host_id);
  PointerUpToAnchor(prerendering_url);
  prerender_observer.WaitForActivation();
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), prerendering_url);
  EXPECT_TRUE(prerender_observer.was_activated());
}

// TODO(crbug.com/40275452): These tests are turned off on Fuchsia and iOS
// tentatively because pointer simulation on them doesn't work properly on this
// test.
#if !BUILDFLAG(IS_FUCHSIA) && !BUILDFLAG(IS_IOS)
// Tests the metrics
// Prerender.Experimental.ReceivedPrerendersPerPrimaryPageChangedCount2
// correctly records the number of prerenders by each category per primary page
// changed.
IN_PROC_BROWSER_TEST_F(PrerenderEagernessBrowserTest,
                       ReceivedPrerendersPerPrimaryPageChangedCount) {
  auto GetAllSamples = [&](const std::string& eagerness_category) {
    return histogram_tester().GetAllSamples(
        "Prerender.Experimental.ReceivedPrerendersPerPrimaryPageChangedCount2."
        "SpeculationRule." +
        eagerness_category);
  };

  // Navigate to an initial page,
  const GURL initial_url = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Nothing should have been recoreded yet.
  EXPECT_THAT(GetAllSamples("Total"), testing::IsEmpty());

  // Start one immediate prerender.
  const GURL prerendering_url = GetUrl("/empty.html?prerender");
  AddPrerender(prerendering_url);

  // Navigate to the another url.
  // Expect that the categories "Total" and "Immediate2" record 1 and others
  // record 0, as there was one immediate prerender of the previous page.
  const GURL next_url = GetUrl("/empty.html?next");
  ASSERT_TRUE(NavigateToURL(shell(), next_url));
  EXPECT_THAT(GetAllSamples("Conservative"),
              base::BucketsAre(base::Bucket(0, 1)));
  EXPECT_THAT(GetAllSamples("Moderate"), base::BucketsAre(base::Bucket(0, 1)));
  EXPECT_THAT(GetAllSamples("Eager2"), base::BucketsAre(base::Bucket(0, 1)));
  EXPECT_THAT(GetAllSamples("Immediate2"),
              base::BucketsAre(base::Bucket(1, 1)));

  // Next, try to trigger followings:
  // a) 4 prerenders whose eagerness is immediate
  // b) 2 prerenders whose eagerness is eager
  // c) 2 prerenders whose eagerness is moderate
  // d) 1 prerenders whose eagerness is conservative
  // Then, try to activate the one of the URL(choosing conservative one).

  // a)
  for (int i = 0; i < 4; ++i) {
    GURL prerendering_url_immediate =
        GetUrl("/empty.html?prerender_immediate_" + base::NumberToString(i));
    AddPrerender(prerendering_url_immediate);
  }

  // b)
  for (int i = 0; i < 2; ++i) {
    GURL prerendering_url_eager =
        GetUrl("/empty.html?prerender_eager_" + base::NumberToString(i));
    if (base::FeatureList::IsEnabled(
            blink::features::kPreloadingEagerHoverHeuristics)) {
      InsertAnchor(prerendering_url_eager);
      AddPrerenderWithEagernessAsync(
          prerendering_url_eager, blink::mojom::SpeculationEagerness::kEager);
      PointerHoverToAnchor(prerendering_url_eager);
      WaitForPrerenderLoadCompletion(prerendering_url_eager);
    } else {
      AddPrerender(prerendering_url_eager);
    }
  }

  // c)
  for (int i = 0; i < 2; ++i) {
    GURL prerendering_url_moderate =
        GetUrl("/empty.html?prerender_moderate_" + base::NumberToString(i));
    InsertAnchor(prerendering_url_moderate);
    AddPrerenderWithEagernessAsync(
        prerendering_url_moderate,
        blink::mojom::SpeculationEagerness::kModerate);
    PointerHoverToAnchor(prerendering_url_moderate);
    WaitForPrerenderLoadCompletion(prerendering_url_moderate);
  }

  // d)
  const GURL prerendering_url_conservative =
      GetUrl("/empty.html?prerender_conservative");
  InsertAnchor(prerendering_url_conservative);
  AddPrerenderWithEagernessAsync(
      prerendering_url_conservative,
      blink::mojom::SpeculationEagerness::kConservative);

  // Try to trigger and activate.
  TestActivationManager activation_manager(web_contents(),
                                           prerendering_url_conservative);
  ClickAnchor(prerendering_url_conservative);
  activation_manager.WaitForNavigationFinished();
  ASSERT_EQ(web_contents()->GetLastCommittedURL(),
            prerendering_url_conservative);
  ASSERT_TRUE(activation_manager.was_activated());

  // Expect our results:
  EXPECT_THAT(GetAllSamples("Immediate2"),
              base::BucketsAre(base::Bucket(1, 1), base::Bucket(4, 1)));
  EXPECT_THAT(GetAllSamples("Eager2"),
              base::BucketsAre(base::Bucket(0, 1), base::Bucket(2, 1)));
  EXPECT_THAT(GetAllSamples("Moderate"),
              base::BucketsAre(base::Bucket(0, 1), base::Bucket(2, 1)));
  EXPECT_THAT(GetAllSamples("Conservative"),
              base::BucketsAre(base::Bucket(0, 1), base::Bucket(1, 1)));
}

IN_PROC_BROWSER_TEST_F(PrerenderEagernessBrowserTest,
                       NonImmediatePrerendersCanBeRetriggeredAfterTimeout) {
  // Navigate to an initial page.
  const GURL initial_url = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Add a non-immediate speculation rule.
  const GURL prerendering_url = GetUrl("/empty.html?prerender");
  InsertAnchor(prerendering_url);
  AddPrerenderWithEagernessAsync(prerendering_url,
                                 blink::mojom::SpeculationEagerness::kModerate);

  // Start prerendering.
  test::PrerenderHostCreationWaiter host_creation_waiter_a;
  PointerHoverToAnchor(prerendering_url);
  PrerenderHostId host_id_a = host_creation_waiter_a.Wait();
  test::PrerenderHostObserver prerender_observer_a(*web_contents_impl(),
                                                   host_id_a);

  PrerenderHostRegistry* prerender_host_registry =
      web_contents_impl()->GetPrerenderHostRegistry();
  ASSERT_FALSE(prerender_host_registry->GetSpeculationRulesTimerForTesting()
                   ->IsRunning());

  // Inject mock time task runner.
  auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
  prerender_host_registry->SetTaskRunnerForTesting(task_runner);

  // Change the visibility to hidden and advance the timer. Prerendered page is
  // cancelced by timeout.
  web_contents()->WasHidden();
  ASSERT_TRUE(prerender_host_registry->GetSpeculationRulesTimerForTesting()
                  ->IsRunning());
  task_runner->FastForwardBy(
      PrerenderHostRegistry::kTimeToLiveInBackgroundForSpeculationRules);
  ASSERT_FALSE(prerender_host_registry->GetSpeculationRulesTimerForTesting()
                   ->IsRunning());
  prerender_observer_a.WaitForDestroyed();
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kTimeoutBackgrounded, 1);

  // Changing the visibility to shown.
  web_contents()->WasShown();

  // Start prerendering again.
  test::PrerenderHostCreationWaiter host_creation_waiter_b;
  PointerHoverToAnchor(prerendering_url);
  PrerenderHostId host_id_b = host_creation_waiter_b.Wait();
  test::PrerenderHostObserver prerender_observer_b(*web_contents(), host_id_b);

  NavigatePrimaryPage(prerendering_url);
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), prerendering_url);
  EXPECT_TRUE(prerender_observer_b.was_activated());
}

IN_PROC_BROWSER_TEST_P(PrerenderTargetAgnosticBrowserTest,
                       ResetForNonImmediatePrerender) {
#if !BUILDFLAG(IS_ANDROID)
  const GURL initial_url = GetUrl("/empty.html");
  std::vector<GURL> prerendering_urls;
  std::vector<base::WeakPtr<WebContents>> prerender_web_contents_list;

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Add moderate prerenders as many times as limit + 1 and trigger all of them
  // by hovering their links. All prerenders should be started at the time of
  // hovering, and the oldest started prerender should be canceled and removed
  // from the registry for the limit after the last prerender is started.
  int num_of_attempts =
      PrerenderHostRegistry::kMaxRunningSpeculationRulesNonImmediatePrerenders +
      1;
  for (int i = 0; i < num_of_attempts; i++) {
    ASSERT_TRUE(current_frame_host());
    PreloadingDeciderObserverForPrerenderTesting preloading_decider_observer(
        *current_frame_host());
    const GURL prerendering_url =
        GetUrl("/empty.html?prerender" + base::ToString(i));
    prerendering_urls.push_back(prerendering_url);
    InsertAnchor(prerendering_url);
    AddPrerendersAsync({prerendering_url},
                       blink::mojom::SpeculationEagerness::kModerate,
                       GetTargetHint());
    preloading_decider_observer.WaitUpdateSpeculationCandidates();

    test::PrerenderHostCreationWaiter host_creation_waiter;
    PointerHoverToAnchor(prerendering_url);
    PrerenderHostId host_id = host_creation_waiter.Wait();
    auto* prerender_web_contents =
        test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
    prerender_web_contents_list.push_back(prerender_web_contents->GetWeakPtr());
    test::PrerenderTestHelper::WaitForPrerenderLoadCompletion(
        *prerender_web_contents, prerendering_url);
  }

  for (int i = 0; i < num_of_attempts; i++) {
    bool host_existing_in_registry =
        prerender_web_contents_list[i] &&
        HasHostForUrl(*prerender_web_contents_list[i], prerendering_urls[i]);
    if (i == 0) {
      // The first (= oldest) prerender is removed since the (limit + 1)-th
      // prerender was started.
      ASSERT_FALSE(host_existing_in_registry);
    } else {
      ASSERT_TRUE(host_existing_in_registry);
    }
  }

  // Hover the first link again. This should be retriggered.
  const auto& prerendering_url_first = prerendering_urls[0];
  test::PrerenderHostCreationWaiter host_creation_waiter;
  PointerHoverToAnchor(prerendering_url_first);
  PrerenderHostId host_id = host_creation_waiter.Wait();
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  prerender_web_contents_list[0] = prerender_web_contents->GetWeakPtr();
  test::PrerenderTestHelper::WaitForPrerenderLoadCompletion(
      *prerender_web_contents, prerendering_url_first);

  // The oldest prerender in registry at this point should be removed due to the
  // limit.
  for (int i = 0; i < num_of_attempts; i++) {
    bool host_existing_in_registry =
        prerender_web_contents_list[i] &&
        HasHostForUrl(*prerender_web_contents_list[i], prerendering_urls[i]);
    if (i == 1) {
      EXPECT_FALSE(host_existing_in_registry);
    } else {
      EXPECT_TRUE(host_existing_in_registry);
    }
  }
#else
  // TODO(crbug.com/40269669): Android doesn't support pointer interaction.
  GTEST_SKIP();
#endif  // BUILDFLAG(IS_ANDROID)
}
#endif  // !BUILDFLAG(IS_FUCHSIA) && !BUILDFLAG(IS_IOS)

class PrerenderWithBackForwardCacheBrowserTest
    : public PrerenderBrowserTest,
      public testing::WithParamInterface<BackForwardCacheType> {
 public:
  PrerenderWithBackForwardCacheBrowserTest() {
    switch (GetParam()) {
      case BackForwardCacheType::kDisabled:
        feature_list_.InitAndDisableFeature(::features::kBackForwardCache);
        break;
      case BackForwardCacheType::kEnabled:
        feature_list_.InitWithFeaturesAndParameters(
            GetDefaultEnabledBackForwardCacheFeaturesForTesting(
                /*ignore_outstanding_network_request=*/false),
            GetDefaultDisabledBackForwardCacheFeaturesForTesting());
        break;
    }
  }

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

INSTANTIATE_TEST_SUITE_P(All,
                         PrerenderWithBackForwardCacheBrowserTest,
                         testing::Values(BackForwardCacheType::kDisabled,
                                         BackForwardCacheType::kEnabled),
                         ToString);

// Tests that history navigation works after activation. This runs with variaous
// BFCache configurations that may modify behavior of history navigation.
// This is a regression test for https://crbug.com/1201914.
IN_PROC_BROWSER_TEST_P(PrerenderWithBackForwardCacheBrowserTest,
                       HistoryNavigationAfterActivation) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  RenderFrameHostImpl* initial_frame_host = current_frame_host();
  blink::LocalFrameToken initial_frame_token =
      initial_frame_host->GetFrameToken();

  // When the BFCache is disabled, activation will destroy the initial frame
  // host. This observer will be used for confirming it.
  RenderFrameDeletedObserver delete_observer(initial_frame_host);

  // Make and activate a prerendered page.
  AddPrerender(kPrerenderingUrl);
  NavigatePrimaryPage(kPrerenderingUrl);
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);

  // Check if the initial page is in the BFCache.
  switch (GetParam()) {
    case BackForwardCacheType::kDisabled:
      EXPECT_NE(current_frame_host(), initial_frame_host);
      // The initial frame host should be deleted after activation because it is
      // not cached in the BFCache.
      delete_observer.WaitUntilDeleted();
      break;
    case BackForwardCacheType::kEnabled:
      // Same-origin prerender activation should allow the initial page to be
      // cached in the BFCache.
      ASSERT_TRUE(IsBackForwardCacheEnabled());
      EXPECT_TRUE(initial_frame_host->IsInBackForwardCache());
      break;
  }

  // Navigate back to the initial page.
  TestNavigationObserver observer(web_contents());
  shell()->GoBackOrForward(-1);
  observer.Wait();
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Check if the back navigation is served from the BFCache.
  switch (GetParam()) {
    case BackForwardCacheType::kDisabled:
      // The frame host should be created again.
      EXPECT_NE(current_frame_host()->GetFrameToken(), initial_frame_token);
      break;
    case BackForwardCacheType::kEnabled:
      // The frame host should be restored.
      EXPECT_EQ(current_frame_host()->GetFrameToken(), initial_frame_token);
      EXPECT_FALSE(initial_frame_host->IsInBackForwardCache());
      break;
  }
}

// Tests that a trigger page destroys a prerendered page when it navigates
// forward and goes into the back/forward cache.
IN_PROC_BROWSER_TEST_P(PrerenderWithBackForwardCacheBrowserTest,
                       CancelOnAfterTriggerIsStoredInBackForwardCache_Forward) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kNextUrl = GetUrl("/empty.html?next");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  RenderFrameHostImplWrapper initial_frame_host(current_frame_host());

  // Make a prerendered page from the initial page.
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  test::PrerenderHostObserver prerender_observer(*web_contents_impl(), host_id);

  // Navigate the initial page to a non-prerendered page.
  ASSERT_TRUE(NavigateToURL(shell(), kNextUrl));

  // Check if the initial page is in the back/forward cache.
  switch (GetParam()) {
    case BackForwardCacheType::kDisabled:
      // The BFCache is disabled, so the initial page is not in the
      // back/forward cache.
      if (ShouldCreateNewHostForAllFrames()) {
        ASSERT_TRUE(initial_frame_host.WaitUntilRenderFrameDeleted());
      } else {
        ASSERT_FALSE(initial_frame_host->IsInBackForwardCache());
      }
      break;
    case BackForwardCacheType::kEnabled:
      // The back/forward cache is enabled, so the initial page is in the
      // back/forward cache after the same-origin navigation.
      ASSERT_TRUE(IsBackForwardCacheEnabled());
      ASSERT_TRUE(initial_frame_host->IsInBackForwardCache());
      break;
  }

  // The navigation should destroy the prerendered page regardless of if the
  // initial page was in the back/forward cache.
  prerender_observer.WaitForDestroyed();
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kTriggerDestroyed);
}

// Tests that a trigger page destroys a prerendered page when it navigates back
// and goes into the BFCache.
IN_PROC_BROWSER_TEST_P(PrerenderWithBackForwardCacheBrowserTest,
                       CancelOnAfterTriggerIsStoredInBackForwardCache_Back) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kNextUrl = GetUrl("/empty.html?next");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Navigate to a next page.
  ASSERT_TRUE(NavigateToURL(shell(), kNextUrl));
  RenderFrameHostImplWrapper next_frame_host(current_frame_host());

  // Make a prerendered page from the next page.
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  test::PrerenderHostObserver prerender_observer(*web_contents_impl(), host_id);

  // Navigate back to the initial page.
  TestNavigationObserver navigation_observer(web_contents());
  shell()->GoBackOrForward(-1);
  navigation_observer.Wait();
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Check if the next page is in the back/forward cache.
  switch (GetParam()) {
    case BackForwardCacheType::kDisabled:
      // The back/forward cache is disabled, so the next page is not in the
      // back/forward cache.
      if (ShouldCreateNewHostForAllFrames()) {
        ASSERT_TRUE(next_frame_host.WaitUntilRenderFrameDeleted());
      } else {
        ASSERT_FALSE(next_frame_host->IsInBackForwardCache());
      }
      break;
    case BackForwardCacheType::kEnabled:
      // The back/forward cache is enabled, so the next page is in the
      // back/forward cache after the same-origin back navigation.
      ASSERT_TRUE(IsBackForwardCacheEnabled());
      ASSERT_TRUE(next_frame_host->IsInBackForwardCache());
      break;
  }

  // The navigation should destroy the prerendered page regardless of if the
  // next page was in the back/forward cache.
  prerender_observer.WaitForDestroyed();
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kTriggerDestroyed);
}

class PrerenderBackForwardCacheRestorationBrowserTest
    : public PrerenderEagernessBrowserTest,
      public BackForwardCacheMetricsTestMatcher,
      public testing::WithParamInterface<blink::mojom::SpeculationEagerness> {
 public:
  PrerenderBackForwardCacheRestorationBrowserTest() {
    feature_list_.InitWithFeaturesAndParameters(
        GetDefaultEnabledBackForwardCacheFeaturesForTesting(
            /*ignore_outstanding_network_request=*/false),
        GetDefaultDisabledBackForwardCacheFeaturesForTesting());
  }

 protected:
  blink::mojom::SpeculationEagerness GetSpeculationEagerness() const {
    return GetParam();
  }

  // implementation for `BackForwardCacheMetricsTestMatcher`
  const ukm::TestAutoSetUkmRecorder& ukm_recorder() override {
    return *PrerenderBrowserTest::test_ukm_recorder();
  }

  // implementation for `BackForwardCacheMetricsTestMatcher`
  const base::HistogramTester& histogram_tester() override {
    return PrerenderBrowserTest::histogram_tester();
  }

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

INSTANTIATE_TEST_SUITE_P(
    All,
    PrerenderBackForwardCacheRestorationBrowserTest,
    testing::Values(blink::mojom::SpeculationEagerness::kImmediate,
                    blink::mojom::SpeculationEagerness::kEager,
                    blink::mojom::SpeculationEagerness::kModerate,
                    blink::mojom::SpeculationEagerness::kConservative),
    [](const testing::TestParamInfo<blink::mojom::SpeculationEagerness>& info) {
      return base::ToString(info.param);
    });

// Test whether speculation rules prerendering is processed again on pages
// restored from BFCache via forward navigation.
// When the eagerness is kImmediate(default), speculation rules prerendering
// will no longer be processed after restoration. For non-immediate cases,
// candidates are stored between restoration unless they were triggered by user
// action (This test scenario reproduces only this case). However, once after
// processed by user action, then they will not be processed again until they
// are retriggered (crbug.com/1449163 for more information).
IN_PROC_BROWSER_TEST_P(PrerenderBackForwardCacheRestorationBrowserTest,
                       RestoredViaForwardNavigation) {
  const GURL initial_url = GetUrl("/empty.html");
  const GURL next_url = GetUrl("/empty.html?next");
  const GURL prerendering_url = GetUrl("/empty.html?prerender");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Navigate to a next page.
  ASSERT_TRUE(NavigateToURL(shell(), next_url));
  RenderFrameHostImpl* rfh_next = current_frame_host();
  InsertAnchor(prerendering_url);

  ASSERT_TRUE(rfh_next);
  PreloadingDeciderObserverForPrerenderTesting preloading_decider_observer(
      *rfh_next);
  auto* preloading_decider =
      PreloadingDecider::GetOrCreateForCurrentDocument(rfh_next);

  // Add speculation rules and wait to be loaded.
  AddPrerenderWithEagernessAsync(prerendering_url, GetSpeculationEagerness());
  if (IsImmediateSpeculationEagerness(GetSpeculationEagerness())) {
    WaitForPrerenderLoadCompletion(prerendering_url);
    ASSERT_TRUE(HasHostForUrl(prerendering_url));
  } else {
    preloading_decider_observer.WaitUpdateSpeculationCandidates();
    ASSERT_TRUE(preloading_decider->IsOnStandByForTesting(
        prerendering_url, blink::mojom::SpeculationAction::kPrerender));
  }

  // Navigate backward to the initial page. The next page should be stored to
  // the BFCache.
  GoBack();
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), initial_url);
  ExpectRestored(FROM_HERE);
  ASSERT_TRUE(rfh_next->IsInBackForwardCache());

  // Navigate forward. The next page should be restored from the BFCache.
  GoForward();
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), next_url);
  ExpectRestored(FROM_HERE);

  if (IsImmediateSpeculationEagerness(GetSpeculationEagerness())) {
    // Prerendering will be processed by retriggering.
    WaitForPrerenderLoadCompletion(prerendering_url);
    PrerenderHostId host_id_retriggered = GetHostForUrl(prerendering_url);

    test::PrerenderHostObserver prerender_observer(*web_contents(),
                                                   host_id_retriggered);

    // Activate the prerendered page.
    NavigatePrimaryPage(prerendering_url);
    prerender_observer.WaitForActivation();
    ASSERT_EQ(web_contents()->GetLastCommittedURL(), prerendering_url);
    EXPECT_TRUE(prerender_observer.was_activated());
  } else {
    ASSERT_FALSE(HasHostForUrl(prerendering_url));

    // |on_standby_candidates_| holds the non-immediate candidates if the
    // candidates were not processed by user interaction.
    EXPECT_TRUE(preloading_decider->IsOnStandByForTesting(
        prerendering_url, blink::mojom::SpeculationAction::kPrerender));

    // Trigger and activate the non-immediate prerender.
    {
      TestActivationManager activation_manager(web_contents(),
                                               prerendering_url);
      ClickAnchor(prerendering_url);
      activation_manager.WaitForNavigationFinished();
      ASSERT_EQ(web_contents()->GetLastCommittedURL(), prerendering_url);
      ASSERT_TRUE(activation_manager.was_activated());
    }
  }
}

// Test whether speculation rules prerendering is processed again on pages
// restored from BFCache via backward navigation.
// When immediate eagerness like `kImmediate` (default), speculation rules
// prerendering will no longer be processed after restoration. For non-immediate
// cases (kModerate, kConservative), candidates are stored between restoration
// unless they were triggered by user action. However, once after processed by
// user action, then they will not be processed again until they are retriggered
// (crbug.com/1449163 for more information).
IN_PROC_BROWSER_TEST_P(PrerenderBackForwardCacheRestorationBrowserTest,
                       RestoredViaBackwardNavigation) {
  const GURL initial_url = GetUrl("/empty.html");
  const GURL prerendering_url_a = GetUrl("/empty.html?prerender_a");
  const GURL prerendering_url_b = GetUrl("/empty.html?prerender_b");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  RenderFrameHostImpl* rfh_initial = current_frame_host();
  InsertAnchor(prerendering_url_a);
  InsertAnchor(prerendering_url_b);

  if (IsImmediateSpeculationEagerness(GetSpeculationEagerness())) {
    // Add speculation rules and wait to be loaded.
    AddPrerenderWithEagernessAsync(prerendering_url_a,
                                   GetSpeculationEagerness());
    AddPrerenderWithEagernessAsync(prerendering_url_b,
                                   GetSpeculationEagerness());
    WaitForPrerenderLoadCompletion(prerendering_url_a);
    WaitForPrerenderLoadCompletion(prerendering_url_b);

    PrerenderHostId host_id_a = GetHostForUrl(prerendering_url_a);
    test::PrerenderHostObserver prerender_observer_a(*web_contents(),
                                                     host_id_a);

    // Activate the page A. The initial page should be stored to the BFCache.
    NavigatePrimaryPage(prerendering_url_a);
    prerender_observer_a.WaitForActivation();
    ASSERT_EQ(web_contents()->GetLastCommittedURL(), prerendering_url_a);
    ASSERT_TRUE(prerender_observer_a.was_activated());
    ASSERT_TRUE(rfh_initial->IsInBackForwardCache());

    // Navigate backward. The initial page should be restored from the BFCache.
    GoBack();
    ASSERT_EQ(web_contents()->GetLastCommittedURL(), initial_url);
    ExpectRestored(FROM_HERE);

    // Prerendering for both the page A and the page B will be processed by
    // retriggering.
    WaitForPrerenderLoadCompletion(prerendering_url_a);
    WaitForPrerenderLoadCompletion(prerendering_url_b);
    PrerenderHostId host_id_a_retriggered = GetHostForUrl(prerendering_url_a);

    test::PrerenderHostObserver prerender_observer_a_retriggered(
        *web_contents(), host_id_a_retriggered);

    // Activate the page A again.
    NavigatePrimaryPage(prerendering_url_a);
    prerender_observer_a_retriggered.WaitForActivation();
    ASSERT_EQ(web_contents()->GetLastCommittedURL(), prerendering_url_a);
    EXPECT_TRUE(prerender_observer_a_retriggered.was_activated());
  } else {
    auto* preloading_decider =
        PreloadingDecider::GetOrCreateForCurrentDocument(rfh_initial);

    // Add speculation rules and wait to be loaded.
    // TODO(taiyo): modify |PreloadingDeciderObserverForPrerenderTesting| to
    // enable observing for URLs.
    {
      ASSERT_TRUE(rfh_initial);
      PreloadingDeciderObserverForPrerenderTesting preloading_decider_observer(
          *rfh_initial);
      AddPrerenderWithEagernessAsync(prerendering_url_a,
                                     GetSpeculationEagerness());
      preloading_decider_observer.WaitUpdateSpeculationCandidates();
    }
    {
      ASSERT_TRUE(rfh_initial);
      PreloadingDeciderObserverForPrerenderTesting preloading_decider_observer(
          *rfh_initial);
      AddPrerenderWithEagernessAsync(prerendering_url_b,
                                     GetSpeculationEagerness());
      preloading_decider_observer.WaitUpdateSpeculationCandidates();
    }
    ASSERT_TRUE(preloading_decider->IsOnStandByForTesting(
        prerendering_url_a, blink::mojom::SpeculationAction::kPrerender));
    ASSERT_TRUE(preloading_decider->IsOnStandByForTesting(
        prerendering_url_b, blink::mojom::SpeculationAction::kPrerender));

    // Activate the page A. The initial page should be stored to the BFCache.
    {
      TestActivationManager activation_manager(web_contents(),
                                               prerendering_url_a);
      ClickAnchor(prerendering_url_a);
      activation_manager.WaitForNavigationFinished();
      ASSERT_EQ(web_contents()->GetLastCommittedURL(), prerendering_url_a);
      ASSERT_TRUE(activation_manager.was_activated());
      ASSERT_TRUE(rfh_initial->IsInBackForwardCache());
    }

    // Navigate backward. The initial page should be restored from the BFCache.
    GoBack();
    ASSERT_EQ(web_contents()->GetLastCommittedURL(), initial_url);
    ExpectRestored(FROM_HERE);

    // |on_standby_candidates_| holds the non-immediate candidates if the
    // candidates were not processed by user interaction so that the the Page
    // B's candidate should be in the |on_standby_candidates_|.
    EXPECT_TRUE(preloading_decider->IsOnStandByForTesting(
        prerendering_url_b, blink::mojom::SpeculationAction::kPrerender));

    // TODO(crbug.com/40273826): In the current implementation, non-immediate
    // candidates that are once processed by user interaction will no
    // longer be stored in |on_standby_candidates_| when retriggered (more
    // specifically, |UpdateSpeculationCandidates| is (re)invoked) and instead
    // |PrerenderHost| will be created immediately, as with immediate
    // candidates. See crbug description for more details.
    {
      WaitForPrerenderLoadCompletion(prerendering_url_a);
      EXPECT_TRUE(HasHostForUrl(prerendering_url_a));
      EXPECT_FALSE(preloading_decider->IsOnStandByForTesting(
          prerendering_url_a, blink::mojom::SpeculationAction::kPrerender));
    }

    ASSERT_FALSE(HasHostForUrl(prerendering_url_b));

    // Trigger and activate the Page A again.
    {
      TestActivationManager activation_manager(web_contents(),
                                               prerendering_url_a);
      ClickAnchor(prerendering_url_a);
      activation_manager.WaitForNavigationFinished();
      ASSERT_EQ(web_contents()->GetLastCommittedURL(), prerendering_url_a);
      ASSERT_TRUE(activation_manager.was_activated());
    }
  }
}

// Tests that PrerenderHostRegistry can hold up to two prerendering for the
// prerender embedders it receives.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, StartByEmbeddersMultipleTimes) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kFirstPrerenderingUrl = GetUrl("/empty.html?prerender1");
  const GURL kSecondPrerenderingUrl = GetUrl("/empty.html?prerender2");
  const GURL kThirdPrerenderingUrl = GetUrl("/empty.html?prerender3");

  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  // Start prerendering by embedder triggered prerendering; this should be
  // trigger successfully.
  std::unique_ptr<PrerenderHandle> prerender_handle1 =
      AddEmbedderTriggeredPrerenderAsync(kFirstPrerenderingUrl);
  EXPECT_TRUE(prerender_handle1);

  histogram_tester().ExpectBucketCount(
      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_"
      "EmbedderSuffixForTest",
      PrerenderFinalStatus::kMaxNumOfRunningImmediatePrerendersExceeded, 0);

  // Start prerendering by embedder triggered prerendering; this should be
  // trigger successfully.
  std::unique_ptr<PrerenderHandle> prerender_handle2 =
      AddEmbedderTriggeredPrerenderAsync(kSecondPrerenderingUrl);
  EXPECT_TRUE(prerender_handle2);

  histogram_tester().ExpectBucketCount(
      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_"
      "EmbedderSuffixForTest",
      PrerenderFinalStatus::kMaxNumOfRunningEmbedderPrerendersExceeded, 0);

  // Start prerendering by embedder triggered prerendering; this should hit the
  // limit.
  std::unique_ptr<PrerenderHandle> prerender_handle3 =
      AddEmbedderTriggeredPrerenderAsync(kThirdPrerenderingUrl);
  EXPECT_FALSE(prerender_handle3);

  histogram_tester().ExpectBucketCount(
      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_"
      "EmbedderSuffixForTest",
      PrerenderFinalStatus::kMaxNumOfRunningEmbedderPrerendersExceeded, 1);
}

// Tests that PrerenderHostRegistry can hold up to two prerendering for the
// prerender speculation rule and prerender embedders in total.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       StartByEmbeddersAndSpeculationRulesMultipleTimes) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kSpeculationRulesPrerenderingUrl =
      GetUrl("/empty.html?prerender1");
  const GURL kEmbedderPrerenderingUrl1 = GetUrl("/empty.html?prerender2");
  const GURL kEmbedderPrerenderingUrl2 = GetUrl("/empty.html?prerender3");
  const GURL kEmbedderPrerenderingUrl3 = GetUrl("/empty.html?prerender4");

  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  // Add a prerender speculation rule; this should be triggered successfully.
  AddPrerender(kSpeculationRulesPrerenderingUrl);

  // Add the first prerender speculation rule; it should trigger prerendering
  // successfully.
  histogram_tester().ExpectBucketCount(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kMaxNumOfRunningImmediatePrerendersExceeded, 0);

  histogram_tester().ExpectBucketCount(
      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_"
      "EmbedderSuffixForTest",
      PrerenderFinalStatus::kMaxNumOfRunningEmbedderPrerendersExceeded, 0);

  // Start the first embedder triggered prerendering; this should be triggered
  // successfully.
  std::unique_ptr<PrerenderHandle> prerender_handle1 =
      AddEmbedderTriggeredPrerenderAsync(kEmbedderPrerenderingUrl1);
  EXPECT_TRUE(prerender_handle1);

  // Start the second embedder triggered prerendering; this should be triggered
  // successfully.
  std::unique_ptr<PrerenderHandle> prerender_handle2 =
      AddEmbedderTriggeredPrerenderAsync(kEmbedderPrerenderingUrl2);
  EXPECT_TRUE(prerender_handle2);

  histogram_tester().ExpectBucketCount(
      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_"
      "EmbedderSuffixForTest",
      PrerenderFinalStatus::kMaxNumOfRunningEmbedderPrerendersExceeded, 0);

  // Start the third embedder triggered prerendering; this should hit the limit.
  std::unique_ptr<PrerenderHandle> prerender_handle3 =
      AddEmbedderTriggeredPrerenderAsync(kEmbedderPrerenderingUrl3);
  EXPECT_FALSE(prerender_handle3);

  histogram_tester().ExpectBucketCount(
      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_"
      "EmbedderSuffixForTest",
      PrerenderFinalStatus::kMaxNumOfRunningEmbedderPrerendersExceeded, 1);

  // Cancel the second embedder triggered prerendering and start a new one;
  // this should succeed as one of the prerenders is freed.
  prerender_handle2.reset();
  prerender_handle3 =
      AddEmbedderTriggeredPrerenderAsync(kEmbedderPrerenderingUrl3);
  EXPECT_TRUE(prerender_handle3);
}

class MultiplePrerendersBrowserTest : public PrerenderBrowserTest {
 public:
  MultiplePrerendersBrowserTest() {
    feature_list_.InitWithFeaturesAndParameters(
        {{blink::features::kPrerender2MemoryControls,
          // A value 100 allows prerenderings regardless of the current memory
          // usage.
          {{"acceptable_percent_of_system_memory", "100"},
           // Allow prerendering on low-end trybot devices so that prerendering
           // can run on any bots.
           {"memory_threshold_in_mb", "0"}}}},
        {});
  }

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

class MultiplePrerendersWithLimitedMemoryBrowserTest
    : public MultiplePrerendersBrowserTest {
 public:
  MultiplePrerendersWithLimitedMemoryBrowserTest() {
    feature_list_.InitWithFeaturesAndParameters(
        {{blink::features::kPrerender2MemoryControls,
          // A value 0 doesn't allow any prerendering.
          {{"acceptable_percent_of_system_memory", "0"},
           // Allow prerendering on low-end trybot devices so that prerendering
           // can run on any bots.
           {"memory_threshold_in_mb", "0"}}}},
        {});
  }

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

// Tests that moderate-level memory pressure doesn't cancel prerendering on
// trigger.
IN_PROC_BROWSER_TEST_F(MultiplePrerendersBrowserTest,
                       MemoryPressureOnTrigger_Moderate) {
  GURL initial_url = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Emulate moderate-level memory pressure state.
  base::MemoryPressureListenerRegistry::SimulatePressureNotification(
      base::MEMORY_PRESSURE_LEVEL_MODERATE);

  // Triggering prerendering should not be canceled due to the moderate level
  // memory pressure.
  GURL prerender_url = GetUrl("/empty.html?prerender");
  AddPrerender(prerender_url);
  EXPECT_TRUE(HasHostForUrl(prerender_url));

  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kMemoryPressureOnTrigger, 0);
}

// Tests that critical-level memory pressure cancels prerendering on trigger.
IN_PROC_BROWSER_TEST_F(MultiplePrerendersBrowserTest,
                       MemoryPressureOnTrigger_Critical) {
  GURL initial_url = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Emulate critical-level memory pressure state.
  base::MemoryPressureListenerRegistry::SimulatePressureNotification(
      base::MEMORY_PRESSURE_LEVEL_CRITICAL);

  // Triggering prerendering should be canceled due to the critical level memory
  // pressure.
  GURL prerender_url = GetUrl("/empty.html?prerender");
  test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());
  AddPrerenderAsync(prerender_url);
  registry_observer.WaitForTrigger(prerender_url);
  EXPECT_FALSE(HasHostForUrl(prerender_url));

  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kMemoryPressureOnTrigger, 1);
}

// Tests that moderate-level memory pressure doesn't cancel prerendering after
// triggered.
IN_PROC_BROWSER_TEST_F(MultiplePrerendersBrowserTest,
                       MemoryPressureAfterTriggered_Moderate) {
  GURL initial_url = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  std::vector<GURL> prerender_urls = {
      GetUrl("/empty.html?prerender0"),
      GetUrl("/empty.html?prerender1"),
      GetUrl("/empty.html?prerender2"),
  };

  for (const GURL& prerender_url : prerender_urls) {
    AddPrerender(prerender_url);
  }

  // Emulate moderate-level memory pressure event. This shouldn't cancel
  // prerendering.
  base::MemoryPressureListener::NotifyMemoryPressure(
      base::MEMORY_PRESSURE_LEVEL_MODERATE);

  // Run the message loop to give a chance to unexpectedly cancel prerendering
  // due to some bug.
  base::RunLoop().RunUntilIdle();

  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kMemoryPressureAfterTriggered, 0);
}

// Tests that critical-level memory pressure cancels prerendering after
// triggered.
IN_PROC_BROWSER_TEST_F(MultiplePrerendersBrowserTest,
                       MemoryPressureAfterTriggered_Critical) {
  GURL initial_url = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  std::vector<GURL> prerender_urls = {
      GetUrl("/empty.html?prerender0"),
      GetUrl("/empty.html?prerender1"),
      GetUrl("/empty.html?prerender2"),
  };

  std::vector<std::unique_ptr<test::PrerenderHostObserver>> observers;
  for (const GURL& prerender_url : prerender_urls) {
    PrerenderHostId host_id = AddPrerender(prerender_url);
    observers.push_back(std::make_unique<test::PrerenderHostObserver>(
        *web_contents(), host_id));
  }

  // Emulate critical-level memory pressure event. This should cancel
  // prerendering.
  base::MemoryPressureListener::NotifyMemoryPressure(
      base::MEMORY_PRESSURE_LEVEL_CRITICAL);
  for (auto& observer : observers) {
    observer->WaitForDestroyed();
  }
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kMemoryPressureAfterTriggered,
      prerender_urls.size());
}

// Tests that PrerenderHostRegistry only starts prerender speculation rules
// up to `max_num_of_running_speculation_rules` defined by a Finch param.
IN_PROC_BROWSER_TEST_F(MultiplePrerendersBrowserTest,
                       AddSpeculationRulesMultipleTimes) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  for (int i = 0;
       i <
       PrerenderHostRegistry::kMaxRunningSpeculationRulesImmediatePrerenders;
       i++) {
    GURL prerendering_url =
        GetUrl("/empty.html?prerender" + base::NumberToString(i));

    // Add a prerender speculation rule; it should trigger prerendering
    // successfully.
    AddPrerender(prerendering_url);
  }

  test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());

  const GURL kExceededPrerenderingUrl =
      GetUrl("/empty.html?exceeded-prerender");
  // Add a new prerender speculation rule. Since PrerenderHostRegistry limits
  // the number of running prerenders to `max_num_of_running_speculation_rules`
  // defined by a Finch param, this rule should not be applied.
  AddPrerenderAsync(kExceededPrerenderingUrl);
  registry_observer.WaitForTrigger(kExceededPrerenderingUrl);
  EXPECT_FALSE(HasHostForUrl(kExceededPrerenderingUrl));

  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::kMaxNumOfRunningImmediatePrerendersExceeded);

  const GURL kEmbedderTriggeredPrerenderingUrl =
      GetUrl("/empty.html?embedder-triggered-prerender");
  // Start an embedder triggered prerendering; this should be triggered
  // successfully because its limitation is independent from speculation rules.
  std::unique_ptr<PrerenderHandle> prerender_handle =
      AddEmbedderTriggeredPrerenderAsync(kEmbedderTriggeredPrerenderingUrl);
  EXPECT_TRUE(prerender_handle);
}

// Tests that PrerenderHostRegistry can start prerendering when the DevTools is
// open even if the acceptable percent of the system memory is set to 0.
IN_PROC_BROWSER_TEST_F(MultiplePrerendersWithLimitedMemoryBrowserTest,
                       DevToolsOverride) {
  GURL initial_url = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Emulating Devtools attached to test the memory restriction override. Retain
  // the returned host until the test finishes to avoid DevTools termination.
  scoped_refptr<DevToolsAgentHost> dev_tools_agent_host =
      content::DevToolsAgentHost::GetOrCreateFor(web_contents());
  ASSERT_TRUE(dev_tools_agent_host);

  std::vector<GURL> urls = {
      GetUrl("/empty.html?prerender0"),
      GetUrl("/empty.html?prerender1"),
      GetUrl("/empty.html?prerender2"),
  };

  for (const GURL& url : urls) {
    AddPrerender(url);
  }

  // Prerender attempts shouldn't be cancelled for the memory limit.
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kMemoryLimitExceeded, 0);

  // Activate one of the prerendered pages. This should cancel the other
  // prerendered as kTriggerDestroyed.
  NavigatePrimaryPage(urls[0]);
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), urls[0]);
  histogram_tester().ExpectBucketCount(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kActivated, 1);
  histogram_tester().ExpectBucketCount(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kOtherPrerenderedPageActivated, 2);
}

// Tests that cross-site urls cannot be prerendered.
IN_PROC_BROWSER_TEST_P(PrerenderBrowserTestFallbackEnabledDisabled,
                       SkipCrossSitePrerender) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetCrossSiteUrl("/empty.html?crossorigin");

  base::RunLoop run_loop;
  PrefetchContainer::SetPrefetchResponseCompletedCallbackForTesting(
      base::BindLambdaForTesting(
          [&](base::WeakPtr<PrefetchContainer> prefetch_container) {
            if (prefetch_container->GetURL() != kPrerenderingUrl) {
              return;
            }
            run_loop.Quit();
          }));

  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());

  url::Origin initiator_origin = url::Origin::Create(kInitialUrl);
  url::Origin prerender_origin = url::Origin::Create(kPrerenderingUrl);

  // Add a cross-origin prerender rule.
  AddPrerenderAsync(kPrerenderingUrl);

  // Wait for PrerenderHostRegistry to receive the cross-origin prerender
  // request, and it should be ignored.
  registry_observer.WaitForTrigger(kPrerenderingUrl);
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));

  if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
    // Wait prefetch completion.
    run_loop.Run();
  }

  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::kCrossSiteNavigationInInitialNavigation);

  // Cross-check that in case of cross-origin navigation the eligibility
  // reason points to kCrossOrigin.
  ASSERT_TRUE(NavigateToURL(shell(), kPrerenderingUrl));

  // Prefetch admits cross-site, prerender doesn't.
  if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
    ExpectPreloadingAttemptUkm(
        {attempt_ukm_entry_builder().BuildEntry(
             PrimaryPageSourceId(), PreloadingType::kPrefetch,
             PreloadingEligibility::kEligible,
             PreloadingHoldbackStatus::kAllowed,
             PreloadingTriggeringOutcome::kReady,
             PreloadingFailureReason::kUnspecified,
             /*accurate=*/true,
             /*ready_time=*/kMockElapsedTime,
             blink::mojom::SpeculationEagerness::kImmediate),
         attempt_ukm_entry_builder().BuildEntry(
             PrimaryPageSourceId(), PreloadingType::kPrerender,
             PreloadingEligibility::kCrossOrigin,
             PreloadingHoldbackStatus::kUnspecified,
             PreloadingTriggeringOutcome::kUnspecified,
             PreloadingFailureReason::kUnspecified,
             /*accurate=*/true,
             /*ready_time=*/std::nullopt,
             blink::mojom::SpeculationEagerness::kImmediate)});
  } else {
    ExpectPreloadingAttemptUkm({attempt_ukm_entry_builder().BuildEntry(
        PrimaryPageSourceId(), PreloadingType::kPrerender,
        PreloadingEligibility::kCrossOrigin,
        PreloadingHoldbackStatus::kUnspecified,
        PreloadingTriggeringOutcome::kUnspecified,
        PreloadingFailureReason::kUnspecified,
        /*accurate=*/true,
        /*ready_time=*/std::nullopt,
        blink::mojom::SpeculationEagerness::kImmediate)});
  }
}

// Tests that same-site cross-origin navigation by speculation rules is not
// allowed with the feature enabled but without opt-in.
IN_PROC_BROWSER_TEST_F(
    PrerenderBrowserTest,
    SameSiteCrossOriginNavigationSpeculationRulesWithoutOptInHeader) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl =
      GetSameSiteCrossOriginUrl("/empty.html?samesitecrossorigin");

  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Add a same-site cross-origin prerender rule.
  test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());
  AddPrerenderAsync(kPrerenderingUrl);
  // Wait for PrerenderHostRegistry to receive the same-site cross-origin
  // prerender request, but it will be ignored because the opt-in header is
  // missing.
  registry_observer.WaitForTrigger(kPrerenderingUrl);
  // Navigate to the prerendering URL. This should result in regular navigation,
  // not prerender activation.
  NavigatePrimaryPage(kPrerenderingUrl);

  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::
          kSameSiteCrossOriginNavigationNotOptInInInitialNavigation);
}

// Tests that same-site cross-origin redirection by speculation rules with the
// feature enabled but without opt-in.
IN_PROC_BROWSER_TEST_P(
    PrerenderBrowserTestFallbackEnabledDisabled,
    SameSiteCrossOriginRedirectionSpeculationRulesWithoutOptInHeader) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering a URL that causes cross-origin redirection. The
  // cross-origin redirection should fail prerendering without an opt-in header.
  const GURL kRedirectedUrl =
      GetSameSiteCrossOriginUrl("/empty.html?samesitecrossorigin");
  const GURL kPrerenderingUrl =
      GetUrl("/server-redirect?" + kRedirectedUrl.spec());
  test::PrerenderHostObserver host_observer(*web_contents_impl(),
                                            kPrerenderingUrl);
  AddPrerenderAsync(kPrerenderingUrl);
  host_observer.WaitForDestroyed();
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  EXPECT_EQ(GetRequestCount(kRedirectedUrl), 1);
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));
  EXPECT_FALSE(HasHostForUrl(kRedirectedUrl));
  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::
          kSameSiteCrossOriginRedirectNotOptInInInitialNavigation);
}

// Tests that same-site cross-origin redirection with credentialed prerender by
// speculation rules with the feature enabled but the redirected page without
// opt-in. This test verifies a case which is a.test -> a.test (credentialed
// prerender) -> b.a.test (no credentialed prerender).
IN_PROC_BROWSER_TEST_P(
    PrerenderBrowserTestFallbackEnabledDisabled,
    SameSiteCrossOriginCredentialedPrerenderRedirectionSpeculationRulesWithoutOptInHeader) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering a URL that causes cross-origin redirection. The
  // cross-origin redirection should fail prerendering without an opt-in header.
  const GURL kRedirectedUrl =
      GetSameSiteCrossOriginUrl("/empty.html?samesitecrossorigin");
  const GURL kPrerenderingUrl = GetUrl(
      "/server-redirect-credentialed-prerender?" + kRedirectedUrl.spec());
  test::PrerenderHostObserver host_observer(*web_contents_impl(),
                                            kPrerenderingUrl);
  AddPrerenderAsync(kPrerenderingUrl);
  host_observer.WaitForDestroyed();
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  EXPECT_EQ(GetRequestCount(kRedirectedUrl), 1);
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));
  EXPECT_FALSE(HasHostForUrl(kRedirectedUrl));
  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::
          kSameSiteCrossOriginRedirectNotOptInInInitialNavigation);
}

// Tests that same-site cross-origin redirection with credentialed prerender by
// speculation rules with the feature enabled but the redirected page without
// opt-in. This test verifies a case which is a.test -> b.a.test (credentialed
// prerender) -> b.a.test (no credentialed prerender)
IN_PROC_BROWSER_TEST_P(
    PrerenderBrowserTestFallbackEnabledDisabled,
    SameSiteCrossOriginCredentialedPrerenderRedirectionSpeculationRulesWithoutOptInHeader2) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering a URL that causes cross-origin redirection. The
  // cross-origin redirection should fail prerendering without an opt-in header.
  const GURL kRedirectedUrl =
      GetSameSiteCrossOriginUrl("/empty.html?samesitecrossorigin");
  const GURL kPrerenderingUrl = GetSameSiteCrossOriginUrl(
      "/server-redirect-credentialed-prerender?" + kRedirectedUrl.spec());
  test::PrerenderHostObserver host_observer(*web_contents_impl(),
                                            kPrerenderingUrl);
  AddPrerenderAsync(kPrerenderingUrl);
  host_observer.WaitForDestroyed();
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  EXPECT_EQ(GetRequestCount(kRedirectedUrl), 1);
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));
  EXPECT_FALSE(HasHostForUrl(kRedirectedUrl));
  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::
          kSameSiteCrossOriginRedirectNotOptInInInitialNavigation);
}

// Tests that same-site cross-origin navigation redirecting back to same-origin
// without opt-in.
IN_PROC_BROWSER_TEST_P(
    PrerenderBrowserTestFallbackEnabledDisabled,
    SameSiteCrossOriginNavigationBackToSameOriginWithoutOptInHeader) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering a URL that causes same-site cross-origin navigation and
  // redirects back to the same-origin. This should not fail even without
  // same-site cross-origin opt-in header.
  const GURL kRedirectedUrl = GetUrl("/empty.html?samesitecrossorigin");
  const GURL kPrerenderingUrl =
      GetSameSiteCrossOriginUrl("/server-redirect?" + kRedirectedUrl.spec());
  test::PrerenderHostObserver host_observer(*web_contents_impl(),
                                            kPrerenderingUrl);

  RedirectChainObserver redirect_chain_observer(*shell()->web_contents(),
                                                kRedirectedUrl);
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 0);
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 0);
  AddPrerender(kPrerenderingUrl);
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 1);

  ASSERT_EQ(2u, redirect_chain_observer.redirect_chain().size());
  EXPECT_EQ(kPrerenderingUrl, redirect_chain_observer.redirect_chain()[0]);
  EXPECT_EQ(kRedirectedUrl, redirect_chain_observer.redirect_chain()[1]);

  NavigatePrimaryPage(kPrerenderingUrl);
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kRedirectedUrl);
  // Activating the prerendered page should not issue a request.
  EXPECT_EQ(GetRequestCount(kRedirectedUrl), 1);
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kActivated);
}

// Tests that cross-origin redirection in multiple redirections by speculation
// rules should be canceled.
IN_PROC_BROWSER_TEST_P(PrerenderBrowserTestFallbackEnabledDisabled,
                       CrossSiteMultipleRedirectionSpeculationRules) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering a URL that causes cross-origin redirection. The
  // cross-origin redirection should fail prerendering without an opt-in
  // header.
  const GURL kRedirectedUrl = GetSameSiteCrossOriginUrl(
      "/prerender/prerender_with_opt_in_header.html?prerender");
  const GURL kRedirectedUrl2 =
      GetCrossSiteUrl("/server-redirect?" + kRedirectedUrl.spec());
  const GURL kPrerenderingUrl =
      GetUrl("/server-redirect?" + kRedirectedUrl2.spec());
  test::PrerenderHostObserver host_observer(*web_contents_impl(),
                                            kPrerenderingUrl);

  base::RunLoop run_loop;
  std::optional<PrefetchStatus> prefetch_status;
  PrefetchContainer::SetPrefetchResponseCompletedCallbackForTesting(
      base::BindLambdaForTesting(
          [&](base::WeakPtr<PrefetchContainer> prefetch_container) {
            if (prefetch_container->GetURL() != kPrerenderingUrl) {
              return;
            }
            prefetch_status = prefetch_container->GetPrefetchStatus();
            run_loop.Quit();
          }));

  AddPrerenderAsync(kPrerenderingUrl);
  host_observer.WaitForDestroyed();

  if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
    // The cancellation is controlled by `PrerenderNavigationThrottle`. If
    // `kPrerender2FallbackPrefetchSpecRule` is enabled, prefetch ahead of
    // prerender is triggered and it follows all redirect in the loading phase
    // of prefetch, and `PrerenderNavigationThrottle` cancels the prerender in
    // the serving phase of prefetch.
    run_loop.Run();
    EXPECT_TRUE(prefetch_status.has_value());
    EXPECT_EQ(prefetch_status.value(), PrefetchStatus::kPrefetchSuccessful);
    EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
    EXPECT_EQ(GetRequestCount(kRedirectedUrl), 1);
    EXPECT_EQ(GetRequestCount(kRedirectedUrl2), 1);
  } else {
    EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
    EXPECT_EQ(GetRequestCount(kRedirectedUrl), 0);
    EXPECT_EQ(GetRequestCount(kRedirectedUrl2), 0);
  }
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));
  EXPECT_FALSE(HasHostForUrl(kRedirectedUrl));
  EXPECT_FALSE(HasHostForUrl(kRedirectedUrl2));
  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::kCrossSiteRedirectInInitialNavigation);
}

// Tests that same-site cross-origin navigation by speculation rules can be
// prerendered with the feature enabled.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       CheckSameSiteCrossOriginSpeculationRulesPrerender) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl =
      GetSameSiteCrossOriginUrl("/prerender/prerender_with_opt_in_header.html");

  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Add a same-site cross-origin prerender rule.
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 0);
  AddPrerender(kPrerenderingUrl);
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);

  NavigatePrimaryPage(kPrerenderingUrl);
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);
  // Activating the prerendered page should not issue a request.
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kActivated);
}

// Tests that same-site cross-origin redirection by speculation rules is
// allowed.
IN_PROC_BROWSER_TEST_P(PrerenderBrowserTestFallbackEnabledDisabled,
                       SameSiteCrossOriginSpeculationRulesRedirection) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering a URL that causes same-origin redirection.
  const GURL kRedirectedUrl = GetSameSiteCrossOriginUrl(
      "/prerender/prerender_with_opt_in_header.html?prerender");
  const GURL kPrerenderingUrl =
      GetSameSiteCrossOriginUrl("/server-redirect?" + kRedirectedUrl.spec());
  RedirectChainObserver redirect_chain_observer(*shell()->web_contents(),
                                                kRedirectedUrl);
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 0);
  ASSERT_EQ(GetRequestCount(kRedirectedUrl), 0);
  AddPrerender(kPrerenderingUrl);
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  EXPECT_EQ(GetRequestCount(kRedirectedUrl), 1);

  ASSERT_EQ(2u, redirect_chain_observer.redirect_chain().size());
  EXPECT_EQ(kPrerenderingUrl, redirect_chain_observer.redirect_chain()[0]);
  EXPECT_EQ(kRedirectedUrl, redirect_chain_observer.redirect_chain()[1]);

  // The prerender host should be registered for the initial request URL, not
  // the redirected URL.
  EXPECT_TRUE(HasHostForUrl(kPrerenderingUrl));
  EXPECT_FALSE(HasHostForUrl(kRedirectedUrl));

  RedirectChainObserver activation_redirect_chain_observer(
      *shell()->web_contents(), kRedirectedUrl);
  NavigationHandleObserver activation_observer(web_contents(),
                                               kPrerenderingUrl);
  NavigatePrimaryPage(kPrerenderingUrl);
  ASSERT_EQ(1u, activation_redirect_chain_observer.redirect_chain().size());
  EXPECT_EQ(kRedirectedUrl,
            activation_redirect_chain_observer.redirect_chain()[0]);

  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kRedirectedUrl);
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kActivated);
  // Activating the prerendered page should not issue a request.
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  EXPECT_EQ(GetRequestCount(kRedirectedUrl), 1);

  // Cross-check that in case redirection when the prerender navigates and
  // user ends up navigating to the redirected URL. accurate_triggering is
  // true.
  ukm::SourceId ukm_source_id = activation_observer.next_page_ukm_source_id();
  if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
    ExpectPreloadingAttemptUkm(
        {attempt_ukm_entry_builder().BuildEntry(
             ukm_source_id, PreloadingType::kPrefetch,
             PreloadingEligibility::kEligible,
             PreloadingHoldbackStatus::kAllowed,
             PreloadingTriggeringOutcome::kSuccess,
             PreloadingFailureReason::kUnspecified,
             /*accurate=*/true,
             /*ready_time=*/kMockElapsedTime,
             blink::mojom::SpeculationEagerness::kImmediate),
         attempt_ukm_entry_builder().BuildEntry(
             ukm_source_id, PreloadingType::kPrerender,
             PreloadingEligibility::kEligible,
             PreloadingHoldbackStatus::kAllowed,
             PreloadingTriggeringOutcome::kSuccess,
             PreloadingFailureReason::kUnspecified,
             /*accurate=*/true,
             /*ready_time=*/kMockElapsedTime,
             blink::mojom::SpeculationEagerness::kImmediate)});
  } else {
    ExpectPreloadingAttemptUkm({attempt_ukm_entry_builder().BuildEntry(
        ukm_source_id, PreloadingType::kPrerender,
        PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed,
        PreloadingTriggeringOutcome::kSuccess,
        PreloadingFailureReason::kUnspecified,
        /*accurate=*/true,
        /*ready_time=*/kMockElapsedTime,
        blink::mojom::SpeculationEagerness::kImmediate)});
  }
}

// Tests that multiple same-site cross-origin redirections by speculation rules
// is allowed, and only the terminal one is checked for the opt in header.
IN_PROC_BROWSER_TEST_P(
    PrerenderBrowserTestFallbackEnabledDisabled,
    SameSiteCrossOriginSpeculationRulesMultipleRedirections) {
  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering a URL that causes same-origin redirection.
  const GURL kRedirectedUrl = GetSameSiteCrossOriginUrl(
      "/prerender/prerender_with_opt_in_header.html?prerender");
  const GURL kRedirectedUrl2 =
      GetSameSiteCrossOriginUrl("/server-redirect?" + kRedirectedUrl.spec());
  const GURL kPrerenderingUrl =
      GetSameSiteCrossOriginUrl("/server-redirect?" + kRedirectedUrl2.spec());
  RedirectChainObserver redirect_chain_observer(*shell()->web_contents(),
                                                kRedirectedUrl);
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 0);
  ASSERT_EQ(GetRequestCount(kRedirectedUrl), 0);
  ASSERT_EQ(GetRequestCount(kRedirectedUrl2), 0);
  AddPrerender(kPrerenderingUrl);
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  EXPECT_EQ(GetRequestCount(kRedirectedUrl), 1);
  EXPECT_EQ(GetRequestCount(kRedirectedUrl2), 1);

  ASSERT_EQ(3u, redirect_chain_observer.redirect_chain().size());
  EXPECT_EQ(kPrerenderingUrl, redirect_chain_observer.redirect_chain()[0]);
  EXPECT_EQ(kRedirectedUrl2, redirect_chain_observer.redirect_chain()[1]);
  EXPECT_EQ(kRedirectedUrl, redirect_chain_observer.redirect_chain()[2]);

  // The prerender host should be registered for the initial request URL, not
  // the redirected URL.
  EXPECT_TRUE(HasHostForUrl(kPrerenderingUrl));
  EXPECT_FALSE(HasHostForUrl(kRedirectedUrl));
  EXPECT_FALSE(HasHostForUrl(kRedirectedUrl2));

  RedirectChainObserver activation_redirect_chain_observer(
      *shell()->web_contents(), kRedirectedUrl);
  NavigationHandleObserver activation_observer(web_contents(),
                                               kPrerenderingUrl);
  NavigatePrimaryPage(kPrerenderingUrl);
  ASSERT_EQ(1u, activation_redirect_chain_observer.redirect_chain().size());
  EXPECT_EQ(kRedirectedUrl,
            activation_redirect_chain_observer.redirect_chain()[0]);

  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kRedirectedUrl);
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kActivated);
  // Activating the prerendered page should not issue a request.
  EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
  EXPECT_EQ(GetRequestCount(kRedirectedUrl), 1);
  EXPECT_EQ(GetRequestCount(kRedirectedUrl2), 1);

  // Cross-check that in case redirection when the prerender navigates and user
  // ends up navigating to the redirected URL. accurate_triggering is true.
  ukm::SourceId ukm_source_id = activation_observer.next_page_ukm_source_id();
  if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
    ExpectPreloadingAttemptUkm({
        attempt_ukm_entry_builder().BuildEntry(
            ukm_source_id, PreloadingType::kPrefetch,
            PreloadingEligibility::kEligible,
            PreloadingHoldbackStatus::kAllowed,
            PreloadingTriggeringOutcome::kSuccess,
            PreloadingFailureReason::kUnspecified,
            /*accurate=*/true,
            /*ready_time=*/kMockElapsedTime,
            blink::mojom::SpeculationEagerness::kImmediate),
        attempt_ukm_entry_builder().BuildEntry(
            ukm_source_id, PreloadingType::kPrerender,
            PreloadingEligibility::kEligible,
            PreloadingHoldbackStatus::kAllowed,
            PreloadingTriggeringOutcome::kSuccess,
            PreloadingFailureReason::kUnspecified,
            /*accurate=*/true,
            /*ready_time=*/kMockElapsedTime,
            blink::mojom::SpeculationEagerness::kImmediate),
    });
  } else {
    ExpectPreloadingAttemptUkm({attempt_ukm_entry_builder().BuildEntry(
        ukm_source_id, PreloadingType::kPrerender,
        PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed,
        PreloadingTriggeringOutcome::kSuccess,
        PreloadingFailureReason::kUnspecified,
        /*accurate=*/true,
        /*ready_time=*/kMockElapsedTime,
        blink::mojom::SpeculationEagerness::kImmediate)});
  }
}

void PrerenderBrowserTest::TestEmbedderTriggerWithUnsupportedScheme(
    const GURL& prerendering_url) {
  const GURL initial_url = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  ASSERT_FALSE(prerendering_url.SchemeIsHTTPOrHTTPS());

  auto* preloading_data =
      PreloadingData::GetOrCreateForWebContents(web_contents_impl());
  PreloadingPredictor preloading_predictor(100, "Embedder");
  PreloadingURLMatchCallback same_url_matcher =
      PreloadingData::GetSameURLMatcher(prerendering_url);
  PreloadingAttempt* preloading_attempt = preloading_data->AddPreloadingAttempt(
      preloading_predictor, PreloadingType::kPrerender,
      std::move(same_url_matcher),
      web_contents_impl()->GetPrimaryMainFrame()->GetPageUkmSourceId());

  // Start prerendering by embedder triggered prerendering.
  std::unique_ptr<PrerenderHandle> prerender_handle =
      AddEmbedderTriggeredPrerenderAsync(prerendering_url, preloading_attempt);
  EXPECT_FALSE(prerender_handle);

  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_"
      "EmbedderSuffixForTest",
      PrerenderFinalStatus::kInvalidSchemeNavigation, 1);

  // Navigate primary page to flush the metrics.
  const GURL navigated_url = GetUrl("/empty.html?navigated");
  ASSERT_TRUE(NavigateToURL(shell(), navigated_url));

  auto attempt_ukm_entry_builder =
      std::make_unique<test::PreloadingAttemptUkmEntryBuilder>(
          preloading_predictor);
  ExpectPreloadingAttemptUkm({attempt_ukm_entry_builder->BuildEntry(
      PrimaryPageSourceId(), PreloadingType::kPrerender,
      PreloadingEligibility::kHttpOrHttpsOnly,
      PreloadingHoldbackStatus::kUnspecified,
      PreloadingTriggeringOutcome::kUnspecified,
      PreloadingFailureReason::kUnspecified,
      /*accurate=*/false,
      /*ready_time=*/std::nullopt,
      /*eagerness=*/std::nullopt)});
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       EmbedderTrigger_UnsupportedScheme_ViewSource) {
  const GURL prerendering_url =
      GURL("view-source:" + GetUrl("/empty.html?prerender").spec());
  TestEmbedderTriggerWithUnsupportedScheme(prerendering_url);
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       EmbedderTrigger_UnsupportedScheme_DataUrl) {
  // The content is "<h1>Hello, World!</h1>".
  const GURL prerendering_url(
      "data:text/html,%3Ch1%3EHello%2C%20World%21%3C%2Fh1%3E");
  TestEmbedderTriggerWithUnsupportedScheme(prerendering_url);
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       EmbedderTrigger_SameOriginRedirection) {
  const GURL initial_url = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  const GURL redirected_url_node_2 = GetUrl("/empty.html?prerender");
  const GURL redirected_url_node_1 =
      GetUrl("/server-redirect?" + redirected_url_node_2.spec());
  const GURL prerender_initial_url =
      GetUrl("/server-redirect?" + redirected_url_node_1.spec());

  RedirectChainObserver redirect_chain_observer(*shell()->web_contents(),
                                                redirected_url_node_2);

  // Start prerendering by embedder triggered prerendering.
  std::unique_ptr<PrerenderHandle> prerender_handle =
      AddEmbedderTriggeredPrerender(prerender_initial_url);
  ASSERT_EQ(3u, redirect_chain_observer.redirect_chain().size());

  // Prerender is not canceled.
  EXPECT_TRUE(HasHostForUrl(prerender_initial_url));

  // Regression test for https://crbug.com/1211274. Make sure that we don't
  // crash when activating a prerendered page which performed a same-origin
  // redirect.
  RedirectChainObserver activation_redirect_chain_observer(
      *shell()->web_contents(), redirected_url_node_2);
  test::PrerenderHostObserver prerender_observer(*web_contents_impl(),
                                                 prerender_initial_url);
  prerender_helper()->NavigatePrimaryPageAsync(
      prerender_initial_url,
      ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
                                ui::PAGE_TRANSITION_FROM_ADDRESS_BAR));
  prerender_observer.WaitForActivation();
  ASSERT_EQ(1u, activation_redirect_chain_observer.redirect_chain().size());
  EXPECT_EQ(redirected_url_node_2,
            activation_redirect_chain_observer.redirect_chain()[0]);
}

// If there is a cross-origin url in the redirection chain, tests prerender
// should be canceled.
IN_PROC_BROWSER_TEST_F(
    PrerenderBrowserTest,
    EmbedderTrigger_CancelIfCrossOriginUrlInRedirectionChain) {
  GURL initial_url = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Prerendering a url that will be redirected to same_origin_redirected_url
  // and then cross_origin_redirected_url.
  GURL cross_origin_redirected_url = GetCrossSiteUrl("/empty.html");
  GURL same_origin_redirected_url =
      GetUrl("/server-redirect?" + cross_origin_redirected_url.spec());
  GURL prerendering_initial_url =
      GetUrl("/server-redirect?" + same_origin_redirected_url.spec());

  RedirectChainObserver redirect_chain_observer(*shell()->web_contents(),
                                                cross_origin_redirected_url);

  // Start prerendering by embedder triggered prerendering.
  std::unique_ptr<PrerenderHandle> prerender_handle =
      AddEmbedderTriggeredPrerender(prerendering_initial_url);

  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_"
      "EmbedderSuffixForTest",
      PrerenderFinalStatus::kCrossSiteRedirectInInitialNavigation, 1);
  EXPECT_FALSE(HasHostForUrl(prerendering_initial_url));
}

std::unique_ptr<PrerenderHandle>
PrerenderEmbedderTriggeredCrossOriginRedirectionPage(
    WebContentsImpl& web_contents,
    const GURL& prerendering_url,
    const GURL& cross_origin_url) {
  EXPECT_FALSE(url::IsSameOriginWith(prerendering_url, cross_origin_url));
  RedirectChainObserver redirect_chain_observer{web_contents, cross_origin_url};

  // Start prerendering by embedder triggered prerendering.
  std::unique_ptr<PrerenderHandle> prerender_handle =
      web_contents.StartPrerendering(
          prerendering_url, PreloadingTriggerType::kEmbedder,
          "EmbedderSuffixForTest",
          /*additional_headers=*/net::HttpRequestHeaders(),
          /*no_vary_search_hint=*/std::nullopt,
          ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
                                    ui::PAGE_TRANSITION_FROM_ADDRESS_BAR),
          /*should_warm_up_compositor=*/false,
          /*should_prepare_paint_tree=*/true,
          PreloadingHoldbackStatus::kUnspecified,
          PreloadPipelineInfo::Create(
              /*planned_max_preloading_type=*/PreloadingType::kPrerender),
          /*preloading_attempt=*/nullptr, /*url_match_predicate=*/{},
          /*prerender_navigation_handle_callback=*/{},
          /*allow_reuse=*/false);
  EXPECT_TRUE(prerender_handle);
  test::PrerenderTestHelper::WaitForPrerenderLoadCompletion(web_contents,
                                                            prerendering_url);
  EXPECT_EQ(2u, redirect_chain_observer.redirect_chain().size());
  return prerender_handle;
}

namespace {

class FrameDisplayStateChangedObserver : public WebContentsObserver {
 public:
  explicit FrameDisplayStateChangedObserver(RenderFrameHost& host)
      : WebContentsObserver(WebContents::FromRenderFrameHost(&host)),
        target_host_(&host) {}

  void WaitForFrameDisplayStateChanged() {
    if (changed_count_ > 0) {
      changed_count_--;
    } else {
      base::RunLoop loop;
      callback_ = loop.QuitClosure();
      loop.Run();
    }
  }

  void FrameDisplayStateChanged(RenderFrameHost* host,
                                bool is_display_none) override {
    if (host == target_host_) {
      if (callback_) {
        std::move(callback_).Run();
      } else {
        changed_count_++;
      }
    }
  }

  int changed_count_ = 0;
  const raw_ptr<RenderFrameHost> target_host_;
  base::OnceClosure callback_;
};

}  // namespace

// Tests that FrameOwnerProperties are in sync after activation.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, FrameOwnerPropertiesDisplayNone) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl =
      GetUrl("/prerender/doc-with-display-none-iframe.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  EXPECT_TRUE(AddTestUtilJS(current_frame_host()));

  // Start prerendering a document with a display:none iframe.
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  RenderFrameHost* prerender_frame_host = GetPrerenderedMainFrameHost(host_id);
  EXPECT_TRUE(ExecJs(prerender_frame_host, "loaded;"));

  // The iframe is at "/empty.html". It should be display none.
  RenderFrameHost* iframe_host = FindRenderFrameHost(
      prerender_frame_host->GetPage(), GetUrl("/empty.html"));
  EXPECT_FALSE(prerender_frame_host->IsFrameDisplayNone());
  EXPECT_TRUE(iframe_host->IsFrameDisplayNone());

  // Activate.
  NavigatePrimaryPage(kPrerenderingUrl);
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);

  // The frames should still have the same display properties.
  EXPECT_FALSE(prerender_frame_host->IsFrameDisplayNone());
  EXPECT_TRUE(iframe_host->IsFrameDisplayNone());

  // Change the display properties.
  FrameDisplayStateChangedObserver obs(*iframe_host);
  EXPECT_TRUE(
      ExecJs(prerender_frame_host,
             "document.querySelector('iframe').style = 'display: block;'"));
  obs.WaitForFrameDisplayStateChanged();

  EXPECT_FALSE(prerender_frame_host->IsFrameDisplayNone());
  EXPECT_FALSE(iframe_host->IsFrameDisplayNone());
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, TriggeredPrerenderUkm) {
  ukm::TestAutoSetUkmRecorder ukm_recorder;

  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);

  // PrerenderPageLoad metric should not be recorded yet.
  EXPECT_EQ(0u,
            ukm_recorder
                .GetEntriesByName(ukm::builders::PrerenderPageLoad::kEntryName)
                .size());

  // Start a prerender.
  ASSERT_TRUE(AddPrerender(kPrerenderingUrl));

  // PrerenderPageLoad:TriggeredPrerender is recorded for the initiator page
  // load.
  const std::vector<raw_ptr<const ukm::mojom::UkmEntry, VectorExperimental>>
      entries = ukm_recorder.GetEntriesByName(
          ukm::builders::PrerenderPageLoad::kEntryName);
  ASSERT_EQ(1u, entries.size());
  EXPECT_EQ(web_contents()->GetPrimaryMainFrame()->GetPageUkmSourceId(),
            entries.front()->source_id);
  ukm_recorder.ExpectEntryMetric(
      entries.front(),
      ukm::builders::PrerenderPageLoad::kTriggeredPrerenderName, 1);
}

// Tests that background color in a prerendered page does not affect
// the primary page.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, ColorSchemeDarkInNonPrimaryPage) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/color-scheme-dark.html");

  // Expect initial page background color to be white.
  BackgroundColorChangeWaiter empty_page_background_waiter(web_contents());

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  // Wait for the page background to change to white.
  empty_page_background_waiter.Wait();

  {
    // Now set up a mock observer for BackgroundColorChanged, to test if the
    // mocked observer executes BackgroundColorChanged for the prerendered page.
    testing::NiceMock<MockWebContentsObserver> background_color_observer(
        web_contents());
    EXPECT_CALL(background_color_observer, OnBackgroundColorChanged())
        .Times(Exactly(0));

    AddPrerender(kPrerenderingUrl);
  }

  BackgroundColorChangeWaiter prerendered_page_background_waiter(
      web_contents());
  // Now set up a mock observer for BackgroundColorChanged, to test if the
  // mocked observer executes BackgroundColorChanged when activating the
  // prerendered page.
  testing::NiceMock<MockWebContentsObserver> background_color_observer(
      web_contents());
  EXPECT_CALL(background_color_observer, OnBackgroundColorChanged())
      .Times(Exactly(1));
  NavigatePrimaryPage(kPrerenderingUrl);
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);
  // Wait for the page background to change.
  prerendered_page_background_waiter.Wait();
}

// TODO(b/335786567): Flaky on win-asan.
#if (BUILDFLAG(IS_WIN) && defined(ADDRESS_SANITIZER))
#define MAYBE_ThemeColorSchemeChangeInNonPrimaryPage \
  DISABLED_ThemeColorSchemeChangeInNonPrimaryPage
#else
#define MAYBE_ThemeColorSchemeChangeInNonPrimaryPage \
  ThemeColorSchemeChangeInNonPrimaryPage
#endif
// Tests that theme color in a prerendered page does not affect
// the primary page.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       MAYBE_ThemeColorSchemeChangeInNonPrimaryPage) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/theme_color.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  {
    // Now set up a mock observer for DidChangeThemeColor, to test if the
    // mocked observer executes DidChangeThemeColor for the prerendered page.
    testing::NiceMock<MockWebContentsObserver> theme_color_observer(
        web_contents());
    EXPECT_CALL(theme_color_observer, DidChangeThemeColor()).Times(Exactly(0));

    AddPrerender(kPrerenderingUrl);
  }

  ThemeChangeWaiter theme_change_waiter(web_contents());
  testing::NiceMock<MockWebContentsObserver> theme_color_observer(
      web_contents());
  EXPECT_CALL(theme_color_observer, DidChangeThemeColor()).Times(Exactly(1));

  NavigatePrimaryPage(kPrerenderingUrl);
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);
  theme_change_waiter.Wait();
}

// Check that the prerendered page window.name is maintained after activation.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       VerifyFrameNameMaintainedAfterActivation) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/title1.html");

  // 1. Load initiator page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // 2. Load prerender.
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  RenderFrameHostImpl* prerendered_render_frame_host =
      GetPrerenderedMainFrameHost(host_id);

  // 3. Set window.name.
  ASSERT_TRUE(
      ExecJs(prerendered_render_frame_host, "window.name = 'prerender_page'"));

  EXPECT_EQ(prerendered_render_frame_host->GetFrameName(), "prerender_page");
  EXPECT_EQ(current_frame_host()->GetFrameName(), "");

  // 4. Activate prerender.
  test::PrerenderHostObserver host_observer(*web_contents(), kPrerenderingUrl);
  NavigatePrimaryPage(kPrerenderingUrl);
  EXPECT_TRUE(host_observer.was_activated());
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);

  // 5. Ensure that the window.name is preserved.
  EXPECT_EQ(current_frame_host()->GetFrameName(), "prerender_page");
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, ActivateWhileReloadingSubframe) {
  const char kSubframePath[] = "/title1.html";
  net::test_server::ControllableHttpResponse first_response(
      embedded_test_server(), kSubframePath);
  net::test_server::ControllableHttpResponse second_response(
      embedded_test_server(), kSubframePath);

  ASSERT_TRUE(embedded_test_server()->Start());

  const GURL kInitialUrl = embedded_test_server()->GetURL("/empty.html");
  const GURL kPrerenderingUrl =
      embedded_test_server()->GetURL("/page_with_iframe.html");
  const GURL kSubframeUrl = embedded_test_server()->GetURL(kSubframePath);

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start a prerender.
  test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());
  AddPrerenderAsync(kPrerenderingUrl);

  // Handle a response for the subframe main resource.
  first_response.WaitForRequest();
  first_response.Send(net::HTTP_OK, "");
  first_response.Done();

  // Now we can wait for the prerendering navigation finishes.
  registry_observer.WaitForTrigger(kPrerenderingUrl);
  PrerenderHostId host_id = GetHostForUrl(kPrerenderingUrl);
  WaitForPrerenderLoadCompletion(host_id);

  RenderFrameHostImpl* prerender_rfh = GetPrerenderedMainFrameHost(host_id);
  RenderFrameHostImpl* child_rfh =
      prerender_rfh->child_at(0)->current_frame_host();
  EXPECT_EQ(child_rfh->GetLastCommittedURL(), kSubframeUrl);

  // Reload the iframe.
  EXPECT_TRUE(ExecJs(child_rfh, "window.location.reload();"));
  second_response.WaitForRequest();
  // Do not finish the second response to execute activation during the reload.

  // Ensure that activation works even while the iframe is under the reload.
  TestNavigationObserver nav_observer(web_contents());
  EXPECT_TRUE(
      ExecJs(web_contents(), JsReplace("location = $1", kPrerenderingUrl)));
  second_response.Send(net::HTTP_OK, "");
  second_response.Done();
  nav_observer.WaitForNavigationFinished();
}

// Check that the inactive RFH shouldn't update UserActivation.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DoNotUpdateUserActivationState) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/title1.html");

  // 1. Load initiator page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // 2. Load prerender.
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  RenderFrameHostImpl* prerendered_rfh = GetPrerenderedMainFrameHost(host_id);

  EXPECT_FALSE(
      current_frame_host()->frame_tree_node()->HasStickyUserActivation());
  EXPECT_FALSE(prerendered_rfh->frame_tree_node()->HasStickyUserActivation());

  // 3. Try to set the user activation bits to the prerendered RFH.
  prerendered_rfh->UpdateUserActivationState(
      blink::mojom::UserActivationUpdateType::kNotifyActivation,
      blink::mojom::UserActivationNotificationType::kTest);
  EXPECT_FALSE(prerendered_rfh->frame_tree_node()->HasStickyUserActivation());
  EXPECT_FALSE(prerendered_rfh->HasTransientUserActivation());

  EXPECT_FALSE(
      current_frame_host()->frame_tree_node()->HasStickyUserActivation());
  EXPECT_FALSE(
      current_frame_host()->frame_tree_node()->HasTransientUserActivation());

  // 4. Set the user activation bits to the primary RFH.
  current_frame_host()->UpdateUserActivationState(
      blink::mojom::UserActivationUpdateType::kNotifyActivation,
      blink::mojom::UserActivationNotificationType::kTest);
  EXPECT_TRUE(
      current_frame_host()->frame_tree_node()->HasStickyUserActivation());

  EXPECT_FALSE(prerendered_rfh->frame_tree_node()->HasStickyUserActivation());
}

// Tests that prerendering is cancelled when a mixed content subframe is
// detected.
IN_PROC_BROWSER_TEST_P(PrerenderTargetAgnosticBrowserTest, MixedContent) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerendering");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Make a prerendered page.
  PrerenderHostId host_id = prerender_helper()->AddPrerender(
      kPrerenderingUrl, /*eagerness=*/std::nullopt, GetTargetHint());
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  auto* prerendered_rfh =
      test::PrerenderTestHelper::GetPrerenderedMainFrameHost(
          *prerender_web_contents, host_id);
  CHECK(prerendered_rfh);
  EXPECT_TRUE(AddTestUtilJS(prerendered_rfh));

  test::PrerenderHostObserver host_observer(*prerender_web_contents, host_id);

  // Make a mixed content iframe.
  std::ignore =
      ExecJs(prerendered_rfh,
             "add_iframe_async('http://a.test/empty.html?prerendering')",
             EvalJsOptions::EXECUTE_SCRIPT_NO_RESOLVE_PROMISES);

  host_observer.WaitForDestroyed();
  if (GetTargetHint() == "_blank") {
    EXPECT_FALSE(prerender_helper()->HasNewTabHandle(host_id));
  } else {
    EXPECT_TRUE(prerender_helper()
                    ->GetHostForUrl(*prerender_web_contents, kPrerenderingUrl)
                    .is_null());
  }

  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kMixedContent);
}

// Check that the Content-Security-Policy set via HTTP header applies after the
// activation. This test verifies that that the web sandbox flags value is none.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       ActivatePageWithCspHeaderFrameSrc) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl =
      GetUrl("/set-header?Content-Security-Policy: frame-src 'none'");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  RenderFrameHostImpl* prerendered_render_frame_host =
      GetPrerenderedMainFrameHost(host_id);

  // Check that CSP was set on the prerendered page prior to activation.
  {
    const std::vector<network::mojom::ContentSecurityPolicyPtr>& root_csp_pre =
        prerendered_render_frame_host->policy_container_host()
            ->policies()
            .content_security_policies;
    EXPECT_EQ(1u, root_csp_pre.size());
    EXPECT_EQ("frame-src 'none'", root_csp_pre[0]->header->header_value);
    EXPECT_EQ(prerendered_render_frame_host->active_sandbox_flags(),
              network::mojom::WebSandboxFlags::kNone);
  }

  test::PrerenderHostObserver host_observer(*web_contents(), kPrerenderingUrl);
  NavigatePrimaryPage(kPrerenderingUrl);
  EXPECT_TRUE(host_observer.was_activated());
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);

  // Check that CSP was set on the prerendered page after activation.
  {
    const std::vector<network::mojom::ContentSecurityPolicyPtr>& root_csp_post =
        current_frame_host()
            ->policy_container_host()
            ->policies()
            .content_security_policies;
    EXPECT_EQ(1u, root_csp_post.size());
    EXPECT_EQ("frame-src 'none'", root_csp_post[0]->header->header_value);
    EXPECT_EQ(current_frame_host()->active_sandbox_flags(),
              network::mojom::WebSandboxFlags::kNone);
    EXPECT_EQ(static_cast<WebContentsImpl*>(web_contents())
                  ->GetPrimaryFrameTree()
                  .root()
                  ->active_sandbox_flags(),
              network::mojom::WebSandboxFlags::kNone);
  }
}

// Check that the Content-Security-Policy set via HTTP header applies after the
// activation. This test verifies that that the web sandbox flags value is set
// to allow scripts.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       ActivatePageWithCspHeaderSandboxFlags) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl =
      GetUrl("/set-header?Content-Security-Policy: sandbox allow-scripts");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  RenderFrameHostImpl* prerendered_render_frame_host =
      GetPrerenderedMainFrameHost(host_id);

  // Check that CSP was set on the prerendered page prior to activation.
  {
    const std::vector<network::mojom::ContentSecurityPolicyPtr>& root_csp_pre =
        prerendered_render_frame_host->policy_container_host()
            ->policies()
            .content_security_policies;
    EXPECT_EQ(1u, root_csp_pre.size());
    EXPECT_EQ("sandbox allow-scripts", root_csp_pre[0]->header->header_value);
    EXPECT_EQ(prerendered_render_frame_host->active_sandbox_flags(),
              network::mojom::WebSandboxFlags::kAll &
                  ~network::mojom::WebSandboxFlags::kScripts &
                  ~network::mojom::WebSandboxFlags::kAutomaticFeatures);
  }

  test::PrerenderHostObserver host_observer(*web_contents(), kPrerenderingUrl);
  NavigatePrimaryPage(kPrerenderingUrl);
  EXPECT_TRUE(host_observer.was_activated());
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);

  // Check that CSP was set on the prerendered page after activation.
  {
    const std::vector<network::mojom::ContentSecurityPolicyPtr>& root_csp_post =
        current_frame_host()
            ->policy_container_host()
            ->policies()
            .content_security_policies;
    EXPECT_EQ(1u, root_csp_post.size());
    EXPECT_EQ("sandbox allow-scripts", root_csp_post[0]->header->header_value);
    EXPECT_EQ(current_frame_host()->active_sandbox_flags(),
              network::mojom::WebSandboxFlags::kAll &
                  ~network::mojom::WebSandboxFlags::kScripts &
                  ~network::mojom::WebSandboxFlags::kAutomaticFeatures);
    EXPECT_EQ(static_cast<WebContentsImpl*>(web_contents())
                  ->GetPrimaryFrameTree()
                  .root()
                  ->active_sandbox_flags(),
              network::mojom::WebSandboxFlags::kAll &
                  ~network::mojom::WebSandboxFlags::kScripts &
                  ~network::mojom::WebSandboxFlags::kAutomaticFeatures);
  }
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, VerifyPrerenderProcessVisibility) {
  // Navigate the primary main frame to an initial page.
  const GURL kInitialUrl = GetUrl("/empty.html?initial");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start a prerender.
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  RenderFrameHost* prerender_frame_host = GetPrerenderedMainFrameHost(host_id);
  RenderProcessHost* prerender_process_host =
      prerender_frame_host->GetProcess();
  ASSERT_NE(prerender_frame_host, nullptr);
  // Ensure that a prerender process is backgrounded. This will put prerender
  // processes in lower priority compared to other active processes. (See
  // https://crbug.com/1211665)
  EXPECT_TRUE(prerender_process_host->GetPriority() ==
              base::Process::Priority::kBestEffort);

  // Activate the prerendered page.
  test::PrerenderHostObserver host_observer(*web_contents(), kPrerenderingUrl);
  NavigatePrimaryPage(kPrerenderingUrl);
  EXPECT_TRUE(host_observer.was_activated());
  // Expect the change in the ChildProcessLauncherPriority to increase priority.
  EXPECT_NE(prerender_process_host->GetPriority(),
            base::Process::Priority::kBestEffort);
}

class PrerenderSpecificRequestHeadersBrowserTest
    : public PrerenderBrowserTest,
      public testing::WithParamInterface<bool> {
 public:
  PrerenderSpecificRequestHeadersBrowserTest() {
    if (GetParam()) {
      feature_list_.InitAndEnableFeature(
          blink::features::kRemovePurposeHeaderForPrefetch);
    } else {
      feature_list_.InitAndDisableFeature(
          blink::features::kRemovePurposeHeaderForPrefetch);
    }
  }
  ~PrerenderSpecificRequestHeadersBrowserTest() override = default;

  void SetUp() override {
    ssl_server().RegisterRequestHandler(
        base::BindRepeating(&HandleCorsRequest));
    PrerenderBrowserTest::SetUp();
  }

  bool IsRemovePurposeHeaderEnabled() const { return GetParam(); }

  static std::unique_ptr<net::test_server::HttpResponse> HandleCorsRequest(
      const net::test_server::HttpRequest& request) {
    // The "Purpose: prefetch" header shouldn't cause CORS preflights.
    EXPECT_NE(request.method_string, "OPTIONS");

    // Ignore if the request is not cross origin.
    //
    // Note: Checking the origin of `request.GetURL()` doesn't work here because
    // the host part of the URL is translated (e.g., "a.test" to "127.0.0.1")
    // based on the host resolver rule before this point.
    if (request.relative_url.find("cors") == std::string::npos) {
      return nullptr;
    }

    // Serves a fake response with the ACAO header.
    auto response = std::make_unique<net::test_server::BasicHttpResponse>();
    response->AddCustomHeader("Access-Control-Allow-Origin", "*");
    response->set_code(net::HTTP_OK);
    response->set_content("");
    response->set_content_type("text/plain");
    return response;
  }

  bool TestSecPurposePrefetchHeader(const GURL& url) {
    net::test_server::HttpRequest::HeaderMap headers = GetRequestHeaders(url);

    // Test Purpose headers based on feature flag state
    auto purpose_it = headers.find(blink::kPurposeHeaderName);
    if (IsRemovePurposeHeaderEnabled()) {
      // When feature is enabled, legacy Purpose header should be removed
      EXPECT_EQ(headers.end(), purpose_it)
          << "Purpose header should not be present when feature is enabled";
    } else {
      // When feature is disabled, legacy Purpose header should be present
      if (purpose_it == headers.end()) {
        return false;
      }
      EXPECT_EQ(blink::kSecPurposePrefetchHeaderValue, purpose_it->second);
    }

    auto sec_purpose_it = headers.find(blink::kSecPurposeHeaderName);
    if (sec_purpose_it == headers.end()) {
      return false;
    }
    EXPECT_EQ(blink::kSecPurposePrefetchPrerenderHeaderValue,
              sec_purpose_it->second);
    return true;
  }

  bool HasSecSpeculationTagsHeader(const GURL& url) {
    net::test_server::HttpRequest::HeaderMap headers = GetRequestHeaders(url);
    return headers.contains(blink::kSecSpeculationTagsHeaderName);
  }

  std::string GetSecSpeculationTagsHeader(const GURL& url) {
    net::test_server::HttpRequest::HeaderMap headers = GetRequestHeaders(url);
    EXPECT_TRUE(headers.contains(blink::kSecSpeculationTagsHeaderName));
    return headers[blink::kSecSpeculationTagsHeaderName];
  }

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

// Tests that a request for the initial prerender navigation has the
// Purpose and Sec-Purpose headers, but not the Sec-Speculation-Tags header.
IN_PROC_BROWSER_TEST_P(PrerenderSpecificRequestHeadersBrowserTest,
                       InitialNavigation_Embedder) {
  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), GetUrl("/empty.html")));

  // Start prerendering.
  const GURL prerender_url = GetUrl("/empty.html?prerender");
  std::unique_ptr<PrerenderHandle> prerender_handle =
      AddEmbedderTriggeredPrerender(prerender_url);
  EXPECT_TRUE(prerender_handle);

  // The embedder-triggered prerender request should have the purpose headers,
  // but not the Sec-Speculation-Tags header.
  EXPECT_TRUE(TestSecPurposePrefetchHeader(prerender_url));
  EXPECT_FALSE(HasSecSpeculationTagsHeader(prerender_url));
}

// Tests that a redirected request for the initial prerender navigation has the
// Purpose, Sec-Purpose, and Sec-Speculation-Tags headers.
//
// TODO(nhiroki/domenic): Move this test to WPT.
// speculation-rules/prerender/headers.https.html is a good starting point.
IN_PROC_BROWSER_TEST_P(PrerenderSpecificRequestHeadersBrowserTest,
                       RedirectionOnInitialNavigation) {
  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), GetUrl("/empty.html")));

  // Start prerendering a URL that causes same-origin redirection.
  const GURL kRedirectedUrl = GetUrl("/empty.html?prerender");
  const GURL kPrerenderingUrl =
      GetUrl("/server-redirect?" + kRedirectedUrl.spec());
  RedirectChainObserver redirect_chain_observer(*shell()->web_contents(),
                                                kRedirectedUrl);
  AddPrerender(kPrerenderingUrl);
  ASSERT_EQ(2u, redirect_chain_observer.redirect_chain().size());
  EXPECT_EQ(kPrerenderingUrl, redirect_chain_observer.redirect_chain()[0]);
  EXPECT_EQ(kRedirectedUrl, redirect_chain_observer.redirect_chain()[1]);

  // Both the initial request and the redirected request should have the
  // headers.
  EXPECT_TRUE(TestSecPurposePrefetchHeader(kPrerenderingUrl));
  EXPECT_TRUE(HasSecSpeculationTagsHeader(kPrerenderingUrl));
  EXPECT_EQ(GetSecSpeculationTagsHeader(kPrerenderingUrl), "null");
  EXPECT_TRUE(TestSecPurposePrefetchHeader(kRedirectedUrl));
  EXPECT_TRUE(HasSecSpeculationTagsHeader(kRedirectedUrl));
  EXPECT_EQ(GetSecSpeculationTagsHeader(kRedirectedUrl), "null");
}

IN_PROC_BROWSER_TEST_P(PrerenderSpecificRequestHeadersBrowserTest,
                       SpeculationRulesTagsMergingForImmediateCandidates) {
  const GURL initial_url =
      GetUrl("/prerender/multiple_prerender_with_tags.html");
  const GURL prerender_url = GetUrl("/prerender/empty.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  WaitForPrerenderLoadCompletion(prerender_url);

  EXPECT_TRUE(HasSecSpeculationTagsHeader(prerender_url));
  EXPECT_EQ(GetSecSpeculationTagsHeader(prerender_url), "\"tag1\", \"tag2\"");
}

IN_PROC_BROWSER_TEST_P(PrerenderSpecificRequestHeadersBrowserTest,
                       SpeculationRulesTagForSameSiteCrossOrigin) {
  const GURL initial_url = GetUrl("/prerender/empty.html");
  const GURL prerender_url =
      GetSameSiteCrossOriginUrl("/prerender/prerender_with_opt_in_header.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  PrerenderHostId host_id = AddPrerenderWithTags(prerender_url, "tag1");
  auto* prerendered_rfh = GetPrerenderedMainFrameHost(host_id);
  EXPECT_TRUE(prerendered_rfh != nullptr);

  EXPECT_TRUE(HasSecSpeculationTagsHeader(prerender_url));
  EXPECT_EQ(GetSecSpeculationTagsHeader(prerender_url), "\"tag1\"");
}

// This prefetch test is tentatively implemented here to reuse the test infra.
// TODO(crbug.com/381687257): Move this test to prefetch browser tests.
IN_PROC_BROWSER_TEST_P(PrerenderSpecificRequestHeadersBrowserTest, Prefetch) {
  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), GetUrl("/empty.html")));

  test::TestPrefetchWatcher test_prefetch_watcher;

  // Start prefetching.
  const GURL prefetch_url = GetUrl("/empty.html?prefetch");
  AddPrefetchAsync(prefetch_url);

  test_prefetch_watcher.WaitUntilPrefetchResponseCompleted(
      static_cast<RenderFrameHostImpl*>(
          shell()->web_contents()->GetPrimaryMainFrame())
          ->GetDocumentToken(),
      prefetch_url);

  EXPECT_TRUE(HasSecSpeculationTagsHeader(prefetch_url));
  EXPECT_EQ(GetSecSpeculationTagsHeader(prefetch_url), "null");
}

// Test that there is no tags merging if both of the candidates are enacted.
IN_PROC_BROWSER_TEST_P(PrerenderSpecificRequestHeadersBrowserTest,
                       SpeculationRulesTagsMergingForNonImmediateCandidates) {
#if !BUILDFLAG(IS_ANDROID)
  const GURL initial_url = GetUrl(
      "/prerender/multiple_prerender_with_tags_and_different_eagerness.html");
  const GURL prerender_url = GetUrl("/prerender/empty.html");

  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  InsertAnchor(prerender_url);
  PointerDownToAnchor(prerender_url);
  WaitForPrerenderLoadCompletion(prerender_url);

  EXPECT_TRUE(HasSecSpeculationTagsHeader(prerender_url));
  EXPECT_EQ(GetSecSpeculationTagsHeader(prerender_url),
            "\"conservative\", \"moderate\"");
#else
  // Android doesn't support pointer interaction.
  GTEST_SKIP();
#endif  // BUILDFLAG(IS_ANDROID)
}

// Test that there is no tags merging if only one of the candidates is enacted.
IN_PROC_BROWSER_TEST_P(PrerenderSpecificRequestHeadersBrowserTest,
                       SpeculationRulesTagsNoMergingForNonImmediateCandidates) {
#if !BUILDFLAG(IS_ANDROID)
  const GURL initial_url = GetUrl(
      "/prerender/multiple_prerender_with_tags_and_different_eagerness.html");
  const GURL prerender_url = GetUrl("/prerender/empty.html");

  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  InsertAnchor(prerender_url);
  PointerHoverToAnchor(prerender_url);
  WaitForPrerenderLoadCompletion(prerender_url);

  EXPECT_TRUE(HasSecSpeculationTagsHeader(prerender_url));
  EXPECT_EQ(GetSecSpeculationTagsHeader(prerender_url), "\"moderate\"");
#else
  // Android doesn't support pointer interaction.
  GTEST_SKIP();
#endif  // BUILDFLAG(IS_ANDROID)
}

INSTANTIATE_TEST_SUITE_P(RemovePurposeHeaderVariations,
                         PrerenderSpecificRequestHeadersBrowserTest,
                         ::testing::Bool());

class PrerenderUserAgentOverrideBrowserTest : public PrerenderBrowserTest {
 public:
  PrerenderUserAgentOverrideBrowserTest() {
    feature_list_.InitAndEnableFeature(
        features::kPreloadingRespectUserAgentOverride);
  }
  ~PrerenderUserAgentOverrideBrowserTest() override = default;

  std::string GetUserAgentHeader(const GURL& url) {
    net::test_server::HttpRequest::HeaderMap headers = GetRequestHeaders(url);
    EXPECT_TRUE(headers.contains(net::HttpRequestHeaders::kUserAgent));
    return headers[net::HttpRequestHeaders::kUserAgent];
  }

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

// WebContentsDelegate to set UserAgentOverrideOption for prefetch and
// prerender.
class ScopedUserAgentOverrideTestDelegate : public WebContentsDelegate {
 public:
  explicit ScopedUserAgentOverrideTestDelegate(WebContents& web_contents)
      : web_contents_(web_contents.GetWeakPtr()) {
    web_contents_->SetDelegate(this);
  }
  ~ScopedUserAgentOverrideTestDelegate() override {
    if (web_contents_) {
      web_contents_->SetDelegate(nullptr);
    }
  }

  NavigationController::UserAgentOverrideOption
  ShouldOverrideUserAgentForPreloading(const GURL& url) override {
    return override_option_;
  }

  PreloadingEligibility IsPrerender2Supported(
      WebContents& web_contents,
      PreloadingTriggerType trigger_type) override {
    return PreloadingEligibility::kEligible;
  }

  void InheritOverride() {
    override_option_ =
        NavigationController::UserAgentOverrideOption::UA_OVERRIDE_INHERIT;
  }
  void ForceEnableOverride() {
    override_option_ =
        NavigationController::UserAgentOverrideOption::UA_OVERRIDE_TRUE;
  }
  void ForceDisableOverride() {
    override_option_ =
        NavigationController::UserAgentOverrideOption::UA_OVERRIDE_FALSE;
  }

 private:
  NavigationController::UserAgentOverrideOption override_option_ =
      NavigationController::UserAgentOverrideOption::UA_OVERRIDE_INHERIT;
  base::WeakPtr<WebContents> web_contents_;
};

// Tests that WebContents-level User-Agent header overrides are used for
// prerender requests depending on `UserAgentOverrideOption`.
IN_PROC_BROWSER_TEST_F(PrerenderUserAgentOverrideBrowserTest,
                       EnabledToDisabled) {
  const GURL initial_url = GetUrl("/prerender/empty.html");
  const GURL prerendering_url_1 = GetUrl("/prerender/empty.html?prerender1");
  const GURL prerendering_url_2 = GetUrl("/prerender/empty.html?prerender2");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Set User-Agent override.
  shell()->web_contents()->SetUserAgentOverride(
      blink::UserAgentOverride::UserAgentOnly("fake"), true);
  ScopedUserAgentOverrideTestDelegate ua_override_delegate(
      *shell()->web_contents());

  // Enable UA override and start prerendering.
  ua_override_delegate.ForceEnableOverride();
  std::unique_ptr<PrerenderHandle> prerender_handle =
      AddEmbedderTriggeredPrerender(prerendering_url_1);
  ASSERT_TRUE(prerender_handle);

  // The prerender request should use the overridden User-Agent.
  EXPECT_EQ(GetUserAgentHeader(prerendering_url_1), "fake");

  // Disable UA override and start prerendering.
  ua_override_delegate.ForceDisableOverride();
  std::unique_ptr<PrerenderHandle> prerender_handle_2 =
      AddEmbedderTriggeredPrerender(prerendering_url_2);
  ASSERT_TRUE(prerender_handle_2);

  // The prerender request should NOT use the overridden User-Agent.
  EXPECT_NE(GetUserAgentHeader(prerendering_url_2), "fake");
}

// Tests that the WebContents-level User-Agent header override setting is
// inherited for prerender request with `UA_OVERRIDE_INHERIT`.
IN_PROC_BROWSER_TEST_F(PrerenderUserAgentOverrideBrowserTest, Inherit) {
  const GURL initial_url_1 = GetUrl("/empty.html");
  const GURL initial_url_2 = GetUrl("/title1.html");
  const GURL prerendering_url_1 = GetUrl("/prerender/empty.html?prerender");
  const GURL prerendering_url_2 = GetUrl("/prerender/empty.html?prerender2");

  // Set a User-Agent override and make sure `UserAgentOverrideOption` is
  // `UA_OVERRIDE_INHERIT`.
  shell()->web_contents()->SetUserAgentOverride(
      blink::UserAgentOverride::UserAgentOnly("fake"), true);
  ScopedUserAgentOverrideTestDelegate ua_override_delegate(
      *shell()->web_contents());
  ua_override_delegate.InheritOverride();

  // Scenario 1: Navigate from a page without UA override.
  {
    // Navigate to an initial page without UA override.
    ASSERT_TRUE(NavigateToURL(shell(), initial_url_1));
    ASSERT_FALSE(shell()
                     ->web_contents()
                     ->GetPrimaryMainFrame()
                     ->GetController()
                     .GetLastCommittedEntry()
                     ->GetIsOverridingUserAgent());

    // Start prerendering.
    std::unique_ptr<PrerenderHandle> prerender_handle =
        AddEmbedderTriggeredPrerender(prerendering_url_1);
    ASSERT_TRUE(prerender_handle);

    // The prerender request should NOT use the overridden User-Agent.
    EXPECT_NE(GetUserAgentHeader(prerendering_url_1), "fake");
  }

  // Scenario 2: Navigate from a page with UA override.
  {
    // Navigate to an initial page with UA override.
    shell()
        ->web_contents()
        ->GetPrimaryMainFrame()
        ->GetController()
        .GetLastCommittedEntry()
        ->SetIsOverridingUserAgent(true);
    ASSERT_TRUE(NavigateToURL(shell(), initial_url_2));
    ASSERT_TRUE(shell()
                    ->web_contents()
                    ->GetPrimaryMainFrame()
                    ->GetController()
                    .GetLastCommittedEntry()
                    ->GetIsOverridingUserAgent());

    // Start prerendering.
    std::unique_ptr<PrerenderHandle> prerender_handle =
        AddEmbedderTriggeredPrerender(prerendering_url_2);
    ASSERT_TRUE(prerender_handle);

    // The prerender request should use the overridden User-Agent.
    EXPECT_EQ(GetUserAgentHeader(prerendering_url_2), "fake");
  }
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, EnterFullscreen) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerendering");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start a prerender.
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  auto* prerendered_rfh = GetPrerenderedMainFrameHost(host_id);

  // We should disallow to enter Fullscreen by the inactive RFH.
  prerendered_rfh->EnterFullscreen(
      blink::mojom::FullscreenOptions::New(),
      base::BindOnce([](bool value) { EXPECT_FALSE(value); }));
  EXPECT_FALSE(web_contents_impl()->IsFullscreen());
}

namespace {
class TestJavaScriptDialogManager : public JavaScriptDialogManager,
                                    public WebContentsDelegate {
 public:
  TestJavaScriptDialogManager() = default;
  ~TestJavaScriptDialogManager() override = default;

  // WebContentsDelegate overrides
  JavaScriptDialogManager* GetJavaScriptDialogManager(
      WebContents* source) override {
    return this;
  }

  // JavaScriptDialogManager overrides
  void RunJavaScriptDialog(WebContents* web_contents,
                           RenderFrameHost* render_frame_host,
                           JavaScriptDialogType dialog_type,
                           const std::u16string& message_text,
                           const std::u16string& default_prompt_text,
                           DialogClosedCallback callback,
                           bool* did_suppress_message) override {}
  void RunBeforeUnloadDialog(WebContents* web_contents,
                             RenderFrameHost* render_frame_host,
                             bool is_reload,
                             DialogClosedCallback callback) override {}
  void CancelDialogs(WebContents* web_contents, bool reset_state) override {
    cancel_dialogs_called_ = true;
  }

  bool cancel_dialogs_called() { return cancel_dialogs_called_; }

 private:
  bool cancel_dialogs_called_ = false;
};

class PrerenderWithRenderDocumentBrowserTest : public PrerenderBrowserTest {
 public:
  PrerenderWithRenderDocumentBrowserTest() {
    InitAndEnableRenderDocumentFeature(
        &feature_list_,
        GetRenderDocumentLevelName(RenderDocumentLevel::kSubframe));
  }
  ~PrerenderWithRenderDocumentBrowserTest() override = default;

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

IN_PROC_BROWSER_TEST_F(
    PrerenderWithRenderDocumentBrowserTest,
    ModalDialogShouldNotBeDismissedAfterPrerenderSubframeNavigation) {
  const GURL kPrerenderingUrl = GetUrl("/title1.html");
  const GURL kSubframeUrl1 = GetUrl("/empty.html");
  const GURL kSubframeUrl2 = GetUrl("/title2.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), GetUrl("/empty.html")));

  // Start prerendering.
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  RenderFrameHost* prerender_rfh = GetPrerenderedMainFrameHost(host_id);
  CHECK(prerender_rfh);
  AddTestUtilJS(prerender_rfh);

  // Add subframe in prerendering page.
  ASSERT_TRUE(
      ExecJs(prerender_rfh, JsReplace("add_iframe($1)", kSubframeUrl1)));

  // Setup test dialog manager and create dialog.
  TestJavaScriptDialogManager dialog_manager;
  web_contents_impl()->SetDelegate(&dialog_manager);
  web_contents_impl()->RunJavaScriptDialog(
      web_contents_impl()->GetPrimaryMainFrame(), u"", u"",
      JAVASCRIPT_DIALOG_TYPE_ALERT, false, base::NullCallback());

  // Navigate subframe (with render document enabled, this should cause a RFH
  // swap).
  TestNavigationManager subframe_nav_manager(web_contents(), kSubframeUrl2);
  ASSERT_TRUE(ExecJs(
      prerender_rfh,
      JsReplace("document.querySelector('iframe').src = $1", kSubframeUrl2)));
  ASSERT_TRUE(subframe_nav_manager.WaitForNavigationFinished());

  // We should not dismiss dialogs when the prerender's subframe navigates and
  // swaps its RFH.
  EXPECT_FALSE(dialog_manager.cancel_dialogs_called());

  // Clean up test dialog manager.
  web_contents_impl()->SetDelegate(nullptr);
}

// Tests that NavigationHandle::GetNavigatingFrameType() returns the correct
// type in prerendering and after activation.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, NavigationHandleFrameType) {
  {
    const GURL kInitialUrl = GetUrl("/empty.html");
    DidFinishNavigationObserver observer(
        web_contents(),
        base::BindLambdaForTesting([](NavigationHandle* navigation_handle) {
          EXPECT_TRUE(navigation_handle->IsInPrimaryMainFrame());
          CHECK_EQ(navigation_handle->GetNavigatingFrameType(),
                   FrameType::kPrimaryMainFrame);
        }));
    // Navigate to an initial page.
    ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  }

  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");
  {
    DidFinishNavigationObserver observer(
        web_contents(),
        base::BindLambdaForTesting([](NavigationHandle* navigation_handle) {
          EXPECT_TRUE(navigation_handle->IsInPrerenderedMainFrame());
          CHECK_EQ(navigation_handle->GetNavigatingFrameType(),
                   FrameType::kPrerenderMainFrame);
        }));
    // Start prerendering.
    AddPrerender(kPrerenderingUrl);
  }

  {
    DidFinishNavigationObserver observer(
        web_contents(),
        base::BindLambdaForTesting([](NavigationHandle* navigation_handle) {
          EXPECT_TRUE(navigation_handle->IsInPrimaryMainFrame());
          EXPECT_TRUE(navigation_handle->IsPrerenderedPageActivation());
          CHECK_EQ(navigation_handle->GetNavigatingFrameType(),
                   FrameType::kPrimaryMainFrame);
        }));
    NavigatePrimaryPage(kPrerenderingUrl);
  }
}

// Tests that NavigationHandle::IsRendererInitiated() returns RendererInitiated
// = true correctly.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       NavigationHandleIsRendererInitiatedTrue) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");
  {
    DidFinishNavigationObserver observer(
        web_contents(),
        base::BindLambdaForTesting([](NavigationHandle* navigation_handle) {
          EXPECT_TRUE(navigation_handle->IsInPrerenderedMainFrame());
          EXPECT_TRUE(navigation_handle->IsRendererInitiated());
        }));
    // Start prerendering.
    AddPrerender(kPrerenderingUrl);
  }
  NavigatePrimaryPage(kPrerenderingUrl);
}

// Tests that FrameTreeNode::has_received_user_gesture_before_nav_ is not set on
// the prerendered main frame or the activated main frame when the primary main
// frame doesn't have it.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       HasReceivedUserGestureBeforeNavigation) {
  // Navigate to an initial page.
  const GURL initial_url = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // The primary main frame doesn't have the
  // has_received_user_gesture_before_nav bit.
  ASSERT_FALSE(current_frame_host()
                   ->frame_tree_node()
                   ->has_received_user_gesture_before_nav());

  // Start prerendering.
  const GURL prerendering_url = GetUrl("/empty.html?prerender");
  PrerenderHostId host_id = AddPrerender(prerendering_url);
  RenderFrameHostImpl* prerendered_render_frame_host =
      GetPrerenderedMainFrameHost(host_id);

  // The prerendered main frame should not have the bit.
  EXPECT_FALSE(prerendered_render_frame_host->frame_tree_node()
                   ->has_received_user_gesture_before_nav());

  // Activate the prerendered page.
  test::PrerenderHostObserver host_observer(*web_contents(), host_id);
  NavigatePrimaryPage(prerendering_url);
  ASSERT_TRUE(host_observer.was_activated());

  // The activated main frame should not have the bit.
  EXPECT_FALSE(current_frame_host()
                   ->frame_tree_node()
                   ->has_received_user_gesture_before_nav());
}

// Tests that FrameTreeNode::has_received_user_gesture_before_nav_ is not
// propagated from the primary main frame to the prerendered main frame but it
// is propagated to the activated main frame.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       HasReceivedUserGestureBeforeNavigation_Propagation) {
  // Navigate to an initial page.
  const GURL initial_url = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Set the has_received_user_gesture_before_nav bit on the primary main frame.
  current_frame_host()->HadStickyUserActivationBeforeNavigationChanged(true);
  ASSERT_TRUE(current_frame_host()
                  ->frame_tree_node()
                  ->has_received_user_gesture_before_nav());

  // Start prerendering.
  const GURL prerendering_url = GetUrl("/empty.html?prerender");
  PrerenderHostId host_id = AddPrerender(prerendering_url);
  RenderFrameHostImpl* prerendered_render_frame_host =
      GetPrerenderedMainFrameHost(host_id);

  // The prerendered main frame should not have the bit.
  EXPECT_FALSE(prerendered_render_frame_host->frame_tree_node()
                   ->has_received_user_gesture_before_nav());

  // Activate the prerendered page.
  test::PrerenderHostObserver host_observer(*web_contents(), host_id);
  NavigatePrimaryPage(prerendering_url);
  ASSERT_TRUE(host_observer.was_activated());

  // The activated main frame should have the bit.
  EXPECT_TRUE(current_frame_host()
                  ->frame_tree_node()
                  ->has_received_user_gesture_before_nav());
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       CancelPrerenderWhenIsOverridingUserAgentDiffers) {
  const std::string user_agent_override = "foo";

  // Navigate to an initial page.
  const GURL initial_url = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Enable user agent override for future navigations.
  UserAgentInjector injector(shell()->web_contents(), user_agent_override);

  const GURL prerendering_url = GetUrl("/empty.html?prerender");

  // Start prerendering.
  const PrerenderHostId host_id = AddPrerender(prerendering_url);

  RenderFrameHostImpl* prerender_rfh =
      static_cast<RenderFrameHostImpl*>(GetPrerenderedMainFrameHost(host_id));
  EXPECT_EQ(user_agent_override, EvalJs(prerender_rfh, "navigator.userAgent"));

  // Stop overriding user agent from now on.
  injector.set_is_overriding_user_agent(false);

  // Activate the prerendered page.
  test::PrerenderHostObserver host_observer(*web_contents(), host_id);
  NavigatePrimaryPage(prerendering_url);
  host_observer.WaitForDestroyed();

  ExpectFinalStatusForSpeculationRule(
      PrerenderFinalStatus::kActivationNavigationParameterMismatch);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.ActivationHeadersMismatch.SpeculationRule",
      -511888193, 1);
}

class PrerenderSpeculationRulesHoldbackBrowserTest
    : public PrerenderBrowserTest,
      public ::testing::WithParamInterface<bool> {
 public:
  PrerenderSpeculationRulesHoldbackBrowserTest() {
    if (GetParam()) {
      scoped_feature_list_prerender2_fallback_.InitWithFeaturesAndParameters(
          {
              {
                  features::kPrerender2FallbackPrefetchSpecRules,
                  {
                      {
                          features::
                              kPrerender2FallbackPrefetchUseBlockUntilHeadTimetout
                                  .name,
                          "false",
                      },
                      {
                          features::kPrerender2FallbackPrefetchSchedulerPolicy
                              .name,
                          "NotUse",
                      },
                  },
              },
          },
          {});
    } else {
      scoped_feature_list_prerender2_fallback_.InitWithFeaturesAndParameters(
          {}, {
                  features::kPrerender2FallbackPrefetchSpecRules,
              });
    }

    prerender_helper()->SetHoldback(
        PreloadingType::kPrerender,
        content_preloading_predictor::kSpeculationRules, true);
  }
  ~PrerenderSpeculationRulesHoldbackBrowserTest() override = default;

  bool IsPrerender2FallbackPrefetchSpecRulesEnabled() { return GetParam(); }

 private:
  base::test::ScopedFeatureList scoped_feature_list_prerender2_fallback_;
};

INSTANTIATE_TEST_SUITE_P(/* no prefix */,
                         PrerenderSpeculationRulesHoldbackBrowserTest,
                         ::testing::Bool());

IN_PROC_BROWSER_TEST_P(PrerenderSpeculationRulesHoldbackBrowserTest,
                       PrerenderHoldbackTest) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start prerendering `kPrerenderingUrl` this should fail as we are in
  // holdback.
  test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());
  AddPrerenderAsync(kPrerenderingUrl);

  // Wait for PrerenderHostRegistry to receive the holdback prerender
  // request, and it should be ignored.
  registry_observer.WaitForTrigger(kPrerenderingUrl);
  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));

  NavigationHandleObserver activation_observer(web_contents(),
                                               kPrerenderingUrl);
  NavigatePrimaryPage(kPrerenderingUrl);

  // Cross-check that PreloadingHoldbackStatus is correctly set.
  ukm::SourceId ukm_source_id = activation_observer.next_page_ukm_source_id();
  if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
    ExpectPreloadingAttemptUkm(
        {attempt_ukm_entry_builder().BuildEntry(
             ukm_source_id, PreloadingType::kPrefetch,
             PreloadingEligibility::kEligible,
             PreloadingHoldbackStatus::kAllowed,
             PreloadingTriggeringOutcome::kSuccess,
             PreloadingFailureReason::kUnspecified,
             /*accurate=*/true, /*ready_time=*/kMockElapsedTime,
             blink::mojom::SpeculationEagerness::kImmediate),
         attempt_ukm_entry_builder().BuildEntry(
             ukm_source_id, PreloadingType::kPrerender,
             PreloadingEligibility::kEligible,
             PreloadingHoldbackStatus::kHoldback,
             PreloadingTriggeringOutcome::kUnspecified,
             PreloadingFailureReason::kUnspecified,
             /*accurate=*/true,
             /*ready_time=*/std::nullopt,
             blink::mojom::SpeculationEagerness::kImmediate)});
  } else {
    ExpectPreloadingAttemptUkm({attempt_ukm_entry_builder().BuildEntry(
        ukm_source_id, PreloadingType::kPrerender,
        PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kHoldback,
        PreloadingTriggeringOutcome::kUnspecified,
        PreloadingFailureReason::kUnspecified,
        /*accurate=*/true,
        /*ready_time=*/std::nullopt,
        blink::mojom::SpeculationEagerness::kImmediate)});
  }
}

class PrerenderFencedFrameBrowserTest : public PrerenderBrowserTest {
 public:
  PrerenderFencedFrameBrowserTest() {
    feature_list_.InitWithFeaturesAndParameters(
        {{blink::features::kFencedFrames, {}},
         {::features::kPrivacySandboxAdsAPIsOverride, {}},
         {blink::features::kFencedFramesAPIChanges, {}},
         {blink::features::kFencedFramesDefaultMode, {}}},
        {/* disabled_features */});
  }
  ~PrerenderFencedFrameBrowserTest() override = default;

  void SetUp() override {
    ssl_server().RegisterRequestHandler(base::BindRepeating(
        &net::test_server::HandlePrefixedRequest,
        "/fenced-frame-with-speculation-rules",
        base::BindRepeating(HandleFencedFrameWithSpeculationRulesRequest)));
    ssl_server().RegisterRequestHandler(base::BindRepeating(
        &net::test_server::HandlePrefixedRequest,
        "/fenced-frame-with-speculation-rules-header",
        base::BindRepeating(
            HandleFencedFrameWithSpeculationRulesHeaderRequest)));
    ssl_server().RegisterRequestHandler(base::BindRepeating(
        &net::test_server::HandlePrefixedRequest, "/prerender.json",
        base::BindRepeating(HandlePrerenderJsonRequest)));
    PrerenderBrowserTest::SetUp();
  }

  static std::unique_ptr<net::test_server::HttpResponse>
  HandleFencedFrameWithSpeculationRulesRequest(
      const net::test_server::HttpRequest& request) {
    constexpr char kSpeculationRule[] = R"({
      <!doctype html>
      <script type="speculationrules">
      {
        "prerender":[
          {"source": "list", "urls": ["/empty.html"]}
        ]
      }
      </script>
    })";

    auto http_response =
        std::make_unique<net::test_server::BasicHttpResponse>();
    http_response->set_code(net::HTTP_OK);
    http_response->AddCustomHeader("Supports-Loading-Mode", "fenced-frame");
    http_response->set_content_type("text/html");
    http_response->set_content(kSpeculationRule);
    return http_response;
  }

  static std::unique_ptr<net::test_server::HttpResponse>
  HandleFencedFrameWithSpeculationRulesHeaderRequest(
      const net::test_server::HttpRequest& request) {
    auto http_response =
        std::make_unique<net::test_server::BasicHttpResponse>();
    http_response->set_code(net::HTTP_OK);
    http_response->AddCustomHeader("Supports-Loading-Mode", "fenced-frame");
    http_response->AddCustomHeader("Speculation-Rules", "\"/prerender.json\"");
    http_response->set_content_type("text/html");
    http_response->set_content("<!doctype html>nothing");
    return http_response;
  }

  static std::unique_ptr<net::test_server::HttpResponse>
  HandlePrerenderJsonRequest(const net::test_server::HttpRequest& request) {
    constexpr char kSpeculationRule[] = R"(
      {
        "prerender":[
          {"source": "list", "urls": ["/empty.html"]}
        ]
      }
    )";

    auto http_response =
        std::make_unique<net::test_server::BasicHttpResponse>();
    http_response->set_code(net::HTTP_OK);
    http_response->set_content_type("application/speculationrules+json");
    http_response->set_content(kSpeculationRule);
    return http_response;
  }

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

// Test that creating a fenced frame in a prerendered page is deferred until
// activation.
IN_PROC_BROWSER_TEST_F(PrerenderFencedFrameBrowserTest,
                       CreateFencedFrameInPrerenderedPage) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");
  const GURL kFencedFrameUrl = GetUrl("/title1.html");
  constexpr char kAddFencedFrameScript[] = R"({
    const fenced_frame = document.createElement('fencedframe');
    fenced_frame.config = new FencedFrameConfig($1);
    document.body.appendChild(fenced_frame);
  })";

  const int kNumNavigations = 3;
  TestNavigationObserver nav_observer(web_contents(), kNumNavigations);

  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  EXPECT_EQ(kInitialUrl, nav_observer.last_navigation_url());

  // Start a prerender.
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  auto* prerendered_rfh = GetPrerenderedMainFrameHost(host_id);
  EXPECT_TRUE(ExecJs(prerendered_rfh,
                     JsReplace(kAddFencedFrameScript, kFencedFrameUrl)));
  // Since we've deferred creating the fenced frame delegate, we should see no
  // child frames.
  size_t child_frame_count = 0;
  prerendered_rfh->ForEachRenderFrameHostImpl([&](RenderFrameHostImpl* rfh) {
    if (rfh != prerendered_rfh) {
      child_frame_count++;
    }
  });
  EXPECT_EQ(0lu, child_frame_count);

  NavigatePrimaryPage(kPrerenderingUrl);
  EXPECT_EQ(kPrerenderingUrl, nav_observer.last_navigation_url());
  nav_observer.Wait();
  EXPECT_EQ(kFencedFrameUrl, nav_observer.last_navigation_url());
}

// Test that prerendering triggered by fenced frames with speculation rules is
// blocked.
IN_PROC_BROWSER_TEST_F(PrerenderFencedFrameBrowserTest,
                       PrerenderFromFencedFrame_SpeculationRules) {
  const GURL initial_url = GetUrl("/empty.html");
  const GURL fenced_frame_url = GetUrl("/fenced-frame-with-speculation-rules");
  constexpr char kAddFencedFrameScript[] = R"({
    const fenced_frame = document.createElement('fencedframe');
    fenced_frame.config = new FencedFrameConfig($1);
    document.body.appendChild(fenced_frame);
  })";

  // Prerendering triggered by fenced frames will be blocked. To detect it, we
  // need to wait its failure by monitoring a console error.
  const char* console_pattern =
      "The SpeculationRules API does not support prerendering in fenced "
      "frames.";
  WebContentsConsoleObserver console_observer(web_contents());
  console_observer.SetPattern(console_pattern);

  // Start prerendering from fenced frames.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  RenderFrameHostImpl* primary_rfh = web_contents_impl()->GetPrimaryMainFrame();
  EXPECT_TRUE(
      ExecJs(primary_rfh, JsReplace(kAddFencedFrameScript, fenced_frame_url)));

  ASSERT_TRUE(console_observer.Wait());

  histogram_tester().ExpectTotalCount(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule", 0);
}

// Test that prerendering triggered by fenced frames with speculation rules
// header is blocked.
IN_PROC_BROWSER_TEST_F(PrerenderFencedFrameBrowserTest,
                       PrerenderFromFencedFrame_LinkSpeculationRules) {
  const GURL initial_url = GetUrl("/empty.html");
  const GURL fenced_frame_url =
      GetUrl("/fenced-frame-with-speculation-rules-header");
  constexpr char kAddFencedFrameScript[] = R"({
    const fenced_frame = document.createElement('fencedframe');
    fenced_frame.config = new FencedFrameConfig($1);
    document.body.appendChild(fenced_frame);
  })";

  // Prerendering triggered by fenced frames will be blocked. To detect it, we
  // need to wait its failure by monitoring a console error.
  const char* console_pattern =
      "The SpeculationRules API does not support prerendering in fenced "
      "frames.";
  WebContentsConsoleObserver console_observer(web_contents());
  console_observer.SetPattern(console_pattern);

  // Start prerendering from fenced frames.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  RenderFrameHostImpl* primary_rfh = web_contents_impl()->GetPrimaryMainFrame();
  EXPECT_TRUE(
      ExecJs(primary_rfh, JsReplace(kAddFencedFrameScript, fenced_frame_url)));

  ASSERT_TRUE(console_observer.Wait());

  histogram_tester().ExpectTotalCount(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule", 0);
}

namespace {

class PrerenderWithSiteIsolationDisabledBrowserTest
    : public PrerenderBrowserTest {
 public:
  PrerenderWithSiteIsolationDisabledBrowserTest() = default;
  ~PrerenderWithSiteIsolationDisabledBrowserTest() override = default;

  void SetUpCommandLine(base::CommandLine* command_line) override {
    PrerenderBrowserTest::SetUpCommandLine(command_line);
    command_line->AppendSwitch(switches::kDisableSiteIsolation);
  }
};

}  // namespace

// This test sets up a scenario where we swap SiteInstances during a prerender
// page's first navigation. Full site isolation is disabled for this test, but
// we dynamically isolate "b.test". The max process count is also set to 1.
//
// We initially start off with navigating the primary main frame to b.test,
// which will be assigned to a process P1.
//
// P1 ----- b.test
//
// We then add an a.test iframe, which will be assigned to a different process
// P2. This is because P1 currently hosts content from b.test, and b.test has
// been configured to require isolation from other sites.
//
// P1 ------ b.test
// P2 ------ a.test
//
// We then start prerendering b.test. This happens in two steps. In the first
// step we initialize the FrameTree and create an empty main frame that hasn't
// been navigated. This empty main frame has an empty SiteInstance (prerenders
// use an empty SiteInfo for this currently) which is assigned to P2 (in normal
// circumstances, it would be assigned to a new process but because we're above
// the process limit, it tries to reuse an existing process, and P2 is eligible
// as it currently only has the a.test iframe and a.test does not need to be
// isolated).
//
// P1 ------ b.test
// P2 ------ a.test, <empty prerender>
//
// In the second step, we navigate the prerender main frame to the prerender
// url, which is b.test. Now b.test is configured to be in an isolated process,
// so we can't reuse the current SiteInstance (as it is assigned to P1 which has
// content from a.test), and have to move it to a new process (and therefore
// have to swap the SiteInstance).
//
// P1 ------ b.test (primary), b.test (prerender)
// P2 ------ a.test
IN_PROC_BROWSER_TEST_F(PrerenderWithSiteIsolationDisabledBrowserTest,
                       ForceSiteInstanceSwapForInitialPrerenderNavigation) {
  if (AreAllSitesIsolatedForTesting()) {
    LOG(ERROR) << "Site Isolation should be disabled for this test.";
    return;
  }

  // Set max renderer process count to force process reuse and prevent
  // prerendering pages from getting dedicated processes by default.
  RenderProcessHost::SetMaxRendererProcessCount(1);

  const GURL kInitialUrl =
      ssl_server().GetURL("isolated.b.test", "/empty.html");
  const GURL kIframeUrl = ssl_server().GetURL("a.test", "/empty.html");
  const GURL kPrerenderingUrl =
      ssl_server().GetURL("isolated.b.test", "/title1.html");

  auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
  policy->AddFutureIsolatedOrigins(
      {url::Origin::Create(kInitialUrl)},
      ChildProcessSecurityPolicy::IsolatedOriginSource::TEST);

  // Navigate primary main frame to b.test. It will be assigned to a process
  // that is locked to b.test.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Add an a.test iframe, which will be loaded in a new process that isn't
  // locked.
  ASSERT_TRUE(AddTestUtilJS(current_frame_host()));
  ASSERT_TRUE(
      ExecJs(current_frame_host(), JsReplace("add_iframe($1)", kIframeUrl)));
  RenderFrameHostImplWrapper iframe(
      static_cast<RenderFrameHostImpl*>(ChildFrameAt(current_frame_host(), 0)));
  ASSERT_NE(current_frame_host()->GetProcess(), iframe->GetProcess());

  // Prerender b.test. The initial empty document will be assigned to
  // the same process as the a.test iframe, but on navigation to b.test, it
  // can no longer use the same process, and the SiteInstance will have to be
  // changed in order to assign the document to a different process.
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  RenderFrameHostImplWrapper prerender_rfh(
      GetPrerenderedMainFrameHost(host_id));
  EXPECT_EQ(prerender_rfh->lifecycle_state(),
            LifecycleStateImpl::kPrerendering);
  EXPECT_EQ(prerender_rfh->GetProcess(), current_frame_host()->GetProcess());
}

class PrerenderClientHintsBrowserTest : public PrerenderBrowserTest {
 public:
  PrerenderClientHintsBrowserTest() = default;
  ~PrerenderClientHintsBrowserTest() override = default;

  void SetUp() override {
    ssl_server().RegisterRequestHandler(base::BindRepeating(&HandleRequest));
    PrerenderBrowserTest::SetUp();
  }

  static std::unique_ptr<net::test_server::HttpResponse> HandleRequest(
      const net::test_server::HttpRequest& request) {
    if (request.relative_url.find("acceptch") == std::string::npos) {
      return nullptr;
    }

    // Serve a response indicating clients to provide full version of UA.
    auto response = std::make_unique<net::test_server::BasicHttpResponse>();
    if (request.relative_url.find("full-version") != std::string::npos) {
      response->AddCustomHeader("Accept-CH", "sec-ch-ua-full-version");
    } else if (request.relative_url.find("bitness") != std::string::npos) {
      response->AddCustomHeader("Accept-CH", "sec-ch-ua-bitness");
    } else if (request.relative_url.find("viewport-width") !=
               std::string::npos) {
      response->AddCustomHeader("Accept-CH", "viewport-width");
      response->AddCustomHeader("Accept-CH", "sec-ch-viewport-width");
    } else if (request.relative_url.find("viewport-height") !=
               std::string::npos) {
      // Don't need to add "viewport-height" as it is not defined in the specs.
      response->AddCustomHeader("Accept-CH", "sec-ch-viewport-height");
    } else if (request.relative_url.find("no-value") != std::string::npos) {
      response->AddCustomHeader("Accept-CH", "");
    }
    response->set_code(net::HTTP_OK);
    if (request.relative_url.find("iframe") != std::string::npos) {
      response->set_content(R"(
        <html><head><title>iframe test</title></head>
        <body>
        <iframe src="title1.html" id="test"></iframe>
        </body></html>
      )");
      response->set_content_type("text/html");
    } else if (request.relative_url.find("image") != std::string::npos) {
      response->set_content(R"(
        <html>
        <head></head>
        <body>
          <img src="./blank.jpg"/>
          <p>This page has an image. Yay for images!
        </body>
        </html>
      )");
      response->set_content_type("text/html");

    } else {
      response->set_content("");
      response->set_content_type("text/plain");
    }
    return response;
  }

 protected:
  bool HasRequestHeader(const GURL& url, const std::string& key) {
    net::test_server::HttpRequest::HeaderMap headers = GetRequestHeaders(url);
    return headers.find(key) != headers.end();
  }
};

IN_PROC_BROWSER_TEST_F(PrerenderClientHintsBrowserTest,
                       PrerenderResponseChangesClientHintsLocally) {
  MockClientHintsControllerDelegate client_hints_controller_delegate(
      GetShellUserAgentMetadata());
  ShellContentBrowserClient::Get()
      ->browser_context()
      ->set_client_hints_controller_delegate(&client_hints_controller_delegate);

  // Navigate to an initial page.
  GURL url = GetUrl("/empty.html?acceptch-bitness");
  ASSERT_TRUE(NavigateToURL(shell(), url));

  // Start prerendering.
  GURL prerender_url = GetUrl("/iframe.html?acceptch-full-version");
  PrerenderHostId host_id = AddPrerender(prerender_url);

  // The main frame request does not contain sec-ch-ua-full-version, because it
  // is using the global setting at this moment. sec-ch-ua-bitness should be
  // contained as well, because it is a global setting and applies to all
  // navigations.
  EXPECT_TRUE(HasRequestHeader(prerender_url, "sec-ch-ua-bitness"));
  EXPECT_FALSE(HasRequestHeader(prerender_url, "sec-ch-ua-full-version"));

  // The subframe prerender navigation requests should contain
  // sec-ch-ua-full-version, as the main frame navigation request changed the
  // client hints setting.
  GURL prerender_iframe_url = GetUrl("/title1.html");
  WaitForRequest(prerender_iframe_url, 1);
  EXPECT_TRUE(HasRequestHeader(prerender_iframe_url, "sec-ch-ua-full-version"));
  EXPECT_TRUE(HasRequestHeader(prerender_iframe_url, "sec-ch-ua-bitness"));

  test::PrerenderHostObserver prerender_observer(*web_contents_impl(), host_id);
  NavigatePrimaryPage(prerender_url);

  // The prerendered page should be activated successfully. The settings on the
  // prerendered page should not apply to the primary navigation before
  // activation, so at this point the navigation request is using the global
  // setting, which is the same as the prerender initial navigation.
  prerender_observer.WaitForActivation();

  GURL real_navigate_url = GetUrl("/empty.html?real");
  NavigatePrimaryPage(real_navigate_url);

  // The request headers should contain sec-ch-ua-full-version, because the
  // prerender local setting was propagated to the global setting. The final
  // setting is the union set of global setting and local setting.
  EXPECT_TRUE(HasRequestHeader(real_navigate_url, "sec-ch-ua-full-version"));
  EXPECT_TRUE(HasRequestHeader(prerender_iframe_url, "sec-ch-ua-bitness"));
}

IN_PROC_BROWSER_TEST_F(PrerenderClientHintsBrowserTest,
                       ChangesToClientHintsAreDiscardIfNoActivation) {
  MockClientHintsControllerDelegate client_hints_controller_delegate(
      GetShellUserAgentMetadata());
  ShellContentBrowserClient::Get()
      ->browser_context()
      ->set_client_hints_controller_delegate(&client_hints_controller_delegate);

  // Navigate to an initial page.
  GURL url = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), url));

  // Start prerendering.
  GURL prerender_url = GetUrl("/empty.html?acceptch");
  GURL real_navigate_url = GetUrl("/empty.html?real");

  PrerenderHostId host_id = AddPrerender(prerender_url);
  test::PrerenderHostObserver prerender_observer(*web_contents_impl(), host_id);
  NavigatePrimaryPage(real_navigate_url);

  // The request headers should not contain sec-ch-ua-full-version, because no
  // primary pages indicate to do so and the prerender local setting has been
  // discarded.
  EXPECT_FALSE(HasRequestHeader(real_navigate_url, "sec-ch-ua-full-version"));
  GURL real_navigate_url_2 = GetUrl("/empty.html?real2");
  NavigatePrimaryPage(real_navigate_url_2);

  // The request headers should not contain sec-ch-ua-full-version, because no
  // primary pages indicate to do so and the prerender local setting has been
  // discarded.
  EXPECT_FALSE(HasRequestHeader(real_navigate_url_2, "sec-ch-ua-full-version"));
}

IN_PROC_BROWSER_TEST_F(PrerenderClientHintsBrowserTest,
                       PrimaryResponsesDoNotResetPrenderSettings) {
  MockClientHintsControllerDelegate client_hints_controller_delegate(
      GetShellUserAgentMetadata());
  ShellContentBrowserClient::Get()
      ->browser_context()
      ->set_client_hints_controller_delegate(&client_hints_controller_delegate);

  // Navigate to an initial page.
  GURL url = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), url));

  // Start prerendering.
  GURL prerender_url = GetUrl("/iframe.html?acceptch-full-version");
  PrerenderHostId host_id = AddPrerender(prerender_url);

  // The main frame request does not contain sec-ch-ua-full-version, because it
  // is using the global setting at this moment.
  EXPECT_FALSE(HasRequestHeader(prerender_url, "sec-ch-ua-full-version"));

  // The subframe prerender navigation requests should contain
  // sec-ch-ua-full-version, as the main frame navigation request changed the
  // client hints setting.
  GURL prerender_iframe_url = GetUrl("/title1.html");
  WaitForRequest(prerender_iframe_url, 1);
  EXPECT_TRUE(HasRequestHeader(prerender_iframe_url, "sec-ch-ua-full-version"));

  // Open a new tab, and the new page clears all settings.
  GURL new_tab_url = GetUrl("/image.html?acceptch-no-value");
  OpenURLParams params(
      new_tab_url, Referrer(), WindowOpenDisposition::NEW_BACKGROUND_TAB,
      ui::PAGE_TRANSITION_LINK, /*is_renderer_initiated=*/false);
  auto* new_web_contents =
      web_contents_impl()->OpenURL(params, /*navigation_handle_callback=*/{});
  ASSERT_NE(nullptr, new_web_contents);
  GURL new_tab_image_url = GetUrl("/blank.jpg");
  WaitForRequest(new_tab_image_url, 1);
  EXPECT_FALSE(HasRequestHeader(new_tab_url, "sec-ch-ua-full-version"));

  test::PrerenderHostObserver prerender_observer(*web_contents_impl(), host_id);
  NavigatePrimaryPage(prerender_url);

  // The prerendered page should be activated successfully.
  prerender_observer.WaitForActivation();

  GURL real_navigate_url = GetUrl("/empty.html?real");
  NavigatePrimaryPage(real_navigate_url);

  // The request headers should contain sec-ch-ua-full-version, because the
  // prerender local setting was propagated to the global setting.
  EXPECT_TRUE(HasRequestHeader(real_navigate_url, "sec-ch-ua-full-version"));
}

// Test that changes on the viewport width of the initiator page between when to
// trigger prerendering and when to activate don't fail activation params match.
IN_PROC_BROWSER_TEST_F(PrerenderClientHintsBrowserTest, ViewPort_Width) {
  MockClientHintsControllerDelegate client_hints_controller_delegate(
      GetShellUserAgentMetadata());
  ShellContentBrowserClient::Get()
      ->browser_context()
      ->set_client_hints_controller_delegate(&client_hints_controller_delegate);

  // Set the initial window size.
  web_contents_impl()->Resize(gfx::Rect(10, 20));

  // Navigate to an initial page.
  GURL url = GetUrl("/empty.html?acceptch-viewport-width");
  ASSERT_TRUE(NavigateToURL(shell(), url));

  // Start prerendering. This won't have the "(sec-ch-)viewport-width" headers
  // as the width is 0 due to the lack of a cached/known viewport size.
  GURL prerender_url = GetUrl("/iframe.html?acceptch");
  PrerenderHostId host_id = AddPrerender(prerender_url);
  EXPECT_FALSE(HasRequestHeader(prerender_url, "viewport-width"));
  EXPECT_FALSE(HasRequestHeader(prerender_url, "sec-ch-viewport-width"));

  // Resize the window.
  web_contents_impl()->Resize(gfx::Rect(30, 40));

  // Activation should also not have the "(sec-ch-)viewport-width" headers.
  test::PrerenderHostObserver prerender_observer(*web_contents_impl(), host_id);
  NavigatePrimaryPage(prerender_url);
  prerender_observer.WaitForActivation();
  EXPECT_FALSE(HasRequestHeader(prerender_url, "viewport-width"));
  EXPECT_FALSE(HasRequestHeader(prerender_url, "sec-ch-viewport-width"));
}

// Test that changes on the viewport height of the initiator page between when
// to trigger prerendering and when to activate don't fail activation params
// match.
IN_PROC_BROWSER_TEST_F(PrerenderClientHintsBrowserTest, ViewPort_Height) {
  MockClientHintsControllerDelegate client_hints_controller_delegate(
      GetShellUserAgentMetadata());
  ShellContentBrowserClient::Get()
      ->browser_context()
      ->set_client_hints_controller_delegate(&client_hints_controller_delegate);

  // Set the initial window size.
  web_contents_impl()->Resize(gfx::Rect(10, 20));

  // Navigate to an initial page.
  GURL url = GetUrl("/empty.html?acceptch-viewport-height");
  ASSERT_TRUE(NavigateToURL(shell(), url));

  // Start prerendering. This won't have the "sec-ch-viewport-height" header
  // as the height is 0 due to the lack of a cached/known viewport size.
  GURL prerender_url = GetUrl("/iframe.html?acceptch");
  PrerenderHostId host_id = AddPrerender(prerender_url);
  EXPECT_FALSE(HasRequestHeader(prerender_url, "sec-ch-viewport-height"));

  // Resize the window.
  web_contents_impl()->Resize(gfx::Rect(30, 40));

  // Activation should also not have the "sec-ch-viewport-height" header.
  test::PrerenderHostObserver prerender_observer(*web_contents_impl(), host_id);
  NavigatePrimaryPage(prerender_url);
  prerender_observer.WaitForActivation();
  EXPECT_FALSE(HasRequestHeader(prerender_url, "sec-ch-viewport-height"));
}

void CheckExpectedCrossOriginMetrics(
    const base::HistogramTester& histogram_tester,
    PrerenderCrossOriginRedirectionMismatch mismatch_type,
    std::optional<PrerenderCrossOriginRedirectionProtocolChange>
        protocol_change) {
  histogram_tester.ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_"
      "EmbedderSuffixForTest",
      PrerenderFinalStatus::kCrossSiteRedirectInInitialNavigation, 1);
  histogram_tester.ExpectUniqueSample(
      "Prerender.Experimental.PrerenderCrossOriginRedirectionMismatch.Embedder_"
      "EmbedderSuffixForTest",
      mismatch_type, 1);
  if (protocol_change.has_value()) {
    histogram_tester.ExpectUniqueSample(
        "Prerender.Experimental.CrossOriginRedirectionProtocolChange.Embedder_"
        "EmbedderSuffixForTest",
        protocol_change.value(), 1);
  }
}

// Tests PrerenderCrossOriginRedirectionMismatch.kSchemeHostPortMismatch was
// recorded when a prerendering navigaton was redireted to another origin with
// different scheme, host and port.
IN_PROC_BROWSER_TEST_F(
    PrerenderBrowserTest,
    EmbedderTrigger_CrossOriginRedirection_SchemeHostPortMismatch) {
  base::HistogramTester histogram_tester;
  embedded_test_server()->AddDefaultHandlers(GetTestDataFilePath());
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL initial_url = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // The redirected_url's origin completely differs from the prerendering one.
  GURL redirected_url = embedded_test_server()->GetURL("b.test", "/empty.html");
  GURL prerendering_url = GetUrl("/server-redirect?" + redirected_url.spec());
  ASSERT_NE(prerendering_url.GetScheme(), redirected_url.GetScheme());
  ASSERT_NE(prerendering_url.GetHost(), redirected_url.GetHost());
  ASSERT_NE(prerendering_url.GetPort(), redirected_url.GetPort());

  PrerenderEmbedderTriggeredCrossOriginRedirectionPage(
      *web_contents_impl(), prerendering_url, redirected_url);
  CheckExpectedCrossOriginMetrics(
      histogram_tester,
      PrerenderCrossOriginRedirectionMismatch::kSchemeHostPortMismatch,
      /*protocol_change=*/std::nullopt);
}

// Tests a prerendering navigaton goes with HTTP protocol, and being redirected
// to upgrade its protocol to HTTPS.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       EmbedderTrigger_CrossOriginRedirection_ProtocolUpgrade) {
  base::HistogramTester histogram_tester;
  embedded_test_server()->AddDefaultHandlers(GetTestDataFilePath());
  ASSERT_TRUE(embedded_test_server()->Start());

  GURL initial_url = embedded_test_server()->GetURL("a.test", "/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Redirect to another url with protocol upgraded.
  GURL redirected_url = ssl_server().GetURL("a.test", "/empty.html");
  GURL prerendering_url = embedded_test_server()->GetURL(
      "a.test", "/server-redirect?" + redirected_url.spec());
  ASSERT_NE(prerendering_url.GetScheme(), redirected_url.GetScheme());
  ASSERT_NE(prerendering_url.GetPort(), redirected_url.GetPort());
  ASSERT_EQ(prerendering_url.GetScheme(), url::kHttpScheme);
  ASSERT_EQ(redirected_url.GetScheme(), url::kHttpsScheme);

  PrerenderEmbedderTriggeredCrossOriginRedirectionPage(
      *web_contents_impl(), prerendering_url, redirected_url);
  CheckExpectedCrossOriginMetrics(
      histogram_tester,
      PrerenderCrossOriginRedirectionMismatch::kSchemePortMismatch,
      PrerenderCrossOriginRedirectionProtocolChange::kHttpProtocolUpgrade);
}

// Similar to
// CancelEmbedderTriggeredPrerenderingCrossOriginRedirection_ProtocolUpgrade,
// tests a prerendering navigaton goes with HTTPS protocol, and being redirected
// to upgrade its protocol to HTTPS.
IN_PROC_BROWSER_TEST_F(
    PrerenderBrowserTest,
    EmbedderTrigger_CrossOriginRedirection_ProtocolDowngrade) {
  base::HistogramTester histogram_tester;
  GURL initial_url = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  GURL::Replacements downgrade_protocol;
  downgrade_protocol.SetSchemeStr(url::kHttpScheme);
  std::string port_str(base::NumberToString(ssl_server().port() + 1));
  downgrade_protocol.SetPortStr(port_str);
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // Redirect to another url with protocol upgraded.
  GURL redirected_url =
      GetUrl("/empty.html").ReplaceComponents(downgrade_protocol);
  GURL prerendering_url = GetUrl("/server-redirect?" + redirected_url.spec());
  ASSERT_NE(prerendering_url.GetScheme(), redirected_url.GetScheme());
  ASSERT_NE(prerendering_url.GetPort(), redirected_url.GetPort());
  ASSERT_EQ(prerendering_url.GetScheme(), url::kHttpsScheme);
  ASSERT_EQ(redirected_url.GetScheme(), "http");

  PrerenderEmbedderTriggeredCrossOriginRedirectionPage(
      *web_contents_impl(), prerendering_url, redirected_url);
  CheckExpectedCrossOriginMetrics(
      histogram_tester,
      PrerenderCrossOriginRedirectionMismatch::kSchemePortMismatch,
      PrerenderCrossOriginRedirectionProtocolChange::kHttpProtocolDowngrade);
}

// Tests that embedder triggered prerender can be redirected to the subdomain
// because they are same-site.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       EmbedderTrigger_CrossOriginRedirection_ToSubdomain) {
  GURL initial_url = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  GURL::Replacements set_host;
  set_host.SetHostStr("www.a.test");

  GURL redirected_url = GetUrl("/empty.html").ReplaceComponents(set_host);
  GURL prerendering_url = GetUrl("/server-redirect?" + redirected_url.spec());

  std::unique_ptr<PrerenderHandle> prerender_handle =
      PrerenderEmbedderTriggeredCrossOriginRedirectionPage(
          *web_contents_impl(), prerendering_url, redirected_url);
  test::PrerenderHostObserver prerender_observer(*web_contents_impl(),
                                                 prerendering_url);
  prerender_helper()->NavigatePrimaryPageAsync(
      prerendering_url,
      ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
                                ui::PAGE_TRANSITION_FROM_ADDRESS_BAR));
  prerender_observer.WaitForActivation();
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_"
      "EmbedderSuffixForTest",
      PrerenderFinalStatus::kActivated, 1);
}

// Tests that embedder triggered prerender can be redirected to the same site.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       EmbedderTrigger_CrossOriginRedirection_FromSubdomain) {
  GURL initial_url = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  GURL::Replacements set_host;
  set_host.SetHostStr("www.a.test");

  GURL redirected_url = GetUrl("/empty.html");
  GURL prerendering_url = GetUrl("/server-redirect?" + redirected_url.spec())
                              .ReplaceComponents(set_host);
  std::unique_ptr<PrerenderHandle> prerender_handle =
      PrerenderEmbedderTriggeredCrossOriginRedirectionPage(
          *web_contents_impl(), prerendering_url, redirected_url);
  test::PrerenderHostObserver prerender_observer(*web_contents_impl(),
                                                 prerendering_url);
  prerender_helper()->NavigatePrimaryPageAsync(
      prerendering_url,
      ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
                                ui::PAGE_TRANSITION_FROM_ADDRESS_BAR));
  prerender_observer.WaitForActivation();
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_"
      "EmbedderSuffixForTest",
      PrerenderFinalStatus::kActivated, 1);
}

// Tests PrerenderCrossOriginRedirectionMismatch.kHostMismatch is recorded
// when the prerendering navigation is redirected to a different domain.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       EmbedderTrigger_CrossOriginRedirection_DifferentDomain) {
  base::HistogramTester histogram_tester;
  GURL kInitialUrl = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  GURL kRedirectedUrl = GetCrossSiteUrl("/empty.html?prerender");
  GURL kPrerenderingUrl = GetUrl("/server-redirect?" + kRedirectedUrl.spec());
  PrerenderEmbedderTriggeredCrossOriginRedirectionPage(
      *web_contents_impl(), kPrerenderingUrl, kRedirectedUrl);
  CheckExpectedCrossOriginMetrics(
      histogram_tester, PrerenderCrossOriginRedirectionMismatch::kHostMismatch,
      /*protocol_change=*/std::nullopt);
}

// Tests that prerender works with accessibility.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       PrerenderWithAccessibilityEnabled) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/page_with_iframe.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);

  // Enable accessibility.
  ScopedAccessibilityModeOverride inner_scoped_accessibility_mode(
      shell()->web_contents(), ui::kAXModeComplete);

  // Start prerendering `kPrerenderingUrl`, which has an iframe attached.
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 0);
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  ASSERT_TRUE(host_id);
  ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 1);

  test::PrerenderHostObserver prerender_observer(*web_contents_impl(),
                                                 kPrerenderingUrl);

  NavigatePrimaryPage(kPrerenderingUrl);

  prerender_observer.WaitForActivation();
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kActivated);
}

class UpdateTargetURLDelegate : public WebContentsDelegate {
 public:
  explicit UpdateTargetURLDelegate(WebContents* web_contents) {
    web_contents->SetDelegate(this);
  }

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

  bool is_updated_target_url() { return is_updated_target_url_; }

 private:
  void UpdateTargetURL(WebContents* source, const GURL& url) override {
    is_updated_target_url_ = true;
  }

  bool is_updated_target_url_ = false;
};

// Tests that text autosizer works per page.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, FocusChangeInPrerenderedPage) {
  const GURL kInitialUrl = GetUrl("/empty.html");
  const GURL kPrerenderingUrl = GetUrl("/simple_links.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);
  RenderFrameHostImpl* prerender_frame_host =
      GetPrerenderedMainFrameHost(host_id);

  UpdateTargetURLDelegate delegate(shell()->web_contents());

  // No crash.
  EXPECT_TRUE(ExecJs(prerender_frame_host,
                     "document.getElementById('same_site_link').focus();"));

  // The prerendered page should not update the target url.
  EXPECT_FALSE(delegate.is_updated_target_url());
}

// Tests that an unused RenderWidgetHost (that is owned by a RenderViewHostImpl)
// created by a prerendering FrameTree points to the primary frame tree after
// activation. Regression test for crbug.com/1324149.
IN_PROC_BROWSER_TEST_F(
    PrerenderBrowserTest,
    UnusedRenderWidgetHostFrameTreePointerUpdatedOnActivation) {
  // Since the render view host won't be created until the response is received
  // if feature DeferSpeculativeRFHCreation is on. The test is no longer valid
  // for this case.
  if (base::FeatureList::IsEnabled(features::kDeferSpeculativeRFHCreation)) {
    return;
  }

  IsolateAllSitesForTesting(base::CommandLine::ForCurrentProcess());

  // Navigate to an initial page.
  const GURL kInitialUrl = GetUrl("/title1.html");
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
  EXPECT_TRUE(AddTestUtilJS(current_frame_host()));

  // Start a prerender.
  const GURL kPrerenderingUrl = GetUrl("/title2.html");
  PrerenderHostId host_id = AddPrerender(kPrerenderingUrl);

  // Add a cross-origin iframe to the prerendering page.
  const GURL kCrossOriginSubframeUrl = GetCrossSiteUrl("/title2.html");
  RenderFrameHostImpl* prerender_rfh = GetPrerenderedMainFrameHost(host_id);
  EXPECT_TRUE(AddTestUtilJS(prerender_rfh));
  EXPECT_TRUE(ExecJs(prerender_rfh, JsReplace("add_iframe_async($1)",
                                              kCrossOriginSubframeUrl)));
  base::RunLoop().RunUntilIdle();

  ASSERT_EQ(prerender_rfh->child_count(), 1u);
  FrameTreeNode* iframe = prerender_rfh->child_at(0);
  // The cross-origin navigation in the iframe will be throttled, but not before
  // creating a out-of-process speculative RFH (which would also result in an
  // RVH created for the subframe speculatively).
  ASSERT_TRUE(iframe->render_manager()->speculative_frame_host());
  RenderViewHostImpl* render_view_host =
      iframe->render_manager()->speculative_frame_host()->render_view_host();

  // Activate.
  NavigatePrimaryPage(kPrerenderingUrl);
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);
  // Wait for iframe to finish navigating.
  ASSERT_EQ("LOADED",
            EvalJs(prerender_rfh, JsReplace("wait_iframe_async($1)",
                                            kCrossOriginSubframeUrl)));
  // This asserts that the current RenderViewHost was created before activation
  // (to make sure we're testing the right thing).
  EXPECT_EQ(render_view_host, iframe->current_frame_host()->render_view_host());

  // The unused RenderWidgetHost should point to the primary FrameTree now.
  RenderWidgetHostImpl* render_widget_host = render_view_host->GetWidget();
  EXPECT_NE(render_widget_host,
            iframe->current_frame_host()->GetRenderWidgetHost());
  EXPECT_EQ(render_widget_host->frame_tree(),
            current_frame_host()->frame_tree());

  // Navigate the primary main frame to the same origin as |iframe|; this
  // should reuse |render_view_host|, and as a result |render_widget_host| will
  // be used. If the |render_widget_host| points to the wrong frame_tree, this
  // will result in a segfault (reproducing crbug.com/1324149) when we try to
  // focus the new page's view.
  const GURL kCrossOriginUrl = GetCrossSiteUrl("/title1.html");
  DisableProactiveBrowsingInstanceSwapFor(current_frame_host());
  NavigatePrimaryPage(kCrossOriginUrl);
  ASSERT_EQ(current_frame_host()->render_view_host(), render_view_host);
  ASSERT_EQ(current_frame_host()->GetRenderWidgetHost(), render_widget_host);
}

// Tests that window.close() can cancel speculation rules.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, WindowClosedSpeculationRules) {
  ASSERT_TRUE(embedded_test_server()->Start());

  const GURL kInitialUrl = embedded_test_server()->GetURL("/empty.html");
  const GURL kPrerenderingUrl = embedded_test_server()->GetURL("/title1.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start a prerender.
  AddPrerender(kPrerenderingUrl);

  PrerenderHostId host_id = GetHostForUrl(kPrerenderingUrl);
  WaitForPrerenderLoadCompletion(host_id);

  test::PrerenderHostObserver host_observer(*web_contents(), host_id);
  RenderFrameHostImpl* prerender_rfh = GetPrerenderedMainFrameHost(host_id);
  ASSERT_TRUE(ExecJs(prerender_rfh, "window.close()"));
  host_observer.WaitForDestroyed();
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kWindowClosed);

  // The initiator page should not be closed by window.closed().
  EXPECT_TRUE(ExecJs(web_contents(), ""));
}

// Tests that window.close() can cancel speculation rules whose target_hint is
// "_blank" (i.e., prerender into new tab).
IN_PROC_BROWSER_TEST_F(PrerenderTargetHintBrowserTest,
                       WindowClosedSpeculationRules_WithTargetHintBlank) {
  ASSERT_TRUE(embedded_test_server()->Start());

  const GURL kInitialUrl = embedded_test_server()->GetURL("/empty.html");
  const GURL kPrerenderingUrl = embedded_test_server()->GetURL("/title1.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));

  // Start a prerender.
  PrerenderHostId host_id = prerender_helper()->AddPrerender(
      kPrerenderingUrl, /*eagerness=*/std::nullopt, "_blank");
  auto* prerender_web_contents =
      test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
  ASSERT_NE(prerender_web_contents, web_contents_impl());
  ExpectWebContentsIsForNewTabPrerendering(*prerender_web_contents);

  test::PrerenderHostObserver host_observer(*prerender_web_contents, host_id);
  RenderFrameHost* prerender_rfh =
      test::PrerenderTestHelper::GetPrerenderedMainFrameHost(
          *prerender_web_contents, host_id);
  ASSERT_TRUE(ExecJs(prerender_rfh, "window.close()"));
  host_observer.WaitForDestroyed();
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kWindowClosed);

  // The initiator page should not be closed by window.closed().
  EXPECT_TRUE(ExecJs(web_contents(), ""));
}

// Tests that Prerender is suppressed by slow network.
IN_PROC_BROWSER_TEST_P(PrerenderBrowserTestFallbackEnabledDisabled,
                       SlowNetwork) {
  // Emulate slow network.
  MockClientHintsControllerDelegate client_hints_controller_delegate(
      GetShellUserAgentMetadata());
  ShellContentBrowserClient::Get()
      ->browser_context()
      ->set_client_hints_controller_delegate(&client_hints_controller_delegate);
  network::NetworkQualityTracker& network_quality_tracker =
      *client_hints_controller_delegate.GetNetworkQualityTracker();
  base::TimeDelta http_rtt =
      base::Milliseconds(1) +
      ::features::kSuppressesPrerenderingOnSlowNetworkThreshold.Get();
  network_quality_tracker.ReportRTTsAndThroughputForTesting(
      http_rtt, network_quality_tracker.GetDownstreamThroughputKbps());

  ASSERT_TRUE(embedded_test_server()->Start());

  GURL initial_url = GetUrl("/empty.html");
  GURL prerendering_url = GetUrl("/empty.html?prerender");

  // Attempt to prerender.
  test::PrerenderHostRegistryObserver observer(*web_contents_impl());
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  AddPrerenderAsync(prerendering_url);
  observer.WaitForTrigger(prerendering_url);

  // It should fail.
  EXPECT_FALSE(HasHostForUrl(prerendering_url));
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kSlowNetwork);

  // Navigate primary page to flush the metrics.
  NavigatePrimaryPage(prerendering_url);

  if (IsPrerender2FallbackPrefetchSpecRulesEnabled()) {
    // Prerender is cancelled, but prefetch ahead of prerender is still alive
    // and the navigation uses it.
    ExpectPreloadingAttemptUkm(
        {attempt_ukm_entry_builder().BuildEntry(
             PrimaryPageSourceId(), PreloadingType::kPrerender,
             PreloadingEligibility::kSlowNetwork,
             PreloadingHoldbackStatus::kUnspecified,
             PreloadingTriggeringOutcome::kUnspecified,
             PreloadingFailureReason::kUnspecified,
             /*accurate=*/true,
             /*ready_time=*/std::nullopt,
             blink::mojom::SpeculationEagerness::kImmediate),
         attempt_ukm_entry_builder().BuildEntry(
             PrimaryPageSourceId(), PreloadingType::kPrefetch,
             PreloadingEligibility::kEligible,
             PreloadingHoldbackStatus::kAllowed,
             PreloadingTriggeringOutcome::kSuccess,
             PreloadingFailureReason::kUnspecified,
             /*accurate=*/true,
             /*ready_time=*/kMockElapsedTime,
             blink::mojom::SpeculationEagerness::kImmediate)});
  } else {
    ExpectPreloadingAttemptUkm({attempt_ukm_entry_builder().BuildEntry(
        PrimaryPageSourceId(), PreloadingType::kPrerender,
        PreloadingEligibility::kSlowNetwork,
        PreloadingHoldbackStatus::kUnspecified,
        PreloadingTriggeringOutcome::kUnspecified,
        PreloadingFailureReason::kUnspecified,
        /*accurate=*/true,
        /*ready_time=*/std::nullopt,
        blink::mojom::SpeculationEagerness::kImmediate)});
  }
}

class V8OptimizerContentBrowserClient
    : public ContentBrowserTestContentBrowserClient {
 public:
  explicit V8OptimizerContentBrowserClient(bool enable) : enable_(enable) {}
  ~V8OptimizerContentBrowserClient() override = default;

  bool AreV8OptimizationsEnabledForSite(
      BrowserContext* browser_context,
      const std::optional<base::SafeRef<content::ProcessSelectionUserData>>&
          process_selection_user_data,
      const GURL& site_url) override {
    return enable_;
  }

 public:
  const bool enable_ = true;
};

// Previously, prerendering a page that had the COOP crashed when the V8
// optimizer was disabled by the site settings. This is the regression test for
// the issue. See https://crbug.com/40076091 for details.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCOOPWithoutV8Optimizer) {
  // Disable the V8 optimizer.
  V8OptimizerContentBrowserClient test_browser_client(/*enable=*/false);

  // Attempt to prerender the page that has the COOP.
  const GURL initial_url = GetUrl("/empty.html");
  const GURL prerendering_url =
      GetUrl("/set-header?Cross-Origin-Opener-Policy: same-origin");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), initial_url);

  PrerenderHostId host_id = AddPrerender(prerendering_url);
  test::PrerenderHostObserver prerender_observer(*web_contents(), host_id);
  NavigatePrimaryPage(prerendering_url);
  prerender_observer.WaitForActivation();
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kActivated);
}

// See the comment on PrerenderCOOPWithoutV8Optimizer test for details. This
// test ensures that prerendering is enabled regardless of whether the target
// page has the COOP, when the V8 optimizer is disabled.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       PrerenderNonCOOPWithoutV8Optimizer) {
  // Disable the V8 optimizer.
  V8OptimizerContentBrowserClient test_browser_client(/*enable=*/false);

  const GURL initial_url = GetUrl("/empty.html");
  const GURL prerendering_url = GetUrl("/empty.html?prerender");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), initial_url);

  PrerenderHostId host_id = AddPrerender(prerendering_url);
  test::PrerenderHostObserver prerender_observer(*web_contents(), host_id);
  NavigatePrimaryPage(prerendering_url);
  prerender_observer.WaitForActivation();
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kActivated);
}

// See the comment on PrerenderCOOPWithoutV8Optimizer test for details. This
// test ensures that prerendering a page that has the COOP succeeds when the V8
// optimizer is enabled.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCOOPWithV8Optimizer) {
  // Enable the V8 optimizer.
  V8OptimizerContentBrowserClient test_browser_client(/*enable=*/true);

  const GURL initial_url = GetUrl("/empty.html");
  const GURL prerendering_url =
      GetUrl("/set-header?Cross-Origin-Opener-Policy: same-origin");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  ASSERT_EQ(web_contents()->GetLastCommittedURL(), initial_url);

  // Start prerendering a page that has the COOP.
  PrerenderHostId host_id = AddPrerender(prerendering_url);
  ASSERT_TRUE(host_id);

  // Activate the prerendered page.
  NavigatePrimaryPage(prerendering_url);
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kActivated);
}

// Many of these tests navigate away from a page and then test whether the back
// navigation entry can be prerendered. This is parameterized on whether the
// navigation away from the original page is browser or renderer initiated.
class PrerenderSessionHistoryBrowserTest
    : public PrerenderBrowserTest,
      public testing::WithParamInterface<bool> {
 public:
  static std::string DescribeParams(
      const testing::TestParamInfo<ParamType>& info) {
    return info.param ? "FromBrowser" : "FromRenderer";
  }

  // Navigate `web_contents` to `url`. The test parameterization determines
  // whether to do a browser initiated navigation or a renderer initiated
  // navigation.
  void NavigateAway(WebContentsImpl* web_contents, const GURL& url) {
    const bool from_browser = GetParam();
    if (from_browser) {
      ASSERT_TRUE(NavigateToURL(web_contents, url));
    } else {
      ASSERT_TRUE(NavigateToURLFromRenderer(web_contents, url));
    }
  }

  // Tests in this fixture generally begin by setting up a back navigation
  // entry, with `url1` being the back navigation entry and `url2` being the
  // last committed entry.
  void PerformInitialNavigations(WebContentsImpl* web_contents,
                                 const GURL& url1,
                                 const GURL& url2) {
    ASSERT_TRUE(NavigateToURL(web_contents, url1));
    NavigateAway(web_contents, url2);
  }

  void PredictBackNavigation(WebContentsImpl* web_contents) {
    PrerenderHostRegistry* registry = web_contents->GetPrerenderHostRegistry();
    // For testing convenience, pretend that the mouse back button is the
    // predictor.
    const auto predictor = content_preloading_predictor::kMouseBackButton;

    registry->BackNavigationLikely(predictor);

    WaitForHttpCacheQueryCompletion(web_contents);
  }

  void PerformBackNavigation(WebContentsImpl* web_contents) {
    NavigationControllerImpl& controller = web_contents->GetController();
    ASSERT_TRUE(controller.CanGoBack());
    TestNavigationObserver back_observer(web_contents);
    controller.GoBack();
    back_observer.Wait();
  }

  void WaitForHttpCacheQueryCompletion(WebContentsImpl* web_contents) {
    PrerenderHostRegistry* registry = web_contents->GetPrerenderHostRegistry();
    EXPECT_TRUE(base::test::RunUntil(
        [&]() { return !registry->HasOngoingHttpCacheQueryForTesting(); }));
  }

  void ClearBackForwardCache(WebContentsImpl* web_contents) {
    web_contents->GetController().GetBackForwardCache().Flush();
  }

  void ClearAllCaches(WebContentsImpl* web_contents) {
    BrowsingDataRemover* cache_remover =
        web_contents->GetBrowserContext()->GetBrowsingDataRemover();
    BrowsingDataRemoverCompletionObserver cache_clear_completion_observer(
        cache_remover);
    cache_remover->RemoveAndReply(
        base::Time::Min(), base::Time::Max(),
        BrowsingDataRemover::DATA_TYPE_CACHE,
        BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
        &cache_clear_completion_observer);
    cache_clear_completion_observer.BlockUntilCompletion();
  }

  void ExpectAttemptUkm(ukm::TestUkmRecorder& ukm_recorder,
                        bool accurate,
                        PreloadingEligibility eligibility,
                        ukm::SourceId source_id) {
    std::vector<ukm::TestUkmRecorder::HumanReadableUkmEntry> attempts =
        ukm_recorder.GetEntries(ukm::builders::Preloading_Attempt::kEntryName,
                                test::kPreloadingAttemptUkmMetrics);
    ASSERT_EQ(attempts.size(), 1u);

    const auto predictor = content_preloading_predictor::kMouseBackButton;
    const PreloadingHoldbackStatus holdback_status =
        eligibility == PreloadingEligibility::kEligible
            ? PreloadingHoldbackStatus::kAllowed
            : PreloadingHoldbackStatus::kUnspecified;
    const PreloadingTriggeringOutcome triggering_outcome =
        eligibility == PreloadingEligibility::kEligible
            ? PreloadingTriggeringOutcome::kNoOp
            : PreloadingTriggeringOutcome::kUnspecified;

    test::PreloadingAttemptUkmEntryBuilder entry_builder(predictor);
    ukm::TestUkmRecorder::HumanReadableUkmEntry expected_entry =
        entry_builder.BuildEntry(
            source_id, PreloadingType::kPrerender, eligibility, holdback_status,
            triggering_outcome, PreloadingFailureReason::kUnspecified,
            accurate);

    EXPECT_EQ(attempts[0], expected_entry)
        << test::ActualVsExpectedUkmEntryToString(attempts[0], expected_entry);
  }
};

INSTANTIATE_TEST_SUITE_P(All,
                         PrerenderSessionHistoryBrowserTest,
                         testing::Bool(),
                         PrerenderSessionHistoryBrowserTest::DescribeParams);

// Other tests in `PrerenderSessionHistoryBrowserTest` explicitly trigger the
// prediction and the navigation. For this test, we actually simulate the back
// button press events.
IN_PROC_BROWSER_TEST_P(PrerenderSessionHistoryBrowserTest,
                       BackButtonNavigation) {
  const GURL url1 = GetUrl("/title1.html");
  const GURL url2 = GetCrossSiteUrl("/title2.html");
  PerformInitialNavigations(web_contents_impl(), url1, url2);

  ClearBackForwardCache(web_contents_impl());

  base::HistogramTester histogram_tester;

  NavigationControllerImpl& controller = web_contents_impl()->GetController();
  ASSERT_TRUE(controller.CanGoBack());
  TestNavigationObserver back_observer(web_contents_impl());
  InputEventAckWaiter mouse_down_waiter(
      web_contents_impl()->GetPrimaryMainFrame()->GetRenderWidgetHost(),
      blink::WebInputEvent::Type::kMouseDown);
  const gfx::Point click_location(50, 50);
  SimulateMouseEvent(web_contents_impl(),
                     blink::WebInputEvent::Type::kMouseDown,
                     blink::WebMouseEvent::Button::kBack, click_location);
  // The mouse up triggers the navigation. We wait until after the cache query
  // to send the mouse up to ensure the navigation happens after the browser
  // decides whether to prerender.
  mouse_down_waiter.Wait();
  WaitForHttpCacheQueryCompletion(web_contents_impl());
  SimulateMouseEvent(web_contents_impl(), blink::WebInputEvent::Type::kMouseUp,
                     blink::WebMouseEvent::Button::kBack, click_location);
  back_observer.Wait();

  histogram_tester.ExpectUniqueSample(
      "Preloading.PrerenderBackNavigationEligibility.MouseBackButton",
      PrerenderBackNavigationEligibility::kEligible, 1);
}

IN_PROC_BROWSER_TEST_P(PrerenderSessionHistoryBrowserTest,
                       PredictionForEligibleBackNavigation) {
  const GURL url1 = GetUrl("/title1.html");
  const GURL url2 = GetCrossSiteUrl("/title2.html");
  PerformInitialNavigations(web_contents_impl(), url1, url2);

  ClearBackForwardCache(web_contents_impl());

  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;

  PredictBackNavigation(web_contents_impl());
  PerformBackNavigation(web_contents_impl());

  ukm::SourceId source_id =
      web_contents_impl()->GetPrimaryMainFrame()->GetPageUkmSourceId();

  histogram_tester.ExpectUniqueSample(
      "Preloading.PrerenderBackNavigationEligibility.MouseBackButton",
      PrerenderBackNavigationEligibility::kEligible, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Predictor.MouseBackButton.Precision",
      PredictorConfusionMatrix::kTruePositive, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Predictor.MouseBackButton.Recall",
      PredictorConfusionMatrix::kTruePositive, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Prerender.Attempt.MouseBackButton.Precision",
      PredictorConfusionMatrix::kTruePositive, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Prerender.Attempt.MouseBackButton.Recall",
      PredictorConfusionMatrix::kTruePositive, 1);
  ExpectAttemptUkm(ukm_recorder, true, PreloadingEligibility::kEligible,
                   source_id);
}

IN_PROC_BROWSER_TEST_P(PrerenderSessionHistoryBrowserTest,
                       NoPredictionDueToBfcache) {
  if (!BackForwardCache::IsBackForwardCacheFeatureEnabled()) {
    GTEST_SKIP()
        << "This test assumes the back navigation is restoring from bfcache.";
  }

  const GURL url1 = GetUrl("/title1.html");
  const GURL url2 = GetCrossSiteUrl("/title2.html");
  PerformInitialNavigations(web_contents_impl(), url1, url2);

  base::HistogramTester histogram_tester;

  PredictBackNavigation(web_contents_impl());
  PerformBackNavigation(web_contents_impl());

  histogram_tester.ExpectUniqueSample(
      "Preloading.PrerenderBackNavigationEligibility.MouseBackButton",
      PrerenderBackNavigationEligibility::kBfcacheEntryExists, 1);
  histogram_tester.ExpectTotalCount(
      "Preloading.Predictor.MouseBackButton.Precision", 0);
  histogram_tester.ExpectTotalCount(
      "Preloading.Predictor.MouseBackButton.Recall", 0);
  histogram_tester.ExpectTotalCount(
      "Preloading.Prerender.Attempt.MouseBackButton.Precision", 0);
  histogram_tester.ExpectTotalCount(
      "Preloading.Prerender.Attempt.MouseBackButton.Recall", 0);
}

IN_PROC_BROWSER_TEST_P(PrerenderSessionHistoryBrowserTest,
                       RendererNavigationAfterBackPrediction) {
  const GURL url1 = GetUrl("/title1.html");
  const GURL url2 = GetCrossSiteUrl("/title2.html");
  const GURL url3 = GetCrossSiteUrl("/title3.html");
  PerformInitialNavigations(web_contents_impl(), url1, url2);

  ClearBackForwardCache(web_contents_impl());

  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;

  PredictBackNavigation(web_contents_impl());
  TestNavigationObserver nav_observer(web_contents_impl());
  ASSERT_TRUE(ExecJs(web_contents_impl(), JsReplace("location = $1;", url3)));
  nav_observer.Wait();

  ukm::SourceId source_id =
      web_contents_impl()->GetPrimaryMainFrame()->GetPageUkmSourceId();

  histogram_tester.ExpectUniqueSample(
      "Preloading.PrerenderBackNavigationEligibility.MouseBackButton",
      PrerenderBackNavigationEligibility::kEligible, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Predictor.MouseBackButton.Precision",
      PredictorConfusionMatrix::kFalsePositive, 1);
  // A renderer navigation is not a false negative for this predictor.
  histogram_tester.ExpectTotalCount(
      "Preloading.Predictor.MouseBackButton.Recall", 0);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Prerender.Attempt.MouseBackButton.Precision",
      PredictorConfusionMatrix::kFalsePositive, 1);
  histogram_tester.ExpectTotalCount(
      "Preloading.Prerender.Attempt.MouseBackButton.Recall", 0);
  ExpectAttemptUkm(ukm_recorder, false, PreloadingEligibility::kEligible,
                   source_id);
}

IN_PROC_BROWSER_TEST_P(PrerenderSessionHistoryBrowserTest,
                       NotEligibleForSameDocument) {
  const GURL url1 = GetUrl("/title1.html");
  const GURL url2 = GetUrl("/title1.html#same");
  PerformInitialNavigations(web_contents_impl(), url1, url2);

  base::HistogramTester histogram_tester;

  PredictBackNavigation(web_contents_impl());
  PerformBackNavigation(web_contents_impl());

  histogram_tester.ExpectUniqueSample(
      "Preloading.PrerenderBackNavigationEligibility.MouseBackButton",
      PrerenderBackNavigationEligibility::kTargetIsSameDocument, 1);
  histogram_tester.ExpectTotalCount(
      "Preloading.Predictor.MouseBackButton.Precision", 0);
  histogram_tester.ExpectTotalCount(
      "Preloading.Predictor.MouseBackButton.Recall", 0);
  histogram_tester.ExpectTotalCount(
      "Preloading.Prerender.Attempt.MouseBackButton.Precision", 0);
  histogram_tester.ExpectTotalCount(
      "Preloading.Prerender.Attempt.MouseBackButton.Recall", 0);
}

IN_PROC_BROWSER_TEST_P(PrerenderSessionHistoryBrowserTest,
                       NotEligibleForSameSite) {
  const GURL url1 = GetUrl("/title1.html");
  const GURL url2 = GetSameSiteCrossOriginUrl("/title2.html");
  PerformInitialNavigations(web_contents_impl(), url1, url2);

  ClearBackForwardCache(web_contents_impl());

  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;

  PredictBackNavigation(web_contents_impl());
  PerformBackNavigation(web_contents_impl());

  ukm::SourceId source_id =
      web_contents_impl()->GetPrimaryMainFrame()->GetPageUkmSourceId();

  histogram_tester.ExpectUniqueSample(
      "Preloading.PrerenderBackNavigationEligibility.MouseBackButton",
      PrerenderBackNavigationEligibility::kTargetIsSameSite, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Predictor.MouseBackButton.Precision",
      PredictorConfusionMatrix::kTruePositive, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Predictor.MouseBackButton.Recall",
      PredictorConfusionMatrix::kTruePositive, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Prerender.Attempt.MouseBackButton.Precision",
      PredictorConfusionMatrix::kTruePositive, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Prerender.Attempt.MouseBackButton.Recall",
      PredictorConfusionMatrix::kTruePositive, 1);
  ExpectAttemptUkm(ukm_recorder, true,
                   ToPreloadingEligibility(
                       PrerenderBackNavigationEligibility::kTargetIsSameSite),
                   source_id);
}

IN_PROC_BROWSER_TEST_P(PrerenderSessionHistoryBrowserTest,
                       NotEligibleForUncached) {
  const GURL url1 = GetUrl("/title1.html");
  const GURL url2 = GetCrossSiteUrl("/title2.html");
  PerformInitialNavigations(web_contents_impl(), url1, url2);

  // Ensure `url1` is not served from the HTTP cache or bfcache.
  ClearAllCaches(web_contents_impl());

  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;

  PredictBackNavigation(web_contents_impl());
  PerformBackNavigation(web_contents_impl());

  ukm::SourceId source_id =
      web_contents_impl()->GetPrimaryMainFrame()->GetPageUkmSourceId();

  histogram_tester.ExpectUniqueSample(
      "Preloading.PrerenderBackNavigationEligibility.MouseBackButton",
      PrerenderBackNavigationEligibility::kNoHttpCacheEntry, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Predictor.MouseBackButton.Precision",
      PredictorConfusionMatrix::kTruePositive, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Predictor.MouseBackButton.Recall",
      PredictorConfusionMatrix::kTruePositive, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Prerender.Attempt.MouseBackButton.Precision",
      PredictorConfusionMatrix::kTruePositive, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Prerender.Attempt.MouseBackButton.Recall",
      PredictorConfusionMatrix::kTruePositive, 1);
  ExpectAttemptUkm(ukm_recorder, true,
                   ToPreloadingEligibility(
                       PrerenderBackNavigationEligibility::kNoHttpCacheEntry),
                   source_id);
}

IN_PROC_BROWSER_TEST_P(PrerenderSessionHistoryBrowserTest,
                       NotEligibleForPostMethod) {
  const GURL url1 = GetUrl("/form_that_posts_to_echoall.html");
  const GURL url2 = GetUrl("/echoall");
  const GURL url3 = GetCrossSiteUrl("/title1.html");
  ASSERT_TRUE(NavigateToURL(shell(), url1));

  TestNavigationObserver form_post_observer(web_contents_impl());
  ASSERT_TRUE(
      ExecJs(web_contents_impl(), "document.getElementById('form').submit();"));
  form_post_observer.Wait();
  ASSERT_EQ(url2, web_contents_impl()->GetLastCommittedURL());
  ASSERT_TRUE(web_contents_impl()
                  ->GetController()
                  .GetLastCommittedEntry()
                  ->GetHasPostData());

  NavigateAway(web_contents_impl(), url3);

  ClearBackForwardCache(web_contents_impl());

  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;

  PredictBackNavigation(web_contents_impl());
  PerformBackNavigation(web_contents_impl());

  ukm::SourceId source_id =
      web_contents_impl()->GetPrimaryMainFrame()->GetPageUkmSourceId();

  histogram_tester.ExpectUniqueSample(
      "Preloading.PrerenderBackNavigationEligibility.MouseBackButton",
      PrerenderBackNavigationEligibility::kMethodNotGet, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Predictor.MouseBackButton.Precision",
      PredictorConfusionMatrix::kTruePositive, 1);
  // A POST navigation is not a false negative for this predictor.
  histogram_tester.ExpectTotalCount(
      "Preloading.Predictor.MouseBackButton.Recall", 0);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Prerender.Attempt.MouseBackButton.Precision",
      PredictorConfusionMatrix::kTruePositive, 1);
  histogram_tester.ExpectTotalCount(
      "Preloading.Prerender.Attempt.MouseBackButton.Recall", 0);
  ExpectAttemptUkm(ukm_recorder, true,
                   ToPreloadingEligibility(
                       PrerenderBackNavigationEligibility::kMethodNotGet),
                   source_id);
}

IN_PROC_BROWSER_TEST_P(PrerenderSessionHistoryBrowserTest,
                       NotEligibleForFailedNavigation) {
  const GURL url1 = GetUrl("/page404.html");
  const GURL url2 = GetCrossSiteUrl("/title1.html");
  PerformInitialNavigations(web_contents_impl(), url1, url2);

  ClearBackForwardCache(web_contents_impl());

  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;

  PredictBackNavigation(web_contents_impl());
  PerformBackNavigation(web_contents_impl());

  ukm::SourceId source_id =
      web_contents_impl()->GetPrimaryMainFrame()->GetPageUkmSourceId();

  histogram_tester.ExpectUniqueSample(
      "Preloading.PrerenderBackNavigationEligibility.MouseBackButton",
      PrerenderBackNavigationEligibility::kTargetIsFailedNavigation, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Predictor.MouseBackButton.Precision",
      PredictorConfusionMatrix::kTruePositive, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Predictor.MouseBackButton.Recall",
      PredictorConfusionMatrix::kTruePositive, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Prerender.Attempt.MouseBackButton.Precision",
      PredictorConfusionMatrix::kTruePositive, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Prerender.Attempt.MouseBackButton.Recall",
      PredictorConfusionMatrix::kTruePositive, 1);
  ExpectAttemptUkm(
      ukm_recorder, true,
      ToPreloadingEligibility(
          PrerenderBackNavigationEligibility::kTargetIsFailedNavigation),
      source_id);
}

IN_PROC_BROWSER_TEST_P(PrerenderSessionHistoryBrowserTest,
                       NotEligibleForNonHttpScheme) {
  const GURL url1 = GURL("data:text/html,test");
  const GURL url2 = GetUrl("/title1.html");
  PerformInitialNavigations(web_contents_impl(), url1, url2);

  ClearBackForwardCache(web_contents_impl());

  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;

  PredictBackNavigation(web_contents_impl());
  PerformBackNavigation(web_contents_impl());

  ukm::SourceId source_id =
      web_contents_impl()->GetPrimaryMainFrame()->GetPageUkmSourceId();

  histogram_tester.ExpectUniqueSample(
      "Preloading.PrerenderBackNavigationEligibility.MouseBackButton",
      PrerenderBackNavigationEligibility::kTargetIsNonHttp, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Predictor.MouseBackButton.Precision",
      PredictorConfusionMatrix::kTruePositive, 1);
  // A navigation to a data URL is not a false negative for this predictor.
  histogram_tester.ExpectTotalCount(
      "Preloading.Predictor.MouseBackButton.Recall", 0);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Prerender.Attempt.MouseBackButton.Precision",
      PredictorConfusionMatrix::kTruePositive, 1);
  histogram_tester.ExpectTotalCount(
      "Preloading.Prerender.Attempt.MouseBackButton.Recall", 0);
  ExpectAttemptUkm(ukm_recorder, true,
                   ToPreloadingEligibility(
                       PrerenderBackNavigationEligibility::kTargetIsNonHttp),
                   source_id);
}

// Returns whether the two given windows can script each other.
// Assumes `opener` has a variable named `newWindow` which refers to `openee`.
bool IsScriptable(WebContentsImpl* opener, WebContentsImpl* openee) {
  // Have `opener` set a property such that `openee` can read it.
  const std::string kPropName = "mrPostman";
  const std::string kPropValue = "a property for me";

  if (EvalJs(opener, JsReplace(R"((() => {
                                 let result = '';
                                 try {
                                   newWindow[$1] = $2;
                                   result = newWindow[$1] || '';
                                 } catch {}
                                 return result;
                               })();)",
                               kPropName, kPropValue))
          .ExtractString() != kPropValue) {
    return false;
  }

  return EvalJs(openee, JsReplace("window[$1] || '';", kPropName))
             .ExtractString() == kPropValue;
}

IN_PROC_BROWSER_TEST_P(PrerenderSessionHistoryBrowserTest,
                       NotEligibleForRelatedActiveContents) {
  const GURL url1 = GetUrl("/title1.html");
  const GURL url2 = GetCrossSiteUrl("/title2.html");

  ASSERT_TRUE(NavigateToURL(shell(), url1));
  RenderFrameHostImplWrapper opener_rfh(current_frame_host());
  EXPECT_EQ(1u, opener_rfh->GetSiteInstance()->GetRelatedActiveContentsCount());

  ShellAddedObserver shell_observer;
  EXPECT_TRUE(
      ExecJs(shell(), JsReplace("window.newWindow = window.open($1);", url1)));
  Shell* popup = shell_observer.GetShell();
  WebContentsImpl* popup_contents =
      static_cast<WebContentsImpl*>(popup->web_contents());
  EXPECT_TRUE(WaitForLoadStop(popup_contents));
  EXPECT_TRUE(IsScriptable(web_contents_impl(), popup_contents));
  EXPECT_EQ(2u, opener_rfh->GetSiteInstance()->GetRelatedActiveContentsCount());

  NavigateAway(popup_contents, url2);
  ClearBackForwardCache(popup_contents);
  EXPECT_FALSE(IsScriptable(web_contents_impl(), popup_contents));
  RenderFrameHostImplWrapper cross_site_popup_rfh(
      popup_contents->GetPrimaryMainFrame());
  // Whether the SiteInstance changes depends on the process model. The default
  // SiteInstance could be in use.
  if (cross_site_popup_rfh->GetSiteInstance() ==
      opener_rfh->GetSiteInstance()) {
    EXPECT_EQ(2u,
              opener_rfh->GetSiteInstance()->GetRelatedActiveContentsCount());
  } else if (cross_site_popup_rfh->GetSiteInstance()->IsRelatedSiteInstance(
                 opener_rfh->GetSiteInstance())) {
    EXPECT_EQ(2u,
              opener_rfh->GetSiteInstance()->GetRelatedActiveContentsCount());
  } else {
    // `NavigateAway` may have swapped BrowsingInstances depending on test
    // parameterization.
    EXPECT_EQ(1u,
              opener_rfh->GetSiteInstance()->GetRelatedActiveContentsCount());
  }

  // `opener_rfh` is active and is using the same BrowsingInstance as the
  // popup's back navigation entry, so it would not be safe to prerender for
  // that entry.
  SiteInstanceImpl* target_site_instance =
      popup_contents->GetController().GetEntryAtOffset(-1)->site_instance();
  EXPECT_TRUE(opener_rfh->GetSiteInstance()->IsRelatedSiteInstance(
      target_site_instance));

  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;

  PredictBackNavigation(popup_contents);
  PerformBackNavigation(popup_contents);

  EXPECT_TRUE(IsScriptable(web_contents_impl(), popup_contents));
  EXPECT_EQ(2u, opener_rfh->GetSiteInstance()->GetRelatedActiveContentsCount());

  ukm::SourceId source_id =
      popup_contents->GetPrimaryMainFrame()->GetPageUkmSourceId();

  histogram_tester.ExpectUniqueSample(
      "Preloading.PrerenderBackNavigationEligibility.MouseBackButton",
      PrerenderBackNavigationEligibility::kRelatedActiveContents, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Predictor.MouseBackButton.Precision",
      PredictorConfusionMatrix::kTruePositive, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Predictor.MouseBackButton.Recall",
      PredictorConfusionMatrix::kTruePositive, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Prerender.Attempt.MouseBackButton.Precision",
      PredictorConfusionMatrix::kTruePositive, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Prerender.Attempt.MouseBackButton.Recall",
      PredictorConfusionMatrix::kTruePositive, 1);
  ExpectAttemptUkm(
      ukm_recorder, true,
      ToPreloadingEligibility(
          PrerenderBackNavigationEligibility::kRelatedActiveContents),
      source_id);
}

IN_PROC_BROWSER_TEST_P(PrerenderSessionHistoryBrowserTest,
                       PredictAfterOpeneeDestroyed) {
  const GURL url1 = GetUrl("/title1.html");
  const GURL url2 = GetCrossSiteUrl("/title2.html");
  ASSERT_TRUE(NavigateToURL(shell(), url1));
  RenderFrameHostImplWrapper opener_rfh(current_frame_host());

  ShellAddedObserver shell_observer;
  EXPECT_TRUE(
      ExecJs(shell(), JsReplace("window.newWindow = window.open($1);", url1)));
  Shell* popup = shell_observer.GetShell();
  WebContentsImpl* popup_contents =
      static_cast<WebContentsImpl*>(popup->web_contents());
  EXPECT_TRUE(WaitForLoadStop(popup_contents));
  EXPECT_EQ(2u, opener_rfh->GetSiteInstance()->GetRelatedActiveContentsCount());

  NavigateAway(web_contents_impl(), url2);
  ClearBackForwardCache(web_contents_impl());

  WebContentsDestroyedWatcher close_popup_waiter(popup_contents);
  popup_contents->ClosePage();
  close_popup_waiter.Wait();

  // Unlike `NotEligibleForRelatedActiveContents`, there's no longer another
  // WebContents which is sharing the BrowsingInstance of the back navigation
  // entry, so it would be safe to prerender.

  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;

  PredictBackNavigation(web_contents_impl());
  PerformBackNavigation(web_contents_impl());

  ukm::SourceId source_id =
      web_contents_impl()->GetPrimaryMainFrame()->GetPageUkmSourceId();

  histogram_tester.ExpectUniqueSample(
      "Preloading.PrerenderBackNavigationEligibility.MouseBackButton",
      PrerenderBackNavigationEligibility::kEligible, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Predictor.MouseBackButton.Precision",
      PredictorConfusionMatrix::kTruePositive, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Predictor.MouseBackButton.Recall",
      PredictorConfusionMatrix::kTruePositive, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Prerender.Attempt.MouseBackButton.Precision",
      PredictorConfusionMatrix::kTruePositive, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Prerender.Attempt.MouseBackButton.Recall",
      PredictorConfusionMatrix::kTruePositive, 1);
  ExpectAttemptUkm(ukm_recorder, true, PreloadingEligibility::kEligible,
                   source_id);
}

IN_PROC_BROWSER_TEST_P(PrerenderSessionHistoryBrowserTest,
                       BackNavigationOfCloneWebContents) {
  const GURL url1 = GetUrl("/title1.html");
  const GURL url2 = GetCrossSiteUrl("/title2.html");
  PerformInitialNavigations(web_contents_impl(), url1, url2);

  // Whether the navigation from `url1` to `url2` swapped BrowsingInstances
  // depends on test parameterization and additional configuration options that
  // are not particularly relevant for the intended scope of this test. So we'll
  // just handle both possibilities as part of this test.
  SiteInstanceImpl* prev_site_instance = web_contents_impl()
                                             ->GetController()
                                             .GetEntryAtOffset(-1)
                                             ->site_instance();
  const bool original_navs_swapped_browsing_instance =
      !web_contents_impl()->GetSiteInstance()->IsRelatedSiteInstance(
          prev_site_instance);

  FakeWebContentsDelegate clone_delegate;
  std::unique_ptr<WebContents> new_web_contents_owned =
      web_contents_impl()->Clone();
  WebContentsImpl* new_web_contents =
      static_cast<WebContentsImpl*>(new_web_contents_owned.get());
  new_web_contents->SetDelegate(&clone_delegate);
  TestNavigationObserver clone_load_observer(new_web_contents);
  new_web_contents->GetController().LoadIfNecessary();
  clone_load_observer.Wait();

  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;

  PredictBackNavigation(new_web_contents);
  PerformBackNavigation(new_web_contents);

  const PrerenderBackNavigationEligibility expected_eligibility =
      original_navs_swapped_browsing_instance
          ? PrerenderBackNavigationEligibility::kEligible
          : PrerenderBackNavigationEligibility::kRelatedActiveContents;
  ukm::SourceId source_id =
      new_web_contents->GetPrimaryMainFrame()->GetPageUkmSourceId();

  histogram_tester.ExpectUniqueSample(
      "Preloading.PrerenderBackNavigationEligibility.MouseBackButton",
      expected_eligibility, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Predictor.MouseBackButton.Precision",
      PredictorConfusionMatrix::kTruePositive, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Predictor.MouseBackButton.Recall",
      PredictorConfusionMatrix::kTruePositive, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Prerender.Attempt.MouseBackButton.Precision",
      PredictorConfusionMatrix::kTruePositive, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Prerender.Attempt.MouseBackButton.Recall",
      PredictorConfusionMatrix::kTruePositive, 1);
  ExpectAttemptUkm(ukm_recorder, true,
                   ToPreloadingEligibility(expected_eligibility), source_id);
}

IN_PROC_BROWSER_TEST_P(
    PrerenderSessionHistoryBrowserTest,
    BackNavigationOfClonedWebContentsWithOriginalAtTargetEntry) {
  const GURL url1 = GetUrl("/title1.html");
  const GURL url2 = GetCrossSiteUrl("/title2.html");
  PerformInitialNavigations(web_contents_impl(), url1, url2);

  FakeWebContentsDelegate clone_delegate;
  std::unique_ptr<WebContents> new_web_contents_owned =
      web_contents_impl()->Clone();
  WebContentsImpl* new_web_contents =
      static_cast<WebContentsImpl*>(new_web_contents_owned.get());
  new_web_contents->SetDelegate(&clone_delegate);
  TestNavigationObserver clone_load_observer(new_web_contents);
  new_web_contents->GetController().LoadIfNecessary();
  clone_load_observer.Wait();

  PerformBackNavigation(web_contents_impl());

  base::HistogramTester histogram_tester;
  ukm::TestAutoSetUkmRecorder ukm_recorder;

  PredictBackNavigation(new_web_contents);
  PerformBackNavigation(new_web_contents);

  ukm::SourceId source_id =
      new_web_contents->GetPrimaryMainFrame()->GetPageUkmSourceId();

  histogram_tester.ExpectUniqueSample(
      "Preloading.PrerenderBackNavigationEligibility.MouseBackButton",
      PrerenderBackNavigationEligibility::kRelatedActiveContents, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Predictor.MouseBackButton.Precision",
      PredictorConfusionMatrix::kTruePositive, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Predictor.MouseBackButton.Recall",
      PredictorConfusionMatrix::kTruePositive, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Prerender.Attempt.MouseBackButton.Precision",
      PredictorConfusionMatrix::kTruePositive, 1);
  histogram_tester.ExpectUniqueSample(
      "Preloading.Prerender.Attempt.MouseBackButton.Recall",
      PredictorConfusionMatrix::kTruePositive, 1);
  ExpectAttemptUkm(
      ukm_recorder, true,
      ToPreloadingEligibility(
          PrerenderBackNavigationEligibility::kRelatedActiveContents),
      source_id);
}

// PrerenderHosts created through speculation rules are not suitable for use in
// session history navigations. In particular, the SiteInstances would be
// mismatched.
IN_PROC_BROWSER_TEST_P(
    PrerenderSessionHistoryBrowserTest,
    BackButtonNavigationDoesNotUseSpeculationRulePrerenders) {
  const GURL url1 = GetUrl("/title1.html");
  const GURL url2 = GetUrl("/title2.html");
  PerformInitialNavigations(web_contents_impl(), url1, url2);
  ClearBackForwardCache(web_contents_impl());

  PrerenderHostId host_id = AddPrerender(url1);
  test::PrerenderHostObserver prerender_observer(*web_contents(), host_id);

  PerformBackNavigation(web_contents_impl());

  EXPECT_FALSE(prerender_observer.was_activated());
}

// Tests that the prerendering page does not crash when performing compositor
// warming up.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, WarmingUpCCDoesntInvokeCrashes) {
  const GURL initial_url = GetUrl("/empty.html");
  const GURL prerendering_url = GetUrl("/empty.html?prerender");

  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  auto prerender_handle = AddEmbedderTriggeredPrerender(
      prerendering_url, /*preloading_attempt=*/nullptr,
      /*should_warm_up_compositor=*/true);
  PrerenderHostId prerender_host_id =
      static_cast<PrerenderHandleImpl*>(prerender_handle.get())
          ->prerender_host_id_for_testing();
  test::PrerenderHostObserver prerender_observer(*web_contents(),
                                                 prerender_host_id);

  NavigatePrimaryPageFromAddressBar(prerendering_url);
  prerender_observer.WaitForActivation();
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), prerendering_url);
  EXPECT_TRUE(prerender_observer.was_activated());
}

// Tests the PrerenderHostId of the navigations in main frame and subframes.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       PrerenderHostIdAssignedToNavigationRequest) {
  ASSERT_TRUE(embedded_test_server()->Start());

  const GURL initial_url = GetUrl("/empty.html");
  const GURL prerendering_url = GetUrl("/page_with_iframe.html");
  const GURL subframe_url = GetUrl("/title1.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));

  // The test navigation manager will throttle the loading of the
  // mainframe and subframe in the prerendered page. This allows
  // us to check the PrerenderHostId assigned to the navigation
  // requests.
  TestNavigationManager main_navigation_manager(web_contents(),
                                                prerendering_url);
  TestNavigationManager subframe_navigation_manager(web_contents(),
                                                    subframe_url);
  AddPrerenderAsync(prerendering_url);
  EXPECT_TRUE(main_navigation_manager.WaitForResponse());
  auto* main_request =
      NavigationRequest::From(main_navigation_manager.GetNavigationHandle());
  PrerenderHostId prerender_host_id = main_request->GetPrerenderHostId();
  EXPECT_TRUE(prerender_host_id);
  main_navigation_manager.ResumeNavigation();

  EXPECT_TRUE(
      subframe_navigation_manager.WaitForFirstYieldAfterDidStartNavigation());
  auto* subframe_request = NavigationRequest::From(
      subframe_navigation_manager.GetNavigationHandle());
  EXPECT_EQ(subframe_request->GetPrerenderHostId(), prerender_host_id);
  EXPECT_TRUE(main_navigation_manager.WaitForNavigationFinished());

  // Activate the prerendered page.
  test::PrerenderHostObserver prerender_observer(*web_contents_impl(),
                                                 prerendering_url);
  prerender_helper()->NavigatePrimaryPageAsync(prerendering_url);
  EXPECT_TRUE(subframe_navigation_manager.WaitForNavigationFinished());
  prerender_observer.WaitForActivation();
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       ProcessIsOnlyHostingPrerenderedFramesOrEmpty) {
  ASSERT_TRUE(embedded_test_server()->Start());

  // 1. Navigate to an initial page.
  const GURL initial_url =
      embedded_test_server()->GetURL("b.test", "/page_with_iframe.html");
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  RenderFrameHost* original_subframe_host =
      ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0);
  RenderProcessHost* original_subframe_process =
      original_subframe_host->GetProcess();
  ASSERT_TRUE(original_subframe_process);

  // 2. Prerender the first page.
  const GURL prerender_url1 =
      embedded_test_server()->GetURL("a.test", "/title1.html");
  // The cross-site prerender page must be triggered by the browser.
  auto prerender_handle1 = AddEmbedderTriggeredPrerenderAsync(prerender_url1);
  prerender_helper()->WaitForPrerenderLoadCompletion(prerender_url1);
  PrerenderHostId host_id1 = prerender_helper()->GetHostForUrl(prerender_url1);
  ASSERT_NE(host_id1, PrerenderHostId());
  RenderProcessHostImpl* process1 =
      static_cast<RenderProcessHostImpl*>(GetProcessForPrerenderHost(host_id1));
  ASSERT_TRUE(process1);
  EXPECT_TRUE(process1->IsOnlyHostingPrerenderedFramesOrEmpty());

  // 3. Create a subframe navigation. It is same site as the prerender page
  // but different site with the current page.
  WebContents* active_web_contents = web_contents();
  const GURL navigation_url =
      embedded_test_server()->GetURL("a.test", "/title2.html");
  EXPECT_TRUE(
      NavigateIframeToURL(active_web_contents, "test_iframe", navigation_url));
  RenderFrameHost* subframe_host =
      ChildFrameAt(active_web_contents->GetPrimaryMainFrame(), 0);
  ASSERT_TRUE(subframe_host);

  RenderProcessHostImpl* process2 =
      static_cast<RenderProcessHostImpl*>(subframe_host->GetProcess());
  if (AreAllSitesIsolatedForTesting()) {
    // If the site isolation is enabled, the subframe process reuse feature
    // will locate the frame in the same process
    EXPECT_EQ(process1, process2);
    EXPECT_FALSE(process1->IsOnlyHostingPrerenderedFramesOrEmpty());
  } else {
    // If the site isolation is not enabled, the navigation in the subframe will
    // reuse the same RFH and RPH as b.test rather than allocating a new RFH.
    EXPECT_EQ(original_subframe_process, process2);
    EXPECT_TRUE(process1->IsOnlyHostingPrerenderedFramesOrEmpty());
  }

  // 4. Remove the subframe. Since the frame in the active page is removed,
  // the original process shall be considered only hosting prerendered frames
  // again.
  RenderFrameDeletedObserver delete_observer(subframe_host);
  const std::string remove_iframe_script = R"(
      const subframe = document.getElementById('test_iframe');
      subframe.remove();
  )";
  EXPECT_TRUE(ExecJs(shell(), remove_iframe_script));
  delete_observer.WaitUntilDeleted();
  EXPECT_TRUE(process1->IsOnlyHostingPrerenderedFramesOrEmpty());
}

class PrerenderProcessReuseBrowserTest : public PrerenderBrowserTest {
 public:
  PrerenderProcessReuseBrowserTest() {
    feature_list_.InitWithFeaturesAndParameters(
        {{features::kReusePrerenderingProcessForMainFrames, {}},
         // The isloated origins feature are added so that the navigation
         // to a.test and b.test require a dedicated process on Android with
         // partial site isolation.
         {features::kIsolateOrigins,
          {{features::kIsolateOriginsFieldTrialParamName,
            "https://a.test/,https://b.test/"}}}},
        {features::kProcessPerSiteUpToMainFrameThreshold});
  }

  void SetUpOnMainThread() override {
    if (!AreAllSitesIsolatedForTesting()) {
      browser_client_ =
          std::make_unique<ForceSiteIsolationContentBrowserClient>();
    }
    PrerenderBrowserTest::SetUpOnMainThread();
  }

  void TearDownOnMainThread() override {
    PrerenderBrowserTest::TearDownOnMainThread();
    browser_client_.reset();
  }

  // Forces the site isolation for the origins in the test to emulate
  // isolated sites under partial site isolation.
  class ForceSiteIsolationContentBrowserClient
      : public ContentBrowserTestContentBrowserClient {
   public:
    bool DoesSiteRequireDedicatedProcess(
        BrowserContext* browser_context,
        const GURL& effective_site_url) override {
      return effective_site_url == GURL("http://a.test") ||
             effective_site_url == GURL("http://b.test");
    }
  };

 private:
  std::unique_ptr<ForceSiteIsolationContentBrowserClient> browser_client_;
  base::test::ScopedFeatureList feature_list_;
};

IN_PROC_BROWSER_TEST_F(PrerenderProcessReuseBrowserTest,
                       ReusePrerenderProcessInNavigation) {
  base::HistogramTester histogram_tester;
  ASSERT_TRUE(embedded_test_server()->Start());

  // 1. Navigate to an initial page.
  const GURL initial_url =
      embedded_test_server()->GetURL("b.test", "/page_with_iframe.html");
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  RenderProcessHost* initial_process = current_frame_host()->GetProcess();

  // 2. Prerender a cross-site page.
  const GURL prerender_url =
      embedded_test_server()->GetURL("a.test", "/title1.html");
  // The cross-site prerender page must be triggered by the browser.
  std::unique_ptr<PrerenderHandle> prerender_handle1 =
      AddEmbedderTriggeredPrerenderAsync(prerender_url);
  prerender_helper()->WaitForPrerenderLoadCompletion(prerender_url);
  PrerenderHostId prerender_host_id =
      prerender_helper()->GetHostForUrl(prerender_url);
  ASSERT_TRUE(prerender_host_id);
  RenderProcessHostImpl* prerender_process =
      static_cast<RenderProcessHostImpl*>(
          GetProcessForPrerenderHost(prerender_host_id));
  ASSERT_TRUE(prerender_process);
  ASSERT_TRUE(prerender_process->IsOnlyHostingPrerenderedFramesOrEmpty());

  // 3. Navigate to a page same site as the prerender page.
  const GURL navigation_url =
      embedded_test_server()->GetURL("a.test", "/title2.html");
  EXPECT_TRUE(NavigateToURL(shell(), navigation_url));
  RenderProcessHost* navigation_process = current_frame_host()->GetProcess();
  EXPECT_NE(navigation_process, initial_process);
  EXPECT_EQ(navigation_process, prerender_process);
  // Verify that the reuse policy UMA is correctly recoreded.
  histogram_tester.ExpectUniqueSample(
      "BrowserRenderProcessHost.ReuseExistingProcess.ReusePolicy",
      ProcessReusePolicy::kReusePrerenderingProcessForMainFrame, 1);

  // 4. Create a second tab and navigation to the same site.
  const GURL new_window_url =
      embedded_test_server()->GetURL("a.test", "/red.html");
  Shell* new_window_shell =
      Shell::CreateNewWindow(shell()->web_contents()->GetBrowserContext(),
                             initial_url, nullptr, gfx::Size());
  EXPECT_TRUE(NavigateToURL(new_window_shell, navigation_url));
  FrameTreeNode* new_window_root =
      static_cast<WebContentsImpl*>(new_window_shell->web_contents())
          ->GetPrimaryFrameTree()
          .root();
  RenderFrameHostImpl* new_window_rfh = new_window_root->current_frame_host();
  RenderProcessHost* new_window_process = new_window_rfh->GetProcess();
  // Since the prerender process is hosting both a prerendered page and the page
  // for the original tab, we will create a new process for the new tab
  // navigation.
  ASSERT_TRUE(new_window_process);
  EXPECT_NE(new_window_process, prerender_process);
}

class PrerenderProcessReuseWithoutStrictSiteIsolationBrowserTest
    : public PrerenderProcessReuseBrowserTest,
      public ::testing::WithParamInterface<bool> {
 public:
  PrerenderProcessReuseWithoutStrictSiteIsolationBrowserTest() {
    if (PreferWarmProcess()) {
      feature_list_.InitAndEnableFeature(features::kPreferWarmRendererProcess);
    } else {
      feature_list_.InitAndDisableFeature(features::kPreferWarmRendererProcess);
    }
  }

  bool PreferWarmProcess() const { return GetParam(); }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    PrerenderProcessReuseBrowserTest::SetUpCommandLine(command_line);
    command_line->RemoveSwitch(switches::kSitePerProcess);
  }

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

INSTANTIATE_TEST_SUITE_P(
    All,
    PrerenderProcessReuseWithoutStrictSiteIsolationBrowserTest,
    ::testing::Bool(),
    [](const testing::TestParamInfo<bool>& info) {
      return info.param ? "PreferWarmProcess" : "DefaultReuse";
    });

IN_PROC_BROWSER_TEST_P(
    PrerenderProcessReuseWithoutStrictSiteIsolationBrowserTest,
    PreferWarmProcessOverUnlockedProcess) {
  base::HistogramTester histogram_tester;
  ASSERT_TRUE(embedded_test_server()->Start());

  // 1. Navigate to an initial empty page.
  const GURL initial_url("about:blank");
  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  RenderProcessHost* initial_process = current_frame_host()->GetProcess();

  // 2. Prerender a cross-site page on a.test (which is isolated, hence locked
  // process).
  const GURL prerender_url =
      embedded_test_server()->GetURL("a.test", "/title1.html");
  // The cross-site prerender page must be triggered by the browser.
  std::unique_ptr<PrerenderHandle> prerender_handle1 =
      AddEmbedderTriggeredPrerenderAsync(prerender_url);
  prerender_helper()->WaitForPrerenderLoadCompletion(prerender_url);
  PrerenderHostId prerender_host_id =
      prerender_helper()->GetHostForUrl(prerender_url);
  ASSERT_TRUE(prerender_host_id);
  RenderProcessHostImpl* prerender_process =
      static_cast<RenderProcessHostImpl*>(
          GetProcessForPrerenderHost(prerender_host_id));
  ASSERT_TRUE(prerender_process);
  ASSERT_TRUE(prerender_process->IsOnlyHostingPrerenderedFramesOrEmpty());

  // 3. Navigate to a page same site as the prerender page.
  const GURL navigation_url =
      embedded_test_server()->GetURL("a.test", "/title2.html");
  EXPECT_TRUE(NavigateToURL(shell(), navigation_url));
  RenderProcessHost* navigation_process = current_frame_host()->GetProcess();

  if (PreferWarmProcess()) {
    EXPECT_NE(navigation_process, initial_process);
    EXPECT_EQ(navigation_process, prerender_process);
    histogram_tester.ExpectUniqueSample(
        "BrowserRenderProcessHost.ReuseExistingProcess.ReusePolicy",
        ProcessReusePolicy::kReusePrerenderingProcessForMainFrame, 1);
  } else {
    // Under partial site isolation, since b.test's process is unlocked,
    // navigating to a.test normally would just reuse the unlocked process.
    EXPECT_EQ(navigation_process, initial_process);
    EXPECT_NE(navigation_process, prerender_process);
  }
}

class PrerenderUntilScriptBaseBrowserTest
    : public PrerenderTargetHintBrowserTest {
 public:
  void StartPrerenderUntilScript(const GURL& prerender_url) {
    test::PrerenderHostRegistryObserver observer(*web_contents_impl());
    prerender_helper()->AddPrerenderUntilScriptAsync(prerender_url);
    observer.WaitForTrigger(prerender_url);
    PrerenderHostId host_id = test::PrerenderTestHelper::GetHostForUrl(
        *web_contents(), prerender_url);
    ASSERT_TRUE(host_id);
    PrerenderHost* prerender_host = web_contents_impl()
                                        ->GetPrerenderHostRegistry()
                                        ->FindNonReservedHostById(host_id);
    ASSERT_TRUE(prerender_host);
    EXPECT_TRUE(prerender_host->should_pause_javascript_execution());
  }

 protected:
  // Allows derived tests to reuse duplicate code for testing basic
  // functionalities.
  void RunBasicFunctionalityCheck() {
    // Start prerender-until-script.
    GURL prerender_url = GetUrl("/prerender/inline_script.html");
    StartPrerenderUntilScript(prerender_url);

    // Verify after stylesheet is loaded, the parser continues.
    GURL before_script_element_url = GetUrl("/image.jpg");
    prerender_helper()->WaitForRequest(before_script_element_url, 1);
    // Though the parser is paused due to delayed script execution, preloader
    // should fetch external subresources.
    GURL image_url = GetUrl("/blank.jpg");
    prerender_helper()->WaitForRequest(image_url, 1);

    // Activate.
    NavigatePrimaryPage(prerender_url);

    // A script in the prerendered page sends the beacon request. Since its
    // execution should be deferred until activation, we can verify the script
    // execution is resumed automatically by checking the server's log.
    GURL beacon_url = GetUrl("/activation-beacon");
    prerender_helper()->WaitForRequest(beacon_url, 1);

    // Make sure the deferred script runs after activation.
    ASSERT_EQ(false, EvalJs(web_contents_impl(), "document.prerendering"));
    EXPECT_EQ(false,
              EvalJs(web_contents_impl(), "executed_during_prerendering"));
  }
};

class PrerenderUntilScriptBrowserTest
    : public PrerenderUntilScriptBaseBrowserTest {
 public:
  PrerenderUntilScriptBrowserTest() {
    feature_list_.InitAndEnableFeature(blink::features::kPrerenderUntilScript);
  }

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

// Tests that inline scripts will be deferred until activation.
// TODO(https://crbug.com/428500219): Migrate this test to WPT. For now the
// prerender WPTs require script execution, which is suspended by
// prerender-until-script, and we need to update the test infra first.
IN_PROC_BROWSER_TEST_F(PrerenderUntilScriptBrowserTest, InlineScript) {
  // Navigate to an initial page.
  GURL url = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(web_contents(), url));

  RunBasicFunctionalityCheck();
}

// Tests that external sync scripts will be deferred until activation.
// TODO(https://crbug.com/428500219): Migrate this test to WPT. For now the
// prerender WPTs require script execution, which is suspended by
// prerender-until-script, and we need to update the test infra first.
IN_PROC_BROWSER_TEST_F(PrerenderUntilScriptBrowserTest, ExternalSyncScript) {
  // Navigate to an initial page.
  GURL url = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(web_contents(), url));

  // Start prerender-until-script.
  GURL prerender_url = GetUrl("/prerender/external_sync_script.html");
  StartPrerenderUntilScript(prerender_url);

  // Though the parser is paused due to delayed script execution, preloader
  // should fetch external subresources.
  GURL image_url = GetUrl("/blank.jpg");
  prerender_helper()->WaitForRequest(image_url, 1);
  // Activate.
  NavigatePrimaryPage(prerender_url);

  // A script in the prerendered page sends the beacon request. Since its
  // execution should be deferred until activation, we can verify the script
  // execution is resumed automatically by checking the server's log.
  GURL beacon_url = GetUrl("/activation-beacon");
  prerender_helper()->WaitForRequest(beacon_url, 1);

  // Ensure the state has been propagated to renderer processes.
  ASSERT_EQ(false, EvalJs(web_contents_impl(), "document.prerendering"));
  EXPECT_EQ(false, EvalJs(web_contents_impl(), "executed_during_prerendering"));
}

// Tests that prerender_until_script pages can defer async scripts.
// TODO(https://crbug.com/428500219): Migrate this test to WPT. For now the
// prerender WPTs require script execution, which is suspended by
// prerender-until-script, and we need to update the test infra first.
IN_PROC_BROWSER_TEST_F(PrerenderUntilScriptBrowserTest, AsyncScript) {
  // Navigate to an initial page.
  GURL url = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(web_contents(), url));

  // Start prerender-until-script.
  GURL prerender_url = GetUrl("/prerender/async_script.html");
  StartPrerenderUntilScript(prerender_url);

  // Prerender-until-script does not pause downloading async scripts.
  GURL script_url = GetUrl("/prerender/status_script.js");
  prerender_helper()->WaitForRequest(script_url, 1);

  // Parsing and subresource loading are not affected while async scripts are
  // paused.
  GURL image_url = GetUrl("/blank.jpg");
  prerender_helper()->WaitForRequest(image_url, 1);

  // Activate.
  NavigatePrimaryPage(prerender_url);

  // A script in the prerendered page sends the beacon request. Since its
  // execution should be deferred until activation, we can verify the script
  // execution is resumed automatically by checking the server's log.
  GURL beacon_url = GetUrl("/activation-beacon");
  prerender_helper()->WaitForRequest(beacon_url, 1);

  // Make sure the deferred script runs after activation.
  ASSERT_EQ(false, EvalJs(web_contents_impl(), "document.prerendering"));
  EXPECT_EQ(false, EvalJs(web_contents_impl(), "executed_during_prerendering"));
}

// Tests that scripts with defer attribute are delayed until activation.
// TODO(https://crbug.com/428500219): Migrate this test to WPT. For now the
// prerender WPTs require script execution, which is suspended by
// prerender-until-script, and we need to update the test infra first.
IN_PROC_BROWSER_TEST_F(PrerenderUntilScriptBrowserTest, DeferredScript) {
  // Navigate to an initial page.
  GURL url = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(web_contents(), url));

  // Start prerender-until-script.
  GURL prerender_url = GetUrl("/prerender/deferred_script.html");
  StartPrerenderUntilScript(prerender_url);

  GURL image_url = GetUrl("/blank.jpg");
  prerender_helper()->WaitForRequest(image_url, 1);
  NavigatePrimaryPage(prerender_url);

  // A script in the prerendered page sends the beacon request. Since its
  // execution should be deferred until activation, we can verify the script
  // execution is resumed automatically by checking the server's log.
  GURL beacon_url = GetUrl("/activation-beacon");
  prerender_helper()->WaitForRequest(beacon_url, 1);
  ASSERT_EQ(false, EvalJs(web_contents_impl(), "document.prerendering"));
  EXPECT_EQ(false, EvalJs(web_contents_impl(), "executed_during_prerendering"));
}

// Tests that standby prerender-until-script candidates work.
// TODO(crbug.com/40269669): Add the implementation of pointer interaction
// on Android to the function below.
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_NonImmediateEagerness DISABLED_NonImmediateEagerness
#else
#define MAYBE_NonImmediateEagerness NonImmediateEagerness
#endif
IN_PROC_BROWSER_TEST_F(PrerenderUntilScriptBrowserTest,
                       MAYBE_NonImmediateEagerness) {
  // Navigate to an initial page.
  GURL url = GetUrl("/empty.html");
  ASSERT_TRUE(NavigateToURL(web_contents(), url));

  // Prepare for moderate trigger.
  GURL prerender_url = GetUrl("/prerender/deferred_script.html");
  InsertAnchor(prerender_url);
  RenderFrameHostImpl* rfh = current_frame_host();
  ASSERT_TRUE(rfh);
  PreloadingDeciderObserverForPrerenderTesting preloading_decider_observer(
      *rfh);
  auto* preloading_decider =
      PreloadingDecider::GetOrCreateForCurrentDocument(rfh);

  // Inject prerender-until-script.
  prerender_helper()->AddPrerenderUntilScriptAsync(
      prerender_url, blink::mojom::SpeculationEagerness::kModerate);
  preloading_decider_observer.WaitUpdateSpeculationCandidates();
  EXPECT_FALSE(HasHostForUrl(prerender_url));
  EXPECT_TRUE(preloading_decider->IsOnStandByForTesting(
      prerender_url, blink::mojom::SpeculationAction::kPrerenderUntilScript));

  // Trigger prerender-until-script.
  test::PrerenderHostRegistryObserver observer(*web_contents_impl());
  PointerHoverToAnchor(prerender_url);
  preloading_decider_observer.WaitOnPointerHover();
  observer.WaitForTrigger(prerender_url);
  EXPECT_TRUE(HasHostForUrl(prerender_url));
  EXPECT_FALSE(preloading_decider->IsOnStandByForTesting(
      prerender_url, blink::mojom::SpeculationAction::kPrerenderUntilScript));

  GURL image_url = GetUrl("/blank.jpg");
  prerender_helper()->WaitForRequest(image_url, 1);
  NavigatePrimaryPage(prerender_url);

  // A script in the prerendered page sends the beacon request. Since its
  // execution should be deferred until activation, we can verify the script
  // execution is resumed automatically by checking the server's log.
  GURL beacon_url = GetUrl("/activation-beacon");
  prerender_helper()->WaitForRequest(beacon_url, 1);
  ASSERT_EQ(false, EvalJs(web_contents_impl(), "document.prerendering"));
  EXPECT_EQ(false, EvalJs(web_contents_impl(), "executed_during_prerendering"));
}

IN_PROC_BROWSER_TEST_F(PrerenderUntilScriptBrowserTest, TargetBlank) {
  const GURL url = GetUrl("/simple_links.html");
  const GURL prerender_url = GetUrl("/prerender/deferred_script.html");

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), url));

  // Inject some links to the page.
  std::string add_link_script = base::ReplaceStringPlaceholders(
      R"(
        const link = document.getElementById('same_site_new_window_link');
        link.href = "$1";
      )",
      {prerender_url.spec()}, nullptr);
  ASSERT_TRUE(ExecJs(web_contents(), add_link_script));

  const std::string add_speculation_rules_target_hint_blank_script =
      SpeculationRulesWithIdAndTargetHint(prerender_url, "blank_specrules",
                                          "_blank", "prerender_until_script");

  // Adding speculation rules with target_hint=_blank.
  WebContents* prerender_web_contents = nullptr;
  base::RunLoop run_loop;
  auto creation_subscription = RegisterWebContentsCreationCallback(
      base::BindLambdaForTesting([&](content::WebContents* web_contents) {
        prerender_web_contents = web_contents;
        run_loop.QuitClosure().Run();
      }));
  EXPECT_TRUE(
      ExecJs(web_contents(), add_speculation_rules_target_hint_blank_script));
  // Wait for the new tab prerender.
  run_loop.Run();

  ASSERT_NE(prerender_web_contents, web_contents_impl());
  ExpectWebContentsIsForNewTabPrerendering(*prerender_web_contents);
  GURL image_url = GetUrl("/blank.jpg");
  prerender_helper()->WaitForRequest(image_url, 1);

  // Click the link annotated with "target=_blank". This should activate the
  // prerendered page.
  test::PrerenderHostObserver prerender_observer(*prerender_web_contents,
                                                 prerender_url);
  EXPECT_TRUE(ExecJs(web_contents(), "clickSameSiteNewWindowLink();"));

  // The signal that indicates the activated page starts to execute scripts.
  GURL beacon_url = GetUrl("/activation-beacon");
  prerender_helper()->WaitForRequest(beacon_url, 1);
  EXPECT_EQ(prerender_web_contents->GetLastCommittedURL(), prerender_url);
  EXPECT_TRUE(prerender_observer.was_activated());
  EXPECT_FALSE(HasHostForUrl(prerender_url));
  ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kActivated);
  EXPECT_EQ(prerender_helper()->GetRequestCount(prerender_url), 1);

  // The navigation occurred in a new WebContents, so the original WebContents
  // should still be showing the initial trigger page.
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), url);

  EXPECT_EQ(false, EvalJs(prerender_web_contents, "document.prerendering"));
  EXPECT_EQ(false,
            EvalJs(prerender_web_contents, "executed_during_prerendering"));
}

class PrerenderUntilScriptOriginTrialBrowserTest
    : public PrerenderUntilScriptBaseBrowserTest {
 public:
  PrerenderUntilScriptOriginTrialBrowserTest() {
    // Specifies the prefixed port number encoded in the origin trial token
    // below.
    set_port(45324);
  }

 protected:
  static std::string GetOriginTrialToken() {
    // Generated by tools/origin_trials/generate_token.py https://a.test:45324/
    // PrerenderUntilScript --expire-timestamp=2000000000
    static const std::string token =
        "A73nhliKkuPv6mhHxW3dx37TH9rtTamsxp+UZG+YbCSvxxUTFRHUd5bkRdnxrahQ0WL/"
        "Wu1neptJrBPf1Mu64QEAAABbeyJvcmlnaW4iOiAiaHR0cHM6Ly9hLnRlc3Q6NDUzMjQiLC"
        "AiZmVhdHVyZSI6ICJQcmVyZW5kZXJVbnRpbFNjcmlwdCIsICJleHBpcnkiOiAyMDAwMDAw"
        "MDAwfQ==";
    return token;
  }
};

// Ensures that origin trial token can enable this feature within the execution
// context.
IN_PROC_BROWSER_TEST_F(PrerenderUntilScriptOriginTrialBrowserTest, Basic) {
  const GURL url = GetUrl("/empty.html");
  URLLoaderInterceptor interceptor(base::BindLambdaForTesting(
      [&](URLLoaderInterceptor::RequestParams* params) {
        if (params->url_request.url != url) {
          return false;
        }
        URLLoaderInterceptor::WriteResponse(
            "HTTP/1.1 200 OK\n"
            "Content-type: text/html\n"
            "Origin-Trial: " +
                GetOriginTrialToken() + "\n\n",
            "", params->client.get());
        return true;
      }));

  // Navigate to an initial page.
  ASSERT_TRUE(NavigateToURL(shell(), url));
  RunBasicFunctionalityCheck();
}

class PrerenderFormSubmissionOriginTrialBrowserTest
    : public PrerenderBrowserTest,
      public testing::WithParamInterface<bool> {
 public:
  PrerenderFormSubmissionOriginTrialBrowserTest() {
    if (IsPrerenderUntilScriptEnabled()) {
      feature_list_.InitAndEnableFeature(
          blink::features::kPrerenderUntilScript);
    }
  }

  bool IsPrerenderUntilScriptEnabled() const {
    if (auto* test_info =
            testing::UnitTest::GetInstance()->current_test_info()) {
      if (test_info->value_param() != nullptr &&
          std::string_view(test_info->value_param()).length() > 0) {
        return GetParam();
      }
    }
    return false;
  }

  // `first_attempt_form_field` and `second_attempt_form_field` specify the
  // corresponding prerendering attempts are form navigations or not. The latter
  // can be `std::nullopt`, being `std::nullopt` won't start a prerender
  // attempt. The parameter `navigate_as_form_submission` specifies the type of
  // the actual navigation being form navigation or not, and `should_activate`
  // specifies whether the prerender activation is expected to be successful or
  // not.
  void RunFormSubmissionHintTest(bool first_attempt_form_field,
                                 std::optional<bool> second_attempt_form_field,
                                 std::string target_hint,
                                 bool navigate_as_form_submission,
                                 bool should_activate) {
    // The URL that was used to register the Origin Trial token.
    static constexpr char kOriginUrl[] = "https://127.0.0.1:45356";

    const GURL initiator_url(base::StrCat(
        {kOriginUrl, "/form_submission_origin_trial_initiator.html"}));
    // The suffix `?` is for form submission navigations, which has `?` mark
    // regardless of having any parameter or not.
    const GURL prerender_url(base::StrCat({kOriginUrl, "/empty.html?"}));

    // The EmbeddedTestServer must run on a specific port because the origin
    // trial token hard-coded in form_submission_origin_trial_initiator.html is
    // bound to a specific origin. While EmbeddedTestServer allows us to specify
    // a port, doing so introduces test flakiness due to TCP port reuse
    // restrictions. To avoid this, we use URLLoaderInterceptor to serve the
    // file, making the actual port irrelevant.
    URLLoaderInterceptor prerender_loader(base::BindLambdaForTesting(
        [&](URLLoaderInterceptor::RequestParams* params) {
          if (params->url_request.url != initiator_url &&
              params->url_request.url != prerender_url) {
            return false;
          }

          const std::string headers =
              "HTTP/1.1 200 OK\n"
              "Content-type: text/html\n";
          URLLoaderInterceptor::WriteResponse(
              base::StrCat({"content/test/data/prerender",
                            params->url_request.url.path()}),
              params->client.get(), &headers, std::optional<net::SSLInfo>(),
              params->url_request.url);

          return true;
        }));

    // Navigate to an initial page which has a link to `prerender_url`.
    ASSERT_TRUE(NavigateToURL(shell(), initiator_url));

    PrerenderHostId host_id;
    if (IsPrerenderUntilScriptEnabled()) {
      base::RunLoop run_loop;
      base::CallbackListSubscription creation_subscription;
      WebContents* observed_web_contents = nullptr;

      if (target_hint == "_blank") {
        creation_subscription = RegisterWebContentsCreationCallback(
            base::BindLambdaForTesting([&](content::WebContents* web_contents) {
              observed_web_contents = web_contents;
              run_loop.QuitClosure().Run();
            }));
      } else {
        observed_web_contents = web_contents_impl();
      }

      prerender_helper()->AddPrerenderUntilScriptAsync(
          prerender_url, /*eagerness=*/std::nullopt,
          /*no_vary_search_hint=*/std::nullopt,
          /*target_hint=*/target_hint,
          /*ruleset_tag=*/std::nullopt,
          /*world_id=*/ISOLATED_WORLD_ID_GLOBAL, first_attempt_form_field);

      if (target_hint == "_blank") {
        run_loop.Run();
      } else {
        // The wait is handled by
        // test::PrerenderTestHelper::WaitForPrerenderLoadCompletion.
      }

      test::PrerenderTestHelper::WaitForPrerenderLoadCompletion(
          *observed_web_contents, prerender_url);
      host_id = test::PrerenderTestHelper::GetHostForUrl(*observed_web_contents,
                                                         prerender_url);
      EXPECT_TRUE(host_id);
    } else {
      // Start prerendering `prerender_url` with `form_submission` =
      // `first_attempt_form_field`.
      host_id = prerender_helper()->AddPrerender(
          prerender_url, /*eagerness=*/std::nullopt,
          /*no_vary_search_hint=*/std::nullopt,
          /*target_hint=*/target_hint,
          /*ruleset_tag=*/std::nullopt,
          /*world_id=*/ISOLATED_WORLD_ID_GLOBAL, first_attempt_form_field);
    }

    if (second_attempt_form_field.has_value()) {
      // Start prerendering `prerender_url` with `form_submission` =
      // `second_attempt_form_field`.
      if (IsPrerenderUntilScriptEnabled()) {
        prerender_helper()->AddPrerenderUntilScriptAsync(
            prerender_url,
            /*eagerness=*/std::nullopt,
            /*no_vary_search_hint=*/std::nullopt,
            /*target_hint=*/target_hint,
            /*ruleset_tag=*/std::nullopt,
            /*world_id=*/ISOLATED_WORLD_ID_GLOBAL,
            second_attempt_form_field.value());
      } else {
        prerender_helper()->AddPrerender(prerender_url,
                                         /*eagerness=*/std::nullopt,
                                         /*no_vary_search_hint=*/std::nullopt,
                                         /*target_hint=*/target_hint,
                                         /*ruleset_tag=*/std::nullopt,
                                         /*world_id=*/ISOLATED_WORLD_ID_GLOBAL,
                                         second_attempt_form_field.value());
      }
    }

    auto* prerender_web_contents =
        test::PrerenderTestHelper::GetPrerenderWebContents(host_id);
    EXPECT_TRUE(prerender_web_contents);
    test::PrerenderHostObserver prerender_observer(*prerender_web_contents,
                                                   host_id);

    if (target_hint == "_blank") {
      TestNavigationObserver observer(prerender_web_contents);
      EXPECT_NE(prerender_web_contents, web_contents_impl());
      test::PrerenderTestHelper::OpenNewWindowWithoutOpener(
          *web_contents_impl(), prerender_url, navigate_as_form_submission);
      observer.WaitForNavigationFinished();
      EXPECT_EQ(observer.last_navigation_url(), prerender_url);
    } else {
      test::PrerenderTestHelper::NavigatePrimaryPage(
          *web_contents_impl(), prerender_url,
          navigate_as_form_submission ? ui::PAGE_TRANSITION_FORM_SUBMIT
                                      : ui::PAGE_TRANSITION_LINK);
    }

    if (should_activate) {
      EXPECT_TRUE(prerender_observer.was_activated());
    } else {
      // The prerender host should be destroyed for parameter mismatch.
      EXPECT_FALSE(HasHostForUrl(prerender_url));
      ExpectFinalStatusForSpeculationRule(
          PrerenderFinalStatus::kActivationNavigationParameterMismatch);
      ASSERT_EQ(prerender_web_contents->GetLastCommittedURL(), prerender_url);
    }

    // If a second prerender attempt is tried, it is expected to be treated as
    // duplicated, so no final status for the attempt.
    histogram_tester().ExpectTotalCount(
        "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule", 1);
  }

  // Verifies that a prerender form submission generated by the prerendered page
  // should be canceled regardless of `form_submission`, which denotes whether
  // the prerender speculation rules are generated for form submission or not.
  void RunPrerenderFormInPrerenderTest(bool form_submission) {
    // The URL that was used to register the Origin Trial token.
    static constexpr char kOriginUrl[] = "https://127.0.0.1:45356";

    const GURL initiator_url(
        base::StrCat({kOriginUrl, "/empty.html?initiator"}));
    // The suffix `?` is for form submission navigations, which has `?` mark
    // regardless of having any parameter or not.
    const GURL prerender_url(base::StrCat({kOriginUrl, "/empty.html?"}));

    // The EmbeddedTestServer must run on a specific port because the origin
    // trial token hard-coded in form_submission_origin_trial_initiator.html is
    // bound to a specific origin. While EmbeddedTestServer allows us to specify
    // a port, doing so introduces test flakiness due to TCP port reuse
    // restrictions. To avoid this, we use URLLoaderInterceptor to serve the
    // file, making the actual port irrelevant.
    URLLoaderInterceptor prerender_loader(base::BindLambdaForTesting(
        [&](URLLoaderInterceptor::RequestParams* params) {
          if (params->url_request.url != initiator_url &&
              params->url_request.url != prerender_url) {
            return false;
          }

          const std::string headers =
              "HTTP/1.1 200 OK\n"
              "Content-type: text/html\n";
          URLLoaderInterceptor::WriteResponse(
              base::StrCat({"content/test/data/prerender",
                            params->url_request.url.path()}),
              params->client.get(), &headers, std::optional<net::SSLInfo>(),
              params->url_request.url);

          return true;
        }));

    // Navigate to an initial page which has a link to `prerender_url`.
    ASSERT_TRUE(NavigateToURL(shell(), initiator_url));

    PrerenderHostId host_id = prerender_helper()->AddPrerender(
        prerender_url, /*eagerness=*/std::nullopt,
        /*no_vary_search_hint=*/std::nullopt,
        /*target_hint=*/std::string(),
        /*ruleset_tag=*/std::nullopt,
        /*world_id=*/ISOLATED_WORLD_ID_GLOBAL,
        /*form_submission=*/form_submission);

    // Generating a form submission within a prerendered page is not allowed.
    content::test::PrerenderHostObserver host_observer(*web_contents_impl(),
                                                       host_id);
    RenderFrameHost* prerender_rfh = GetPrerenderedMainFrameHost(host_id);
    std::ignore = ExecJs(prerender_rfh, R"(
                const form = document.createElement('form');
                form.action = '';
                form.method = 'GET';
                document.body.appendChild(form);
                form.submit();)");
    host_observer.WaitForDestroyed();
    // The prerender host should be destroyed.
    EXPECT_FALSE(HasHostForUrl(prerender_url));
    ExpectFinalStatusForSpeculationRule(
        PrerenderFinalStatus::kFormSubmitWhenPrerendering);
  }

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

IN_PROC_BROWSER_TEST_P(PrerenderFormSubmissionOriginTrialBrowserTest,
                       FormSubmissionHint_ActivationSuccessful) {
  RunFormSubmissionHintTest(/*first_attempt_form_field=*/true,
                            /*second_attempt_form_field=*/std::nullopt,
                            /*target_hint=*/std::string(),
                            /*navigate_as_form_submission=*/true,
                            /*should_activate=*/true);
}

IN_PROC_BROWSER_TEST_P(
    PrerenderFormSubmissionOriginTrialBrowserTest,
    FormSubmissionHint_FirstWin_TrueThenFalse_ActivationSuccesful) {
  RunFormSubmissionHintTest(/*first_attempt_form_field=*/true,
                            /*second_attempt_form_field=*/false,
                            /*target_hint=*/std::string(),
                            /*navigate_as_form_submission=*/true,
                            /*should_activate=*/true);
}

IN_PROC_BROWSER_TEST_P(
    PrerenderFormSubmissionOriginTrialBrowserTest,
    FormSubmissionHint_FirstWin_FalseThenTrue_ActivationSuccesful) {
  RunFormSubmissionHintTest(/*first_attempt_form_field=*/false,
                            /*second_attempt_form_field=*/true,
                            /*target_hint=*/std::string(),
                            /*navigate_as_form_submission=*/false,
                            /*should_activate=*/true);
}

// Verifies that the second prerender will be treated as duplicated and
// the non-form submission navigation cannot activate form submission prerender.
IN_PROC_BROWSER_TEST_P(
    PrerenderFormSubmissionOriginTrialBrowserTest,
    FormSubmissionHint_FirstWin_TrueThenFalse_FailWithMismatch) {
  RunFormSubmissionHintTest(/*first_attempt_form_field=*/true,
                            /*second_attempt_form_field=*/false,
                            /*target_hint=*/std::string(),
                            /*navigate_as_form_submission=*/false,
                            /*should_activate=*/false);
}

// Verifies that the second prerender will be treated as duplicated and
// the form submission navigation cannot activate non-form submission prerender.
IN_PROC_BROWSER_TEST_P(
    PrerenderFormSubmissionOriginTrialBrowserTest,
    FormSubmissionHint_FirstWin_FalseThenTrue_FailWithMismatch) {
  RunFormSubmissionHintTest(/*first_attempt_form_field=*/false,
                            /*second_attempt_form_field=*/true,
                            /*target_hint=*/std::string(),
                            /*navigate_as_form_submission=*/true,
                            /*should_activate=*/false);
}

IN_PROC_BROWSER_TEST_P(PrerenderFormSubmissionOriginTrialBrowserTest,
                       FormSubmissionHintBlankTargetHint_ActivationSuccessful) {
  RunFormSubmissionHintTest(/*first_attempt_form_field=*/true,
                            /*second_attempt_form_field=*/std::nullopt,
                            /*target_hint=*/"_blank",
                            /*navigate_as_form_submission=*/true,
                            /*should_activate=*/true);
}

IN_PROC_BROWSER_TEST_P(PrerenderFormSubmissionOriginTrialBrowserTest,
                       FormSubmissionHintBlankTargetHint_FailWithMismatch) {
  RunFormSubmissionHintTest(/*first_attempt_form_field=*/true,
                            /*second_attempt_form_field=*/std::nullopt,
                            /*target_hint=*/"_blank",
                            /*navigate_as_form_submission=*/false,
                            /*should_activate=*/false);
}

// The test will generate a form submission within the prerender by javascript.
// PUS will not run the javascript when prerendering, so this has prerender
// variation only.
IN_PROC_BROWSER_TEST_F(PrerenderFormSubmissionOriginTrialBrowserTest,
                       PrerenderFormInPrerender_WithFormSubmission) {
  RunPrerenderFormInPrerenderTest(/*form_submission=*/true);
}

// The test will generate a form submission within the prerender by javascript.
// PUS will not run the javascript when prerendering, so this has prerender
// variation only.
IN_PROC_BROWSER_TEST_F(PrerenderFormSubmissionOriginTrialBrowserTest,
                       PrerenderFormInPrerender_WithoutFormSubmission) {
  RunPrerenderFormInPrerenderTest(/*form_submission=*/false);
}

INSTANTIATE_TEST_SUITE_P(All,
                         PrerenderFormSubmissionOriginTrialBrowserTest,
                         testing::Bool());

}  // namespace content
