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

#include <string>

#include "base/files/file_path.h"
#include "base/functional/bind.h"
#include "base/path_service.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/timer/elapsed_timer.h"
#include "build/build_config.h"
#include "chrome/browser/preloading/chrome_preloading.h"
#include "chrome/browser/preloading/new_tab_page_preload/new_tab_page_preload_pipeline_manager.h"
#include "chrome/browser/preloading/preloading_prefs.h"
#include "chrome/browser/preloading/prerender/prerender_manager.h"
#include "chrome/browser/preloading/prerender/prerender_utils.h"
#include "chrome/browser/preloading/prerender/search_prewarm_progress_service.h"
#include "chrome/browser/preloading/prerender/search_prewarm_progress_service_factory.h"
#include "chrome/browser/preloading/prerender/search_prewarm_progress_test_utils.h"
#include "chrome/browser/preloading/scoped_prewarm_feature_list.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/webui_url_constants.h"
#include "chrome/test/base/chrome_test_utils.h"
#include "chrome/test/base/platform_browser_test.h"
#include "components/page_load_metrics/browser/navigation_handle_user_data.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/common/content_features.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/preloading_test_util.h"
#include "content/public/test/prerender_test_util.h"
#include "content/public/test/slow_http_response.h"
#include "content/public/test/test_navigation_observer.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom.h"

#if BUILDFLAG(IS_ANDROID)
#include "base/android/android_info.h"
#include "ui/base/device_form_factor.h"
#endif

namespace {

namespace {

// Following definitions are equal to content::PrerenderFinalStatus.
constexpr int kFinalStatusActivated = 0;
constexpr int kFinalStatusInvalidSchemeNavigation = 6;
constexpr int kFinalStatusTriggerDestroyed = 16;
constexpr int kFinalStatusTabClosedWithoutUserGesture = 55;
constexpr int kFinalStatusCrossSiteNavigationInMainFrameNavigation = 64;

}  // namespace

using UkmEntry = ukm::TestUkmRecorder::HumanReadableUkmEntry;
using ukm::builders::Preloading_Attempt;

class PrerenderBrowserTest : public PlatformBrowserTest {
 public:
  PrerenderBrowserTest()
      : prerender_helper_(
            base::BindRepeating(&PrerenderBrowserTest::GetActiveWebContents,
                                base::Unretained(this))) {}

  void SetUp() override {
    prerender_helper_.RegisterServerRequestMonitor(embedded_test_server());
    prerender_helper_.RegisterServerRequestMonitor(&ssl_server_);
    PlatformBrowserTest::SetUp();
  }

  void SetUpOnMainThread() override {
    host_resolver()->AddRule("*", "127.0.0.1");
    embedded_test_server()->ServeFilesFromDirectory(
        base::PathService::CheckedGet(chrome::DIR_TEST_DATA));
    ASSERT_TRUE(embedded_test_server()->Start());

    ssl_server_.SetSSLConfig(
        net::test_server::EmbeddedTestServer::CERT_TEST_NAMES);
    ssl_server_.ServeFilesFromDirectory(
        base::PathService::CheckedGet(chrome::DIR_TEST_DATA));
    ASSERT_TRUE(ssl_server_.Start());
  }

  void TearDownOnMainThread() override {
    ASSERT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete());
    ASSERT_TRUE(ssl_server_.ShutdownAndWaitUntilComplete());
  }

  content::WebContents* GetActiveWebContents() {
    return chrome_test_utils::GetActiveWebContents(this);
  }

  content::test::PrerenderTestHelper& prerender_helper() {
    return prerender_helper_;
  }

  GURL GetUrl(const std::string& path) {
    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);
  }

 protected:
  void TestPrerenderAndActivateInNewTab(const std::string& link_click_script,
                                        bool should_be_activated);

 private:
  content::test::PrerenderTestHelper prerender_helper_;
  test::ScopedPrewarmFeatureList scoped_prewarm_feature_list_{
      test::ScopedPrewarmFeatureList::PrewarmState::kDisabled};
  net::test_server::EmbeddedTestServer ssl_server_{
      net::test_server::EmbeddedTestServer::TYPE_HTTPS};
};

// An end-to-end test of prerendering and activating.
// TODO(crbug.com/452239399): Re-enable this test.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderAndActivate) {
  base::HistogramTester histogram_tester;

  // Navigate to an initial page.
  GURL url = embedded_test_server()->GetURL("/empty.html");
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));

  // Start a prerender.
  GURL prerender_url = embedded_test_server()->GetURL("/simple.html");
  prerender_helper().AddPrerender(prerender_url);

  // Activate.
  content::TestActivationManager activation_manager(GetActiveWebContents(),
                                                    prerender_url);
  ASSERT_TRUE(
      content::ExecJs(GetActiveWebContents()->GetPrimaryMainFrame(),
                      content::JsReplace("location = $1", prerender_url)));
  activation_manager.WaitForNavigationFinished();
  EXPECT_TRUE(activation_manager.was_activated());

  histogram_tester.ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      kFinalStatusActivated, 1);
}

void PrerenderBrowserTest::TestPrerenderAndActivateInNewTab(
    const std::string& link_click_script,
    bool should_be_activated) {
  base::HistogramTester histogram_tester;

  histogram_tester.ExpectBucketCount(
      "Blink.UseCounter.Features",
      blink::mojom::WebFeature::kSpeculationRulesTargetHintBlank, 0);

  // Navigate to an initial page.
  GURL url = embedded_test_server()->GetURL("/prerender/simple_links.html");
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));

  // Start a prerender.
  GURL prerender_url = embedded_test_server()->GetURL("/prerender/empty.html");
  content::PrerenderHostId host_id =
      prerender_helper().AddPrerender(prerender_url,
                                      /*eagerness=*/std::nullopt, "_blank");
  EXPECT_TRUE(host_id);

  // Activate.
  EXPECT_TRUE(ExecJs(GetActiveWebContents(), link_click_script));

  histogram_tester.ExpectBucketCount(
      "Blink.UseCounter.Features",
      blink::mojom::WebFeature::kSpeculationRulesTargetHintBlank, 1);

  histogram_tester.ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      kFinalStatusActivated, should_be_activated ? 1 : 0);
}

// An end-to-end test of prerendering in a new tab and activating.
// Disabled on Android due to failures: https://crbug.com/355255740.
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_PrerenderAndActivate_InNewTab \
  DISABLED_PrerenderAndActivate_InNewTab
#else
#define MAYBE_PrerenderAndActivate_InNewTab PrerenderAndActivate_InNewTab
#endif
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       MAYBE_PrerenderAndActivate_InNewTab) {
  TestPrerenderAndActivateInNewTab("clickSameSiteNewWindowLink();", true);
}

// Disabled on Android due to failures: https://crbug.com/355255740.
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_PrerenderAndActivate_InNewTab_Noopener \
  DISABLED_PrerenderAndActivate_InNewTab_Noopener
#else
#define MAYBE_PrerenderAndActivate_InNewTab_Noopener \
  PrerenderAndActivate_InNewTab_Noopener
#endif
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       MAYBE_PrerenderAndActivate_InNewTab_Noopener) {
  TestPrerenderAndActivateInNewTab("clickSameSiteNewWindowWithNoopenerLink();",
                                   true);
}

// Prerendering in a new tab should not be activate for a new window with an
// opener.
// The test is flaky on android-12l-x64-dbg-tests: https://crbug.com/40935364.
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_PrerenderAndActivate_InNewTab_Opener \
  DISABLED_PrerenderAndActivate_InNewTab_Opener
#else
#define MAYBE_PrerenderAndActivate_InNewTab_Opener \
  PrerenderAndActivate_InNewTab_Opener
#endif  // #if BUILDFLAG(IS_ANDROID) && defined(ARCH_CPU_X86)
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       MAYBE_PrerenderAndActivate_InNewTab_Opener) {
  TestPrerenderAndActivateInNewTab("clickSameSiteNewWindowWithOpenerLink();",
                                   false);
}

// Prerendering in a new tab should not be activate for a current tab.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       PrerenderAndActivate_InNewTab_CurrentTab) {
  TestPrerenderAndActivateInNewTab("clickSameSiteLink();", false);
}

