// 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/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/scoped_prewarm_feature_list.h"
#include "chrome/browser/profiles/profile.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.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 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::FrameTreeNodeId 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/1490582.
#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::FrameTreeNodeId 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 =
      content::WebContents::FromFrameTreeNodeId(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);
}

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::FrameTreeNodeId 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);
}

// Tests that DevTools open overrides PreloadingConfig's holdback.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, 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::FrameTreeNodeId 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::FrameTreeNodeId 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::FrameTreeNodeId 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::FrameTreeNodeId 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::FrameTreeNodeId 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 =
      content::WebContents::FromFrameTreeNodeId(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(),
                                     GURL(chrome::kChromeUINewTabURL)));
  GURL prerender_url = GetUrl("/simple.html");

  auto* ntp_preload_manager =
      NewTabPagePreloadPipelineManager::GetOrCreateForWebContents(
          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(),
                                     GURL(chrome::kChromeUINewTabURL)));
  GURL prerender_url = embedded_test_server()->GetURL("/simple.html?prerender");

  auto* ntp_preload_manager =
      NewTabPagePreloadPipelineManager::GetOrCreateForWebContents(
          GetActiveWebContents());
  ntp_preload_manager->StartPrerender(
      prerender_url,
      chrome_preloading_predictor::kMouseHoverOrMouseDownOnNewTabPage);
  base::RunLoop().RunUntilIdle();
  content::FrameTreeNodeId 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(),
                                     GURL(chrome::kChromeUINewTabURL)));
  GURL prerender_url = GetUrl("/simple.html");

  auto* ntp_preload_manager =
      NewTabPagePreloadPipelineManager::GetOrCreateForWebContents(
          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(),
                                     GURL(chrome::kChromeUINewTabURL)));
  GURL prerender_url = GetUrl("/simple.html?prerender");

  auto* ntp_preload_manager =
      NewTabPagePreloadPipelineManager::GetOrCreateForWebContents(
          GetActiveWebContents());

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

  content::FrameTreeNodeId 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 (!base::Contains(request.GetURL().path(), "delayed_stylesheet.css")) {
      return nullptr;
    }
    return std::make_unique<content::SlowHttpResponse>(
        content::SlowHttpResponse::NoResponse());
  }

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

 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);
}

IN_PROC_BROWSER_TEST_F(PrerenderPrewarmDefaultSearchEngineTest,
                       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::FrameTreeNodeId 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 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");
  prerender_helper().AddPrerender(prerender_url);
  prerender_observer.WaitForDestroyed();
  ASSERT_TRUE(prerender_observer.WasHostReused());
  auto reuse_host_id = prerender_helper().GetHostForUrl(prerender_url);
  ASSERT_EQ(host_id, reuse_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::FrameTreeNodeId host_id = GetPrewarmSearchResultHost();
  ASSERT_TRUE(host_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(), 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());
  auto reuse_host_id = prerender_helper().GetHostForUrl(prerender_url);
  ASSERT_EQ(host_id, reuse_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::FrameTreeNodeId host_id = GetPrewarmSearchResultHost();
  ASSERT_TRUE(host_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(), 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());
  auto reuse_host_id = prerender_helper().GetHostForUrl(prerender_url);
  ASSERT_EQ(host_id, reuse_host_id);
  prerender_helper().WaitForPrerenderLoadCompletion(reuse_host_id);
}

}  // namespace