// Tests main frame navigation on a prerendered page in a new tab.
// Disabled on Android due to failures: https://crbug.com/355255740.
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_MainFrameNavigation_InNewTab DISABLED_MainFrameNavigation_InNewTab
#else
#define MAYBE_MainFrameNavigation_InNewTab MainFrameNavigation_InNewTab
#endif
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       MAYBE_MainFrameNavigation_InNewTab) {
  base::HistogramTester histogram_tester;
  std::string link_click_script = "clickSameSiteNewWindowLink();";

  // Navigate to an initial page.
  GURL url = embedded_test_server()->GetURL("/prerender/simple_links.html");
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));

  // Start a prerender.
  GURL prerender_url = embedded_test_server()->GetURL("/prerender/empty.html");
  content::PrerenderHostId host_id = prerender_helper().AddPrerender(
      prerender_url, /*eagerness=*/std::nullopt, "_blank");
  EXPECT_TRUE(host_id);

  // Navigate a prerendered page to another page.
  GURL navigation_url =
      embedded_test_server()->GetURL("/prerender/empty.html?navigated");
  prerender_helper().NavigatePrerenderedPage(host_id, navigation_url);

  auto* prerender_web_contents =
      prerender_helper().GetPrerenderWebContents(host_id);

  // Activate.
  content::test::PrerenderHostObserver prerender_observer(
      *prerender_web_contents, host_id);
  EXPECT_TRUE(ExecJs(GetActiveWebContents(), link_click_script));
  prerender_observer.WaitForActivation();
  EXPECT_EQ(prerender_web_contents->GetLastCommittedURL(), navigation_url);
  EXPECT_EQ(prerender_web_contents->GetVisibleURL(), navigation_url);

  histogram_tester.ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      kFinalStatusActivated, 1);
}

class PrerenderUntilScriptBrowserTest : public PrerenderBrowserTest {
 public:
  PrerenderUntilScriptBrowserTest() {
    feature_list_.InitAndEnableFeature(blink::features::kPrerenderUntilScript);
  }

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

IN_PROC_BROWSER_TEST_F(PrerenderUntilScriptBrowserTest, UseCounter) {
  base::HistogramTester histogram_tester;

  // Navigate to an initial page.
  GURL url = embedded_test_server()->GetURL("/empty.html");
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));
  histogram_tester.ExpectBucketCount(
      "Blink.UseCounter.Features",
      blink::mojom::WebFeature::kSpeculationRulesPrerenderUntilScript, 0);

  // Trigger prerender-until-script action.
  GURL prerender_url = embedded_test_server()->GetURL("/simple.html");
  prerender_helper().AddPrerenderUntilScriptAsync(prerender_url);
  content::test::PrerenderTestHelper::WaitForPrerenderLoadCompletion(
      *GetActiveWebContents(), prerender_url);

  histogram_tester.ExpectBucketCount(
      "Blink.UseCounter.Features",
      blink::mojom::WebFeature::kSpeculationRulesPrerenderUntilScript, 1);
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       PrerenderTriggeredByEmbedderAndActivate) {
  base::HistogramTester histogram_tester;

  // Navigate to an initial page.
  GURL url = embedded_test_server()->GetURL("/empty.html");
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));

  GURL prerender_url = embedded_test_server()->GetURL("/simple.html");

  // Start embedder triggered prerendering.
  std::unique_ptr<content::PrerenderHandle> prerender_handle =
      prerender_helper().AddEmbedderTriggeredPrerenderAsync(
          prerender_url, content::PreloadingTriggerType::kEmbedder,
          prerender_utils::kDirectUrlInputMetricSuffix,
          ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
                                    ui::PAGE_TRANSITION_FROM_ADDRESS_BAR));
  EXPECT_TRUE(prerender_handle);
  content::test::PrerenderTestHelper::WaitForPrerenderLoadCompletion(
      *GetActiveWebContents(), prerender_url);

  // Activate.
  content::TestActivationManager activation_manager(GetActiveWebContents(),
                                                    prerender_url);
  // Simulate a browser-initiated navigation.
  prerender_helper().NavigatePrimaryPageAsync(
      prerender_url,
      ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
                                ui::PAGE_TRANSITION_FROM_ADDRESS_BAR));
  activation_manager.WaitForNavigationFinished();
  EXPECT_TRUE(activation_manager.was_activated());

  histogram_tester.ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_DirectURLInput",
      kFinalStatusActivated, 1);
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, EmbedderTrigger_ChromeUrl) {
  base::HistogramTester histogram_tester;

  // Navigate to an initial page.
  GURL url = embedded_test_server()->GetURL("/empty.html");
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));

  GURL prerender_url("chrome://new-tab-page");
  ASSERT_FALSE(prerender_url.SchemeIsHTTPOrHTTPS());

  // Start embedder triggered prerendering.
  std::unique_ptr<content::PrerenderHandle> prerender_handle =
      prerender_helper().AddEmbedderTriggeredPrerenderAsync(
          prerender_url, content::PreloadingTriggerType::kEmbedder,
          prerender_utils::kDirectUrlInputMetricSuffix,
          ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
                                    ui::PAGE_TRANSITION_FROM_ADDRESS_BAR));
  EXPECT_FALSE(prerender_handle);

  histogram_tester.ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_DirectURLInput",
      kFinalStatusInvalidSchemeNavigation, 1);
}

// Tests that UseCounter for SpeculationRules-triggered prerender is recorded.
// This cannot be tested in content/ as SpeculationHostImpl records the usage
// with ContentBrowserClient::LogWebFeatureForCurrentPage() that is not
// implemented in content/.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, UseCounter) {
  base::HistogramTester histogram_tester;

  // Navigate to an initial page.
  GURL url = embedded_test_server()->GetURL("/empty.html");
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));

  histogram_tester.ExpectBucketCount(
      "Blink.UseCounter.Features",
      blink::mojom::WebFeature::kSpeculationRulesPrerender, 0);
  histogram_tester.ExpectBucketCount(
      "Blink.UseCounter.Features",
      blink::mojom::WebFeature::kV8Document_Prerendering_AttributeGetter, 0);
  histogram_tester.ExpectBucketCount(
      "Blink.UseCounter.Features",
      blink::mojom::WebFeature::
          kV8Document_Onprerenderingchange_AttributeSetter,
      0);
  histogram_tester.ExpectBucketCount("Blink.UseCounter.Features",
                                     blink::mojom::WebFeature::kPageVisits, 1);

  // Start a prerender. The API call should be recorded.
  GURL prerender_url = embedded_test_server()->GetURL("/simple.html");
  prerender_helper().AddPrerender(prerender_url);
  // kPageVisits should have been issued for kPageVisits already, but the value
  // hasn't been updated due to the update will be delayed until the activation
  // in the current design. The value is still expected to be one.
  // Please refer to crrev.com/c/3856942 for implementation details.
  histogram_tester.ExpectBucketCount("Blink.UseCounter.Features",
                                     blink::mojom::WebFeature::kPageVisits, 1);

  // Accessing related attributes should also be recorded.
  ASSERT_TRUE(content::ExecJs(GetActiveWebContents()->GetPrimaryMainFrame(),
                              "const value = document.prerendering;"));
  ASSERT_TRUE(content::ExecJs(GetActiveWebContents()->GetPrimaryMainFrame(),
                              "document.onprerenderingchange = e => {};"));

  // Make sure the counts are stored by navigating away.
  prerender_helper().NavigatePrimaryPage(prerender_url);

  histogram_tester.ExpectBucketCount(
      "Blink.UseCounter.Features",
      blink::mojom::WebFeature::kSpeculationRulesPrerender, 1);
  histogram_tester.ExpectBucketCount(
      "Blink.UseCounter.Features",
      blink::mojom::WebFeature::kV8Document_Prerendering_AttributeGetter, 1);
  histogram_tester.ExpectBucketCount(
      "Blink.UseCounter.Features",
      blink::mojom::WebFeature::
          kV8Document_Onprerenderingchange_AttributeSetter,
      1);
  histogram_tester.ExpectBucketCount("Blink.UseCounter.Features",
                                     blink::mojom::WebFeature::kPageVisits, 2);
}

// Tests that Prerender2 cannot be triggered when preload setting is disabled.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DisableNetworkPrediction) {
  // Navigate to an initial page.
  GURL url = embedded_test_server()->GetURL("/empty.html");
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));

  // Disable network prediction.
  PrefService* prefs = chrome_test_utils::GetProfile(this)->GetPrefs();
  prefetch::SetPreloadPagesState(prefs,
                                 prefetch::PreloadPagesState::kNoPreloading);
  ASSERT_EQ(prefetch::IsSomePreloadingEnabled(*prefs),
            content::PreloadingEligibility::kPreloadingDisabled);

  // Attempt to trigger prerendering.
  GURL prerender_url = embedded_test_server()->GetURL("/simple.html?1");
  prerender_helper().AddPrerenderAsync(prerender_url);
  // Since preload setting is disabled, prerender shouldn't be triggered.
  base::RunLoop().RunUntilIdle();
  content::PrerenderHostId host_id =
      prerender_helper().GetHostForUrl(prerender_url);
  EXPECT_TRUE(host_id.is_null());

  // Reload the initial page to reset the speculation rules.
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));

  // Re-enable the setting.
  prefetch::SetPreloadPagesState(
      prefs, prefetch::PreloadPagesState::kStandardPreloading);
  ASSERT_EQ(prefetch::IsSomePreloadingEnabled(*prefs),
            content::PreloadingEligibility::kEligible);

  // Attempt to trigger prerendering again.
  content::test::PrerenderHostRegistryObserver registry_observer(
      *GetActiveWebContents());
  prerender_helper().AddPrerenderAsync(prerender_url);
  // Since preload setting is enabled, prerender should be triggered
  // successfully.
  registry_observer.WaitForTrigger(prerender_url);
  host_id = prerender_helper().GetHostForUrl(prerender_url);
  EXPECT_TRUE(host_id);
}

// TODO(https://crbug.com/455854991): Failing on Android tablets.
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_PreloadingHoldbackOverridden DISABLED_PreloadingHoldbackOverridden
#else
#define MAYBE_PreloadingHoldbackOverridden PreloadingHoldbackOverridden
#endif
// Tests that DevTools open overrides PreloadingConfig's holdback.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       MAYBE_PreloadingHoldbackOverridden) {
#if BUILDFLAG(IS_ANDROID)
  if (base::android::android_info::sdk_int() >=
          base::android::android_info::SDK_VERSION_U &&
      ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_DESKTOP) {
    GTEST_SKIP() << "Disabled on Android U+ tablets due to crbug.com/393195683";
  }
#endif
  prerender_helper().SetHoldback("Prerender", "SpeculationRules", true);
  base::HistogramTester histogram_tester;

  // Navigate to an initial page.
  GURL url = embedded_test_server()->GetURL("/empty.html");
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));
  PrefService* prefs = chrome_test_utils::GetProfile(this)->GetPrefs();

  // IsSomePreloadingEnabled is *not* affected by PreloadingConfig.
  ASSERT_EQ(prefetch::IsSomePreloadingEnabled(*prefs),
            content::PreloadingEligibility::kEligible);

  // Emulating Devtools attached to make PreloadingHoldback overridden. Retain
  // the returned host until the test finishes to avoid DevTools termination.
  scoped_refptr<content::DevToolsAgentHost> dev_tools_agent_host =
      content::DevToolsAgentHost::GetOrCreateFor(GetActiveWebContents());
  ASSERT_TRUE(dev_tools_agent_host);

  // Start a prerender.
  GURL prerender_url = embedded_test_server()->GetURL("/simple.html");
  prerender_helper().AddPrerender(prerender_url);

  // Activate.
  content::TestActivationManager activation_manager(GetActiveWebContents(),
                                                    prerender_url);
  ASSERT_TRUE(
      content::ExecJs(GetActiveWebContents()->GetPrimaryMainFrame(),
                      content::JsReplace("location = $1", prerender_url)));
  activation_manager.WaitForNavigationFinished();
  EXPECT_TRUE(activation_manager.was_activated());

  histogram_tester.ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      kFinalStatusActivated, 1);
}

// Tests that Prerender2 cannot be triggered when PreloadingConfig's
// holdback is not overridden by DevTools.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PreloadingHoldbackNotOverridden) {
  prerender_helper().SetHoldback("Prerender", "SpeculationRules", true);

  // Navigate to an initial page.
  GURL url = embedded_test_server()->GetURL("/empty.html");
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));

  PrefService* prefs = chrome_test_utils::GetProfile(this)->GetPrefs();

  // IsSomePreloadingEnabled is *not* affected by PreloadingConfig.
  ASSERT_EQ(prefetch::IsSomePreloadingEnabled(*prefs),
            content::PreloadingEligibility::kEligible);

  content::test::PrerenderHostRegistryObserver registry_observer(
      *GetActiveWebContents());

  // Attempt to trigger prerendering.
  GURL prerender_url = embedded_test_server()->GetURL("/simple.html?1");
  prerender_helper().AddPrerenderAsync(prerender_url);
  // Since preload setting is disabled, prerender shouldn't be triggered.
  registry_observer.WaitForTrigger(prerender_url);
  content::PrerenderHostId host_id =
      prerender_helper().GetHostForUrl(prerender_url);
  EXPECT_TRUE(host_id.is_null());
}

// Tests that the same-origin main frame navigation in an embedder triggered
// prerendering page succeeds.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, SameOriginMainFrameNavigation) {
  base::HistogramTester histogram_tester;

  // Navigate to an initial page.
  GURL url = GetUrl("/empty.html");
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));

  GURL prerender_url = GetUrl("/title1.html");
  GURL navigation_url = GetUrl("/title2.html");

  // Start an embedder triggered prerendering.
  std::unique_ptr<content::PrerenderHandle> prerender_handle =
      prerender_helper().AddEmbedderTriggeredPrerenderAsync(
          prerender_url, content::PreloadingTriggerType::kEmbedder,
          prerender_utils::kDirectUrlInputMetricSuffix,
          ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
                                    ui::PAGE_TRANSITION_FROM_ADDRESS_BAR));
  EXPECT_TRUE(prerender_handle);
  content::test::PrerenderTestHelper::WaitForPrerenderLoadCompletion(
      *GetActiveWebContents(), prerender_url);

  content::PrerenderHostId host_id =
      prerender_helper().GetHostForUrl(prerender_url);
  ASSERT_TRUE(host_id);

  // Start a same-origin navigation in the prerender frame tree. It will not
  // cancel the initiator's prerendering.
  prerender_helper().NavigatePrerenderedPage(host_id, navigation_url);

  // Activate.
  content::TestActivationManager activation_manager(GetActiveWebContents(),
                                                    prerender_url);
  // Simulate a browser-initiated navigation.
  prerender_helper().NavigatePrimaryPageAsync(
      prerender_url,
      ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
                                ui::PAGE_TRANSITION_FROM_ADDRESS_BAR));
  activation_manager.WaitForNavigationFinished();
  EXPECT_TRUE(activation_manager.was_activated());

  histogram_tester.ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_DirectURLInput",
      kFinalStatusActivated, 1);
}

// Tests that the same-site cross-origin main frame navigation in an embedder
// triggered prerendering page succeeds.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       SameSiteCrossOriginMainFrameNavigation) {
  base::HistogramTester histogram_tester;

  // Navigate to an initial page.
  GURL url = GetUrl("/empty.html");
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));

  GURL prerender_url = GetUrl("/title1.html");
  GURL navigation_url =
      GetSameSiteCrossOriginUrl("/prerender_with_opt_in_header.html");

  // Start an embedder triggered prerendering.
  std::unique_ptr<content::PrerenderHandle> prerender_handle =
      prerender_helper().AddEmbedderTriggeredPrerenderAsync(
          prerender_url, content::PreloadingTriggerType::kEmbedder,
          prerender_utils::kDirectUrlInputMetricSuffix,
          ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
                                    ui::PAGE_TRANSITION_FROM_ADDRESS_BAR));
  EXPECT_TRUE(prerender_handle);
  content::test::PrerenderTestHelper::WaitForPrerenderLoadCompletion(
      *GetActiveWebContents(), prerender_url);

  content::PrerenderHostId host_id =
      prerender_helper().GetHostForUrl(prerender_url);
  ASSERT_TRUE(host_id);

  content::test::PrerenderHostObserver prerender_observer(
      *GetActiveWebContents(), host_id);

  // Start a same-site cross-origin main frame navigation in the prerender frame
  // tree. It will not cancel the initiator's prerendering.
  prerender_helper().NavigatePrerenderedPage(host_id, navigation_url);

  // Activate.
  content::TestActivationManager activation_manager(GetActiveWebContents(),
                                                    prerender_url);
  // Simulate a browser-initiated navigation.
  prerender_helper().NavigatePrimaryPageAsync(
      prerender_url,
      ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
                                ui::PAGE_TRANSITION_FROM_ADDRESS_BAR));
  activation_manager.WaitForNavigationFinished();
  EXPECT_TRUE(activation_manager.was_activated());

  histogram_tester.ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_DirectURLInput",
      kFinalStatusActivated, 1);
}

// Tests that the cross-site main frame navigation in an embedder triggered
// prerendering page cancels the prerendering.
IN_PROC_BROWSER_TEST_F(
    PrerenderBrowserTest,
    CrossSiteMainFrameNavigationCancelsEmbedderTriggeredPrerendering) {
  base::HistogramTester histogram_tester;

  // Navigate to an initial page.
  GURL url = GetUrl("/empty.html");
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));

  GURL prerender_url = GetUrl("/title1.html");
  GURL navigation_url = GetCrossSiteUrl("/prerender_with_opt_in_header.html");

  // Start an embedder triggered prerendering.
  std::unique_ptr<content::PrerenderHandle> prerender_handle =
      prerender_helper().AddEmbedderTriggeredPrerenderAsync(
          prerender_url, content::PreloadingTriggerType::kEmbedder,
          prerender_utils::kDirectUrlInputMetricSuffix,
          ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
                                    ui::PAGE_TRANSITION_FROM_ADDRESS_BAR));
  EXPECT_TRUE(prerender_handle);
  content::test::PrerenderTestHelper::WaitForPrerenderLoadCompletion(
      *GetActiveWebContents(), prerender_url);

  content::PrerenderHostId host_id =
      prerender_helper().GetHostForUrl(prerender_url);
  ASSERT_TRUE(host_id);

  content::test::PrerenderHostObserver prerender_observer(
      *GetActiveWebContents(), host_id);

  // Start a cross-site main frame navigation in the prerender frame tree. It
  // will cancel the initiator's prerendering.
  prerender_helper().NavigatePrerenderedPage(host_id, navigation_url);

  prerender_observer.WaitForDestroyed();

  histogram_tester.ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_DirectURLInput",
      kFinalStatusCrossSiteNavigationInMainFrameNavigation, 1);
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                       PrerenderWebContentsDelegate_CloseContents) {
  base::HistogramTester histogram_tester;

  // Navigate to an initial page.
  GURL url = embedded_test_server()->GetURL("/prerender/simple_links.html");
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));

  // Start a prerender.
  GURL prerender_url = embedded_test_server()->GetURL("/prerender/empty.html");
  content::PrerenderHostId host_id = prerender_helper().AddPrerender(
      prerender_url, /*eagerness=*/std::nullopt, "_blank");

  // Navigate a prerendered page to another page.
  GURL navigation_url =
      embedded_test_server()->GetURL("/prerender/empty.html?navigated");
  prerender_helper().NavigatePrerenderedPage(host_id, navigation_url);

  // WebContents::Close() should eventually call
  // PrerenderWebContentsDelegate::CloseContents() that cancels prerendering.
  auto* prerender_web_contents =
      prerender_helper().GetPrerenderWebContents(host_id);
  ASSERT_TRUE(prerender_web_contents);
  content::WebContentsDestroyedWatcher destroyed_watcher(
      prerender_web_contents);
  prerender_web_contents->Close();

  // WebContents created for the new-tab host will eventually be destroyed after
  // host cancellation.
  destroyed_watcher.Wait();
  EXPECT_FALSE(prerender_helper().HasNewTabHandle(host_id));

  histogram_tester.ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      kFinalStatusTabClosedWithoutUserGesture, 1);
}

class PrerenderNewTabPageBrowserTest
    : public PrerenderBrowserTest,
      public testing::WithParamInterface<content::PreloadingPredictor> {
 public:
  PrerenderNewTabPageBrowserTest() = default;

  void SetUpOnMainThread() override {
    PrerenderBrowserTest::SetUpOnMainThread();
    // Initialize PreloadingAttempt builder for the test suite.
    test_ukm_recorder_ = std::make_unique<ukm::TestAutoSetUkmRecorder>();
    attempt_entry_builder_ =
        std::make_unique<content::test::PreloadingAttemptUkmEntryBuilder>(
            chrome_preloading_predictor::kMouseHoverOrMouseDownOnNewTabPage);
  }

  void SimulateNewTabNavigation(const GURL& url) {
    GetActiveWebContents()->OpenURL(
        content::OpenURLParams(
            url, content::Referrer(), WindowOpenDisposition::CURRENT_TAB,
            ui::PageTransitionFromInt(ui::PAGE_TRANSITION_AUTO_BOOKMARK),
            /*is_renderer_initiated=*/false),
        base::BindRepeating(&page_load_metrics::NavigationHandleUserData::
                                AttachNewTabPageNavigationHandleUserData));
  }

  void ExpectPrerenderPageLoad(
      const GURL& prerender_url,
      page_load_metrics::NavigationHandleUserData::InitiatorLocation
          initiator_location) {
    auto entries =
        test_ukm_recorder()->GetMergedEntriesByName("PrerenderPageLoad");
    for (auto& kv : entries) {
      const ukm::mojom::UkmEntry* entry = kv.second.get();
      const ukm::UkmSource* source =
          test_ukm_recorder()->GetSourceForSourceId(entry->source_id);
      if (!source) {
        continue;
      }
      EXPECT_TRUE(source->url().is_valid());
      if (source->url() != prerender_url) {
        continue;
      }
      test_ukm_recorder()->ExpectEntryMetric(
          entry,
          ukm::builders::PrerenderPageLoad::kNavigation_InitiatorLocationName,
          static_cast<int>(initiator_location));
      return;
    }
    EXPECT_TRUE(false) << "PrerenderPageLoad hasn't been recorded.";
  }

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

  const content::test::PreloadingAttemptUkmEntryBuilder&
  attempt_entry_builder() {
    return *attempt_entry_builder_;
  }

 private:
  // This timer is for making TimeToNextNavigation in UKM consistent.
  base::ScopedMockElapsedTimersForTest test_timer_;
  std::unique_ptr<ukm::TestAutoSetUkmRecorder> test_ukm_recorder_;
  std::unique_ptr<content::test::PreloadingAttemptUkmEntryBuilder>
      attempt_entry_builder_;
};

IN_PROC_BROWSER_TEST_F(PrerenderNewTabPageBrowserTest,
                       PrerenderTriggeredByNewTabPageAndActivate) {
  base::HistogramTester histogram_tester;

  // Navigate to an initial page.
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(),
                                     chrome::ChromeUINewTabURLAsGURL()));
  GURL prerender_url = GetUrl("/simple.html");

  std::unique_ptr<NewTabPagePreloadPipelineManager> ntp_preload_manager =
      std::make_unique<NewTabPagePreloadPipelineManager>(
          GetActiveWebContents());
  ntp_preload_manager->StartPrerender(
      prerender_url,
      chrome_preloading_predictor::kMouseHoverOrMouseDownOnNewTabPage);
  content::test::PrerenderTestHelper::WaitForPrerenderLoadCompletion(
      *GetActiveWebContents(), prerender_url);

  // Activate.
  content::TestActivationManager activation_manager(GetActiveWebContents(),
                                                    prerender_url);
  SimulateNewTabNavigation(prerender_url);
  activation_manager.WaitForNavigationFinished();
  EXPECT_TRUE(activation_manager.was_activated());

  histogram_tester.ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_NewTabPage",
      kFinalStatusActivated, 1);
  histogram_tester.ExpectTotalCount(
      "NewTabPage.PrerenderNavigationToActivation", 1);

  ExpectPrerenderPageLoad(prerender_url,
                          page_load_metrics::NavigationHandleUserData::
                              InitiatorLocation::kNewTabPage);
  histogram_tester.ExpectUniqueSample(
      "Prerender.IsPrerenderingSRPUrl.Embedder_NewTabPage", false, 1);
}

// Verify that NewTabPage prerender rejects non https url.
IN_PROC_BROWSER_TEST_F(PrerenderNewTabPageBrowserTest,
                       NewTabPagePrerenderNonHttps) {
  // Navigate to an initial page.
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(),
                                     chrome::ChromeUINewTabURLAsGURL()));
  GURL prerender_url = embedded_test_server()->GetURL("/simple.html?prerender");

  std::unique_ptr<NewTabPagePreloadPipelineManager> ntp_preload_manager =
      std::make_unique<NewTabPagePreloadPipelineManager>(
          GetActiveWebContents());
  ntp_preload_manager->StartPrerender(
      prerender_url,
      chrome_preloading_predictor::kMouseHoverOrMouseDownOnNewTabPage);
  base::RunLoop().RunUntilIdle();
  content::PrerenderHostId host_id =
      prerender_helper().GetHostForUrl(prerender_url);
  EXPECT_TRUE(host_id.is_null());

  // Navigate to a different URL other than the prerender_url to flush the
  // metrics.
  ASSERT_TRUE(content::NavigateToURL(
      GetActiveWebContents(), embedded_test_server()->GetURL("/simple.html")));

  ukm::SourceId ukm_source_id =
      GetActiveWebContents()->GetPrimaryMainFrame()->GetPageUkmSourceId();
  content::test::ExpectPreloadingAttemptUkm(
      *test_ukm_recorder(),
      {attempt_entry_builder().BuildEntry(
          ukm_source_id, content::PreloadingType::kPrerender,
          content::PreloadingEligibility::kHttpsOnly,
          content::PreloadingHoldbackStatus::kUnspecified,
          content::PreloadingTriggeringOutcome::kUnspecified,
          content::PreloadingFailureReason::kUnspecified,
          /*accurate=*/false)});
}

IN_PROC_BROWSER_TEST_F(PrerenderNewTabPageBrowserTest,
                       PrerenderTriggeredCancelAndRetrigger) {
  base::HistogramTester histogram_tester;

  // Navigate to an initial page.
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(),
                                     chrome::ChromeUINewTabURLAsGURL()));
  GURL prerender_url = GetUrl("/simple.html");

  std::unique_ptr<NewTabPagePreloadPipelineManager> ntp_preload_manager =
      std::make_unique<NewTabPagePreloadPipelineManager>(
          GetActiveWebContents());

  ntp_preload_manager->StartPrerender(
      prerender_url,
      chrome_preloading_predictor::kMouseHoverOrMouseDownOnNewTabPage);
  content::test::PrerenderTestHelper::WaitForPrerenderLoadCompletion(
      *GetActiveWebContents(), prerender_url);

  ntp_preload_manager->ResetPrerender();

  histogram_tester.ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_NewTabPage",
      kFinalStatusTriggerDestroyed, 1);

  // Retrigger after cancelation.
  ntp_preload_manager->StartPrerender(
      prerender_url,
      chrome_preloading_predictor::kMouseHoverOrMouseDownOnNewTabPage);
  content::test::PrerenderTestHelper::WaitForPrerenderLoadCompletion(
      *GetActiveWebContents(), prerender_url);

  // Activate.
  content::TestActivationManager activation_manager(GetActiveWebContents(),
                                                    prerender_url);
  SimulateNewTabNavigation(prerender_url);
  activation_manager.WaitForNavigationFinished();
  EXPECT_TRUE(activation_manager.was_activated());

  histogram_tester.ExpectBucketCount(
      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_NewTabPage",
      kFinalStatusActivated, 1);
  histogram_tester.ExpectTotalCount(
      "NewTabPage.PrerenderNavigationToActivation", 1);
}

IN_PROC_BROWSER_TEST_F(PrerenderNewTabPageBrowserTest,
                       DestroyedOnNavigatedAway) {
  base::HistogramTester histogram_tester;

  // Navigate to an initial page.
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(),
                                     chrome::ChromeUINewTabURLAsGURL()));
  GURL prerender_url = GetUrl("/simple.html?prerender");

  std::unique_ptr<NewTabPagePreloadPipelineManager> ntp_preload_manager =
      std::make_unique<NewTabPagePreloadPipelineManager>(
          GetActiveWebContents());

  ntp_preload_manager->StartPrerender(
      prerender_url,
      chrome_preloading_predictor::kMouseHoverOrMouseDownOnNewTabPage);
  content::test::PrerenderTestHelper::WaitForPrerenderLoadCompletion(
      *GetActiveWebContents(), prerender_url);

  content::PrerenderHostId host_id =
      prerender_helper().GetHostForUrl(prerender_url);
  ASSERT_TRUE(host_id);

  // Navigate to a different page. This should cancel prerendering.
  GURL different_url = GetUrl("/simple.html?different");
  content::test::PrerenderHostObserver prerender_observer(
      *GetActiveWebContents(), host_id);
  SimulateNewTabNavigation(different_url);
  prerender_observer.WaitForDestroyed();

  histogram_tester.ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_NewTabPage",
      kFinalStatusTriggerDestroyed, 1);
}

IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, TagsUseCounter) {
  base::HistogramTester histogram_tester;

  histogram_tester.ExpectBucketCount(
      "Blink.UseCounter.Features",
      blink::mojom::WebFeature::kSpeculationRulesTags, 0);

  // Navigate to an initial page.
  GURL url =
      embedded_test_server()->GetURL("/prerender/prerender_with_tags.html");
  GURL prerender_url = embedded_test_server()->GetURL("/prerender/empty.html");
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));
  content::test::PrerenderTestHelper::WaitForPrerenderLoadCompletion(
      *GetActiveWebContents(), prerender_url);

  histogram_tester.ExpectBucketCount(
      "Blink.UseCounter.Features",
      blink::mojom::WebFeature::kSpeculationRulesTags, 1);
}

// Tests that if no tag is specified, then UseCounter will not increase.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, NoUseCountIfTagEmpty) {
  base::HistogramTester histogram_tester;

  histogram_tester.ExpectBucketCount(
      "Blink.UseCounter.Features",
      blink::mojom::WebFeature::kSpeculationRulesTags, 0);

  // Navigate to an initial page.
  GURL url = embedded_test_server()->GetURL("/prerender/empty.html");
  GURL prerender_url =
      embedded_test_server()->GetURL("/prerender/empty.html?prerender");
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));
  prerender_helper().AddPrerender(prerender_url);

  histogram_tester.ExpectBucketCount(
      "Blink.UseCounter.Features",
      blink::mojom::WebFeature::kSpeculationRulesTags, 0);
}

// TODO(crbug.com/425270853): Move the common logic of prewarm tests to
// PrewarmTestHelper in prerender_test_util.h
class PrerenderPrewarmDefaultSearchEngineTest
    : public PrerenderBrowserTest,
      public testing::WithParamInterface<content::PreloadingPredictor> {
 public:
  PrerenderPrewarmDefaultSearchEngineTest() {
    reuse_prerender_host_feature_.InitAndEnableFeature(
        features::kPrerender2ReuseHost);
  }

  void SetUpOnMainThread() override {
    embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
        &PrerenderPrewarmDefaultSearchEngineTest::HandleDelayedResource,
        base::Unretained(this)));
    PrerenderBrowserTest::SetUpOnMainThread();
    PrerenderManager::CreateForWebContents(GetActiveWebContents());
    auto* prerender_manager =
        PrerenderManager::FromWebContents(GetActiveWebContents());
    // The GetURL() function can only be called after the test server
    // is started so we cannot override the prewarm URL feature parameter
    // during the constructor.
    prewarm_url_ = embedded_test_server()->GetURL("/simple.html");
    prerender_manager->SetPrewarmUrlForTesting(prewarm_url_);
  }

  std::unique_ptr<net::test_server::HttpResponse> HandleDelayedResource(
      const net::test_server::HttpRequest& request) {
    if (!request.GetURL().GetPath().contains("delayed_stylesheet.css")) {
      return nullptr;
    }
    return std::make_unique<content::SlowHttpResponse>(
        content::SlowHttpResponse::NoResponse());
  }

  content::PrerenderHostId GetPrewarmSearchResultHost() {
    return prerender_helper().GetPrewarmSearchResultHost(prewarm_url_);
  }

  content::WebContents* CreateNewTab() {
    content::WebContents* original_web_contents = GetActiveWebContents();
    original_web_contents->OpenURL(
        content::OpenURLParams(
            GURL(url::kAboutBlankURL), content::Referrer(),
            WindowOpenDisposition::NEW_FOREGROUND_TAB,
            ui::PageTransitionFromInt(ui::PAGE_TRANSITION_AUTO_BOOKMARK),
            /*is_renderer_initiated=*/false),
        base::BindRepeating(&page_load_metrics::NavigationHandleUserData::
                                AttachNewTabPageNavigationHandleUserData));
    content::WebContents* new_web_contents = GetActiveWebContents();
    EXPECT_TRUE(new_web_contents);
    EXPECT_NE(new_web_contents, original_web_contents);
    return new_web_contents;
  }

 protected:
  GURL prewarm_url_;
  test::ScopedPrewarmFeatureList scoped_prewarm_feature_list_{
      test::ScopedPrewarmFeatureList::PrewarmState::kEnabledWithNoTrigger};
  base::test::ScopedFeatureList reuse_prerender_host_feature_;
};

IN_PROC_BROWSER_TEST_F(PrerenderPrewarmDefaultSearchEngineTest,
                       PrewarmPageLoaded) {
  base::HistogramTester histogram_tester;

  // Navigate to an initial page.
  GURL url = embedded_test_server()->GetURL("/empty.html");
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));

  // Prerender the prewarm page.
  auto* prerender_manager =
      PrerenderManager::FromWebContents(GetActiveWebContents());
  EXPECT_TRUE(prerender_manager->MaybeStartPrewarmSearchResult());
  auto host_id = GetPrewarmSearchResultHost();
  ASSERT_TRUE(host_id);
  prerender_helper().WaitForPrerenderLoadCompletion(host_id);
}

// TODO(https://crbug.com/455856004): Failing on Android tablets.
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_PrewarmPrerenderReuseThenActivate \
  DISABLED_PrewarmPrerenderReuseThenActivate
#else
#define MAYBE_PrewarmPrerenderReuseThenActivate \
  PrewarmPrerenderReuseThenActivate
#endif
IN_PROC_BROWSER_TEST_F(PrerenderPrewarmDefaultSearchEngineTest,
                       MAYBE_PrewarmPrerenderReuseThenActivate) {
  // Navigate to an initial page.
  GURL url = embedded_test_server()->GetURL("/empty.html");
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));

  // Prerender the prewarm page.
  auto* prerender_manager =
      PrerenderManager::FromWebContents(GetActiveWebContents());
  EXPECT_TRUE(prerender_manager->MaybeStartPrewarmSearchResult());
  content::PrerenderHostId prewarm_host_id = GetPrewarmSearchResultHost();
  ASSERT_TRUE(prewarm_host_id);
  content::FrameTreeNodeId prewarm_frame_tree_node_id =
      prerender_helper()
          .GetPrerenderedMainFrameHost(prewarm_host_id)
          ->GetFrameTreeNodeId();
  ASSERT_TRUE(prewarm_frame_tree_node_id);
  prerender_helper().WaitForPrerenderLoadCompletion(prewarm_host_id);

  content::test::PrerenderHostObserver prerender_observer(
      *GetActiveWebContents(), prewarm_host_id);
  // Trigger a new prerender under the same site. The ?1 parameter
  // is added to create a different URL with the prewarm page.
  GURL prerender_url = embedded_test_server()->GetURL("/simple.html?1");
  content::PrerenderHostId prerender_host_id =
      prerender_helper().AddPrerender(prerender_url);
  prerender_observer.WaitForDestroyed();
  ASSERT_TRUE(prerender_observer.WasHostReused());
  content::FrameTreeNodeId prerender_frame_tree_node_id =
      prerender_helper()
          .GetPrerenderedMainFrameHost(prerender_host_id)
          ->GetFrameTreeNodeId();
  // Prerender reuses the prewarmed FrameTree, while PrerenderHost is
  // re-created.
  ASSERT_EQ(prewarm_frame_tree_node_id, prerender_frame_tree_node_id);
  ASSERT_NE(prewarm_host_id, prerender_host_id);

  // Activate
  content::TestActivationManager activation_manager(GetActiveWebContents(),
                                                    prerender_url);
  prerender_helper().NavigatePrimaryPageAsync(
      prerender_url, ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK));
  activation_manager.WaitForNavigationFinished();
  EXPECT_TRUE(activation_manager.was_activated());
}

IN_PROC_BROWSER_TEST_F(PrerenderPrewarmDefaultSearchEngineTest,
                       PrerenderReusePendingCommitPage) {
  // Navigate to an initial page.
  const GURL url = embedded_test_server()->GetURL("/empty.html");
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));

  // Prerender the prewarm page.
  auto* prerender_manager =
      PrerenderManager::FromWebContents(GetActiveWebContents());
  content::TestNavigationManager navigation_manager(GetActiveWebContents(),
                                                    prewarm_url_);
  EXPECT_TRUE(prerender_manager->MaybeStartPrewarmSearchResult());
  // Throttle the navigation to the prewarmed paged before commit.
  EXPECT_TRUE(navigation_manager.WaitForResponse());
  content::PrerenderHostId prewarm_host_id = GetPrewarmSearchResultHost();
  ASSERT_TRUE(prewarm_host_id);
  content::FrameTreeNodeId prewarm_frame_tree_node_id =
      prerender_helper()
          .GetPrerenderedMainFrameHost(prewarm_host_id)
          ->GetFrameTreeNodeId();
  ASSERT_TRUE(prewarm_frame_tree_node_id);

  // Resume the navigation of the previous prewarm page.
  navigation_manager.ResumeNavigation();
  // We intentionally do not wait for the navigation to finish here to test the
  // corner case of reusing a PrerenderHost waiting for the DidCommitNavigation
  // IPC call from the renderer.

  // Trigger a new prerender under the same site. The ?1 parameter
  // is added to create a different URL with the prewarm page.
  GURL prerender_url = embedded_test_server()->GetURL("/simple.html?1");
  content::TestNavigationManager new_navigation_manager(GetActiveWebContents(),
                                                        prerender_url);
  content::test::PrerenderHostObserver prerender_observer(
      *GetActiveWebContents(), prewarm_host_id);
  std::unique_ptr<content::PrerenderHandle> prerender_handle =
      prerender_helper().AddEmbedderTriggeredPrerenderAsync(
          prerender_url, content::PreloadingTriggerType::kEmbedder,
          prerender_utils::kDirectUrlInputMetricSuffix,
          ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
                                    ui::PAGE_TRANSITION_FROM_ADDRESS_BAR));
  EXPECT_TRUE(prerender_handle);
  prerender_observer.WaitForDestroyed();
  ASSERT_TRUE(prerender_observer.WasHostReused());

  // Wait for the previous navigation to finish after creating the new
  // PrerenderHost. Committing the previous navigation should not cause the
  // current prerender to fail.
  EXPECT_TRUE(navigation_manager.WaitForNavigationFinished());
  content::PrerenderHostId prerender_host_id =
      prerender_helper().GetHostForUrl(prerender_url);
  content::FrameTreeNodeId prerender_frame_tree_node_id =
      prerender_helper()
          .GetPrerenderedMainFrameHost(prerender_host_id)
          ->GetFrameTreeNodeId();
  // Prerender reuses the prewarmed FrameTree, while PrerenderHost is
  // re-created.
  ASSERT_EQ(prewarm_frame_tree_node_id, prerender_frame_tree_node_id);
  ASSERT_NE(prewarm_host_id, prerender_host_id);

  EXPECT_TRUE(new_navigation_manager.WaitForNavigationFinished());
}

IN_PROC_BROWSER_TEST_F(PrerenderPrewarmDefaultSearchEngineTest,
                       PrerenderReuseStillLoadingPage) {
  // Prerender the prewarm page.
  auto* prerender_manager =
      PrerenderManager::FromWebContents(GetActiveWebContents());
  prewarm_url_ = embedded_test_server()->GetURL("/with_delayed_css.html");
  prerender_manager->SetPrewarmUrlForTesting(prewarm_url_);
  // Navigate to an initial page.
  const GURL url = embedded_test_server()->GetURL("/empty.html");
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));

  // Prerender the prewarm page.
  content::TestNavigationManager navigation_manager(GetActiveWebContents(),
                                                    prewarm_url_);
  EXPECT_TRUE(prerender_manager->MaybeStartPrewarmSearchResult());
  content::PrerenderHostId prewarm_host_id = GetPrewarmSearchResultHost();
  ASSERT_TRUE(prewarm_host_id);
  content::FrameTreeNodeId prewarm_frame_tree_node_id =
      prerender_helper()
          .GetPrerenderedMainFrameHost(prewarm_host_id)
          ->GetFrameTreeNodeId();
  ASSERT_TRUE(prewarm_frame_tree_node_id);
  ASSERT_TRUE(navigation_manager.WaitForNavigationFinished());
  ASSERT_TRUE(navigation_manager.was_committed());
  ASSERT_TRUE(navigation_manager.was_successful());
  // The prewarm page will still be in loading state

  // Trigger a new prerender under the same site.
  GURL prerender_url = embedded_test_server()->GetURL("/simple.html");
  content::TestNavigationManager new_navigation_manager(GetActiveWebContents(),
                                                        prerender_url);
  content::test::PrerenderHostObserver prerender_observer(
      *GetActiveWebContents(), prewarm_host_id);
  std::unique_ptr<content::PrerenderHandle> prerender_handle =
      prerender_helper().AddEmbedderTriggeredPrerenderAsync(
          prerender_url, content::PreloadingTriggerType::kEmbedder,
          prerender_utils::kDirectUrlInputMetricSuffix,
          ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
                                    ui::PAGE_TRANSITION_FROM_ADDRESS_BAR));
  EXPECT_TRUE(prerender_handle);
  prerender_observer.WaitForDestroyed();
  ASSERT_TRUE(prerender_observer.WasHostReused());

  EXPECT_TRUE(new_navigation_manager.WaitForNavigationFinished());
  content::PrerenderHostId prerender_host_id =
      prerender_helper().GetHostForUrl(prerender_url);
  content::FrameTreeNodeId prerender_frame_tree_node_id =
      prerender_helper()
          .GetPrerenderedMainFrameHost(prerender_host_id)
          ->GetFrameTreeNodeId();
  // Prerender reuses the prewarmed FrameTree, while PrerenderHost is
  // re-created.
  ASSERT_EQ(prewarm_frame_tree_node_id, prerender_frame_tree_node_id);
  ASSERT_NE(prewarm_host_id, prerender_host_id);
  prerender_helper().WaitForPrerenderLoadCompletion(prerender_host_id);
}

// Tests that the SearchPrewarmProgressService correctly tracks the prewarm
// status when prewarming the default search engine, and resets when the
// prewarm is stopped.
IN_PROC_BROWSER_TEST_F(PrerenderPrewarmDefaultSearchEngineTest,
                       SearchPrewarmProgressService) {
  // Navigate to an initial page.
  GURL url = embedded_test_server()->GetURL("/empty.html");
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));

  auto* profile =
      Profile::FromBrowserContext(GetActiveWebContents()->GetBrowserContext());
  auto* service = SearchPrewarmProgressServiceFactory::GetForProfile(profile);
  ASSERT_TRUE(service);
  EXPECT_FALSE(service->HasOnGoingSearchPrewarm());

  // Prerender the prewarm page.
  auto* prerender_manager =
      PrerenderManager::FromWebContents(GetActiveWebContents());
  content::TestNavigationManager navigation_manager(GetActiveWebContents(),
                                                    prewarm_url_);
  EXPECT_TRUE(prerender_manager->MaybeStartPrewarmSearchResult());
  EXPECT_TRUE(service->HasOnGoingSearchPrewarm());

  auto host_id = GetPrewarmSearchResultHost();
  ASSERT_TRUE(host_id);
  EXPECT_TRUE(service->IsOnGoingSearchPrewarm(host_id));

  SearchPrewarmProgressTestObserver observer(service);
  EXPECT_FALSE(observer.was_notified());

  // Resume the navigation.
  EXPECT_TRUE(navigation_manager.WaitForResponse());
  navigation_manager.ResumeNavigation();
  prerender_helper().WaitForPrerenderLoadCompletion(host_id);

  observer.WaitForNotification();
  EXPECT_FALSE(service->HasOnGoingSearchPrewarm());
  EXPECT_FALSE(service->IsOnGoingSearchPrewarm(host_id));
}

// Tests that if the `PrerenderManager` is destroyed (by closing the tab) while
// a search prewarm is ongoing, the registered callbacks on
// `SearchPrewarmProgressService` will be correctly triggered.
IN_PROC_BROWSER_TEST_F(PrerenderPrewarmDefaultSearchEngineTest,
                       SearchPrewarmProgressPrerenderManagerDestroyed) {
  // Navigate to an initial page.
  GURL url = embedded_test_server()->GetURL("/empty.html");
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));

  auto* profile =
      Profile::FromBrowserContext(GetActiveWebContents()->GetBrowserContext());
  auto* service = SearchPrewarmProgressServiceFactory::GetForProfile(profile);
  ASSERT_TRUE(service);
  EXPECT_FALSE(service->HasOnGoingSearchPrewarm());

  // Create another web contents in a new tab.
  content::WebContents* web_contents2 = CreateNewTab();
  ASSERT_TRUE(web_contents2);
  PrerenderManager::CreateForWebContents(web_contents2);
  auto* prerender_manager2 = PrerenderManager::FromWebContents(web_contents2);
  prerender_manager2->SetPrewarmUrlForTesting(prewarm_url_);
  ASSERT_TRUE(content::NavigateToURL(web_contents2, url));

  // Prerender the prewarm page in the second web contents.
  content::TestNavigationManager navigation_manager2(web_contents2,
                                                     prewarm_url_);
  EXPECT_TRUE(prerender_manager2->MaybeStartPrewarmSearchResult());
  EXPECT_TRUE(service->HasOnGoingSearchPrewarm());

  auto host_id = prerender_helper().GetPrewarmSearchResultHost(prewarm_url_);
  ASSERT_TRUE(host_id);
  EXPECT_TRUE(service->IsOnGoingSearchPrewarm(host_id));
  SearchPrewarmProgressTestObserver observer(service);
  EXPECT_FALSE(observer.was_notified());

  // Destroy the tab.
  GetActiveWebContents()->Close();

  observer.WaitForNotification();
  EXPECT_FALSE(service->HasOnGoingSearchPrewarm());

  EXPECT_FALSE(service->IsOnGoingSearchPrewarm(host_id));
}

// Tests that `SearchPrewarmProgressService` handles multiple prewarms happening
// concurrently in different `WebContents` and the callback is triggered only
// after all prewarms finish.
IN_PROC_BROWSER_TEST_F(PrerenderPrewarmDefaultSearchEngineTest,
                       SearchPrewarmProgressServiceMultipleWebContents) {
  // Navigate to an initial page.
  GURL url = embedded_test_server()->GetURL("/empty.html");
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));

  auto* profile =
      Profile::FromBrowserContext(GetActiveWebContents()->GetBrowserContext());
  auto* service = SearchPrewarmProgressServiceFactory::GetForProfile(profile);
  ASSERT_TRUE(service);
  EXPECT_FALSE(service->HasOnGoingSearchPrewarm());

  content::WebContents* web_contents1 = GetActiveWebContents();

  // Prerender the prewarm page in the first tab.
  auto* prerender_manager = PrerenderManager::FromWebContents(web_contents1);
  content::TestNavigationManager navigation_manager(web_contents1,
                                                    prewarm_url_);
  EXPECT_TRUE(prerender_manager->MaybeStartPrewarmSearchResult());
  EXPECT_TRUE(service->HasOnGoingSearchPrewarm());

  auto host_id1 = prerender_helper().GetPrewarmSearchResultHost(prewarm_url_);
  ASSERT_TRUE(host_id1);
  EXPECT_TRUE(service->IsOnGoingSearchPrewarm(host_id1));

  // Create another web contents in a new tab.
  content::WebContents* web_contents2 = CreateNewTab();
  ASSERT_TRUE(web_contents2);
  PrerenderManager::CreateForWebContents(web_contents2);
  auto* prerender_manager2 = PrerenderManager::FromWebContents(web_contents2);
  GURL prewarm_url2 = embedded_test_server()->GetURL("/title1.html");
  prerender_manager2->SetPrewarmUrlForTesting(prewarm_url2);
  ASSERT_TRUE(content::NavigateToURL(web_contents2, url));

  // Prerender the prewarm page in the second tab.
  content::TestNavigationManager navigation_manager2(web_contents2,
                                                     prewarm_url2);
  EXPECT_TRUE(prerender_manager2->MaybeStartPrewarmSearchResult());
  EXPECT_TRUE(service->HasOnGoingSearchPrewarm());

  auto host_id2 = prerender_helper().GetPrewarmSearchResultHost(prewarm_url2);
  ASSERT_TRUE(host_id2);
  EXPECT_TRUE(service->IsOnGoingSearchPrewarm(host_id2));

  SearchPrewarmProgressTestObserver observer(service);
  EXPECT_FALSE(observer.was_notified());

  // Resume the navigation in the first tab.
  EXPECT_TRUE(navigation_manager.WaitForResponse());
  navigation_manager.ResumeNavigation();
  EXPECT_TRUE(navigation_manager.WaitForNavigationFinished());

  EXPECT_TRUE(service->HasOnGoingSearchPrewarm());
  EXPECT_FALSE(observer.was_notified());
  EXPECT_FALSE(service->IsOnGoingSearchPrewarm(host_id1));
  EXPECT_TRUE(service->IsOnGoingSearchPrewarm(host_id2));

  // Resume the navigation in the second tab.
  EXPECT_TRUE(navigation_manager2.WaitForResponse());
  navigation_manager2.ResumeNavigation();
  EXPECT_TRUE(navigation_manager2.WaitForNavigationFinished());

  observer.WaitForNotification();
  EXPECT_FALSE(service->HasOnGoingSearchPrewarm());
  EXPECT_FALSE(service->IsOnGoingSearchPrewarm(host_id1));
  EXPECT_FALSE(service->IsOnGoingSearchPrewarm(host_id2));
}

IN_PROC_BROWSER_TEST_F(PrerenderPrewarmDefaultSearchEngineTest,
                       EmbedderPrerenderCountLimitWithReuse) {
  // Navigate to an initial page.
  GURL url = embedded_test_server()->GetURL("/empty.html");
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));

  // Prerender the prewarm page.
  auto* prerender_manager =
      PrerenderManager::FromWebContents(GetActiveWebContents());
  EXPECT_TRUE(prerender_manager->MaybeStartPrewarmSearchResult());
  content::PrerenderHostId host_id = GetPrewarmSearchResultHost();
  ASSERT_TRUE(host_id);
  prerender_helper().WaitForPrerenderLoadCompletion(host_id);

  content::test::PrerenderHostObserver prerender_observer(
      *GetActiveWebContents(), host_id);
  // Trigger a new prerender under a new site.
  GURL prerender_url_1 =
      embedded_test_server()->GetURL("b.test", "/simple.html");
  std::unique_ptr<content::PrerenderHandle> prerender_handle_1 =
      prerender_helper().AddEmbedderTriggeredPrerenderAsync(
          prerender_url_1, content::PreloadingTriggerType::kEmbedder,
          prerender_utils::kDirectUrlInputMetricSuffix,
          ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
                                    ui::PAGE_TRANSITION_FROM_ADDRESS_BAR));
  EXPECT_TRUE(prerender_handle_1);
  content::test::PrerenderTestHelper::WaitForPrerenderLoadCompletion(
      *GetActiveWebContents(), prerender_url_1);

  // Now there will be 2 prerender pages from the embedder in the
  // PrerenderHostRegistry: The prewarm page and the prerendered page for
  // b.test. We have reached the 2-pages upper limit for the embedder triggered
  // prerenders.

  // Verify that a new prerender request to another site will fail.
  GURL prerender_url_2 =
      embedded_test_server()->GetURL("c.test", "/simple.html");
  std::unique_ptr<content::PrerenderHandle> prerender_handle_2 =
      prerender_helper().AddEmbedderTriggeredPrerenderAsync(
          prerender_url_2, content::PreloadingTriggerType::kEmbedder,
          prerender_utils::kDirectUrlInputMetricSuffix,
          ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
                                    ui::PAGE_TRANSITION_FROM_ADDRESS_BAR));
  EXPECT_FALSE(prerender_handle_2);

  // Verify that a new prerender request reusing the prewarm page will succeed.
  // The "?1" parameter is added to create a different URL with the prewarm
  // page.
  GURL prerender_url_3 = embedded_test_server()->GetURL("/simple.html?1");
  std::unique_ptr<content::PrerenderHandle> prerender_handle_3 =
      prerender_helper().AddEmbedderTriggeredPrerenderAsync(
          prerender_url_3, content::PreloadingTriggerType::kEmbedder,
          prerender_utils::kDirectUrlInputMetricSuffix,
          ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
                                    ui::PAGE_TRANSITION_FROM_ADDRESS_BAR));
  EXPECT_TRUE(prerender_handle_3);
  content::test::PrerenderTestHelper::WaitForPrerenderLoadCompletion(
      *GetActiveWebContents(), prerender_url_3);
  content::test::PrerenderTestHelper::WaitForPrerenderLoadCompletion(
      *GetActiveWebContents(), prerender_url_3);
}

class PrerenderFormSubmissionBrowserTest : public PrerenderBrowserTest {
 public:
  PrerenderFormSubmissionBrowserTest() {
    feature_list_.InitAndEnableFeature(
        blink::features::kPrerenderActivationByFormSubmission);
  }

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

IN_PROC_BROWSER_TEST_F(PrerenderFormSubmissionBrowserTest, UseCounter) {
  base::HistogramTester histogram_tester;

  // Navigate to an initial page.
  GURL url = embedded_test_server()->GetURL("/empty.html");
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));
  histogram_tester.ExpectBucketCount(
      "Blink.UseCounter.Features",
      blink::mojom::WebFeature::kPrerenderActivationByFormSubmission, 0);

  // Trigger prerender with form submission.
  GURL prerender_url = embedded_test_server()->GetURL("/simple.html?prerender");
  prerender_helper().AddPrerendersAsync(
      {prerender_url},
      /*eagerness=*/std::nullopt,
      /*no_vary_search_hint=*/std::nullopt,
      /*target_hint=*/std::string(),
      /*ruleset_tag=*/std::nullopt,
      /*world_id=*/content::ISOLATED_WORLD_ID_GLOBAL,
      /*form_submission=*/true);
  content::test::PrerenderTestHelper::WaitForPrerenderLoadCompletion(
      *GetActiveWebContents(), prerender_url);

  histogram_tester.ExpectBucketCount(
      "Blink.UseCounter.Features",
      blink::mojom::WebFeature::kPrerenderActivationByFormSubmission, 1);
}

// Verifies that HTTP to HTTP, prerender form submission can work as expected
// without being blocked.
IN_PROC_BROWSER_TEST_F(PrerenderFormSubmissionBrowserTest, HTTPFormActivation) {
  base::HistogramTester histogram_tester;

  // Navigate to an initial page.
  GURL url = embedded_test_server()->GetURL("/empty.html");
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));

  // Trigger prerender with form submission.
  GURL prerender_url = embedded_test_server()->GetURL("/simple.html?");
  content::TestActivationManager activation_manager(GetActiveWebContents(),
                                                    prerender_url);
  prerender_helper().AddPrerendersAsync(
      {prerender_url},
      /*eagerness=*/std::nullopt,
      /*no_vary_search_hint=*/std::nullopt,
      /*target_hint=*/std::string(),
      /*ruleset_tag=*/std::nullopt,
      /*world_id=*/content::ISOLATED_WORLD_ID_GLOBAL,
      /*form_submission=*/true);
  content::test::PrerenderTestHelper::WaitForPrerenderLoadCompletion(
      *GetActiveWebContents(), prerender_url);

  ASSERT_TRUE(content::ExecJs(GetActiveWebContents()->GetPrimaryMainFrame(),
                              content::JsReplace(R"(
    const form = document.createElement('form');
                    form.action = $1;
    document.body.appendChild(form);
    form.submit();
    )",
                                                 prerender_url)));
  activation_manager.WaitForNavigationFinished();
  EXPECT_TRUE(activation_manager.was_activated());
}

// Verifies that a search form will not be blocked.
IN_PROC_BROWSER_TEST_F(PrerenderFormSubmissionBrowserTest,
                       SearchableFormActivation) {
  base::HistogramTester histogram_tester;

  // Navigate to an initial page.
  GURL url = embedded_test_server()->GetURL("/empty.html");
  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));

  // Trigger prerender with form submission, and the query parameters are the
  // results of the form data. The case is constructed in a way to make the form
  // identified as searchable.
  GURL prerender_url =
      embedded_test_server()->GetURL("/simple.html?hl=en&q=test");
  content::TestActivationManager activation_manager(GetActiveWebContents(),
                                                    prerender_url);
  prerender_helper().AddPrerendersAsync(
      {prerender_url},
      /*eagerness=*/std::nullopt,
      /*no_vary_search_hint=*/std::nullopt,
      /*target_hint=*/std::string(),
      /*ruleset_tag=*/std::nullopt,
      /*world_id=*/content::ISOLATED_WORLD_ID_GLOBAL,
      /*form_submission=*/true);
  content::test::PrerenderTestHelper::WaitForPrerenderLoadCompletion(
      *GetActiveWebContents(), prerender_url);

  // The form submission script is constructed in a way to be identified as
  // searchable by the heuristic logic in `blink::WebSearchableFormData`.
  ASSERT_TRUE(content::ExecJs(GetActiveWebContents()->GetPrimaryMainFrame(),
                              content::JsReplace(R"(
    const form = document.createElement('form');
    form.action = $1;
    const htmlString = `
        <input type="hidden" name="hl" value="en">
        <input type="text" name="q" value="test">
        <input type="submit" name="btnM" value="Mock Search">
    `;
    form.insertAdjacentHTML('beforeend', htmlString);
    document.body.appendChild(form);
    form.submit();
    )",
                                                 prerender_url)));
  activation_manager.WaitForNavigationFinished();
  EXPECT_TRUE(activation_manager.was_activated());
}

}  // namespace
