// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/metrics/statistics_recorder.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/threading/platform_thread.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/browsing_data/chrome_browsing_data_remover_constants.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/history/history_test_utils.h"
#include "chrome/browser/predictors/autocomplete_action_predictor.h"
#include "chrome/browser/predictors/autocomplete_action_predictor_factory.h"
#include "chrome/browser/prefetch/no_state_prefetch/no_state_prefetch_manager_factory.h"
#include "chrome/browser/prefetch/no_state_prefetch/prerender_test_utils.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/task_manager/task_manager_browsertest_util.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/location_bar/location_bar.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/content_settings/core/browser/cookie_settings.h"
#include "components/content_settings/core/common/pref_names.h"
#include "components/embedder_support/switches.h"
#include "components/no_state_prefetch/browser/no_state_prefetch_handle.h"
#include "components/no_state_prefetch/browser/no_state_prefetch_manager.h"
#include "components/omnibox/browser/omnibox_edit_model.h"
#include "components/omnibox/browser/omnibox_view.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/browsing_data_remover.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/result_codes.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/back_forward_cache_util.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/browsing_data_remover_test_util.h"
#include "content/public/test/no_renderer_crashes_assertion.h"
#include "content/public/test/url_loader_interceptor.h"
#include "content/public/test/url_loader_monitor.h"
#include "net/base/escape.h"
#include "net/base/features.h"
#include "net/base/load_flags.h"
#include "net/base/request_priority.h"
#include "net/cookies/cookie_store.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/request_handler_util.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/mojom/cookie_manager.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/chrome_debug_urls.h"
#include "third_party/blink/public/common/features.h"

using prerender::test_utils::DestructionWaiter;
using prerender::test_utils::TestPrerender;
using task_manager::browsertest_util::WaitForTaskManagerRows;

namespace {

const char kExpectedPurposeHeaderOnPrefetch[] = "Purpose";

std::string CreateServerRedirect(const std::string& dest_url) {
  const char* const kServerRedirectBase = "/server-redirect?";
  return kServerRedirectBase + net::EscapeQueryParamValue(dest_url, false);
}

// This is the public key of tools/origin_trials/eftest.key, used to validate
// origin trial tokens generated by tools/origin_trials/generate_token.py.
static constexpr char kOriginTrialPublicKeyForTesting[] =
    "dRCs+TocuKkocNKa0AtZ4awrt9XKH2SQCI6o4FY6BNA=";

}  // namespace

namespace prerender {

const char k302RedirectPage[] = "/prerender/302_redirect.html";
const char kPrefetchCookiePage[] = "/prerender/cookie.html";
const char kPrefetchFromSubframe[] = "/prerender/prefetch_from_subframe.html";
const char kPrefetchImagePage[] = "/prerender/prefetch_image.html";
const char kPrefetchJpeg[] = "/prerender/image.jpeg";
const char kPrefetchLoaderPath[] = "/prerender/prefetch_loader.html";
const char kPrefetchLoopPage[] = "/prerender/prefetch_loop.html";
const char kPrefetchMetaCSP[] = "/prerender/prefetch_meta_csp.html";
const char kPrefetchNostorePage[] = "/prerender/prefetch_nostore_page.html";
const char kPrefetchPage[] = "/prerender/prefetch_page.html";
const char kPrefetchPageWithFragment[] =
    "/prerender/prefetch_page.html#fragment";
const char kPrefetchPage2[] = "/prerender/prefetch_page2.html";
const char kPrefetchPageBigger[] = "/prerender/prefetch_page_bigger.html";
const char kPrefetchPageMultipleResourceTypes[] =
    "/prerender/prefetch_page_multiple_resource_types.html";
const char kPrefetchPng[] = "/prerender/image.png";
const char kPrefetchPng2[] = "/prerender/image2.png";
const char kPrefetchPngRedirect[] = "/prerender/image-redirect.png";
const char kPrefetchRecursePage[] = "/prerender/prefetch_recurse.html";
const char kPrefetchResponseHeaderCSP[] =
    "/prerender/prefetch_response_csp.html";
const char kPrefetchScript[] = "/prerender/prefetch.js";
const char kPrefetchScript2[] = "/prerender/prefetch2.js";
const char kPrefetchCss[] = "/prerender/style.css";
const char kPrefetchFont[] = "/prerender/font.woff";
const char kPrefetchDownloadFile[] = "/download-test1.lib";
const char kPrefetchSubresourceRedirectPage[] =
    "/prerender/prefetch_subresource_redirect.html";
const char kServiceWorkerLoader[] = "/prerender/service_worker.html";
const char kHungPrerenderPage[] = "/prerender/hung_prerender_page.html";

// A navigation observer to wait on either a new load or a swap of a
// WebContents. On swap, if the new WebContents is still loading, wait for that
// load to complete as well. Note that the load must begin after the observer is
// attached.
class NavigationOrSwapObserver : public content::WebContentsObserver,
                                 public TabStripModelObserver {
 public:
  // Waits for either a new load or a swap of |tab_strip_model|'s active
  // WebContents.
  NavigationOrSwapObserver(TabStripModel* tab_strip_model,
                           content::WebContents* web_contents)
      : content::WebContentsObserver(web_contents),
        tab_strip_model_(tab_strip_model),
        did_start_loading_(false),
        number_of_loads_(1) {
    EXPECT_NE(TabStripModel::kNoTab,
              tab_strip_model->GetIndexOfWebContents(web_contents));
    tab_strip_model_->AddObserver(this);
  }

  // Waits for either |number_of_loads| loads or a swap of |tab_strip_model|'s
  // active WebContents.
  NavigationOrSwapObserver(TabStripModel* tab_strip_model,
                           content::WebContents* web_contents,
                           int number_of_loads)
      : content::WebContentsObserver(web_contents),
        tab_strip_model_(tab_strip_model),
        did_start_loading_(false),
        number_of_loads_(number_of_loads) {
    EXPECT_NE(TabStripModel::kNoTab,
              tab_strip_model->GetIndexOfWebContents(web_contents));
    tab_strip_model_->AddObserver(this);
  }

  ~NavigationOrSwapObserver() override {
    tab_strip_model_->RemoveObserver(this);
  }

  void set_did_start_loading() { did_start_loading_ = true; }

  void Wait() { loop_.Run(); }

  // content::WebContentsObserver implementation:
  void DidStartLoading() override { did_start_loading_ = true; }
  void DidStopLoading() override {
    if (!did_start_loading_)
      return;
    number_of_loads_--;
    if (number_of_loads_ == 0)
      loop_.Quit();
  }

  // TabStripModelObserver implementation:
  void OnTabStripModelChanged(
      TabStripModel* tab_strip_model,
      const TabStripModelChange& change,
      const TabStripSelectionChange& selection) override {
    if (change.type() != TabStripModelChange::kReplaced)
      return;

    auto* replace = change.GetReplace();
    if (replace->old_contents != web_contents())
      return;

    // Switch to observing the new WebContents.
    Observe(replace->new_contents);
    if (replace->new_contents->IsLoading()) {
      // If the new WebContents is still loading, wait for it to complete.
      // Only one load post-swap is supported.
      did_start_loading_ = true;
      number_of_loads_ = 1;
    } else {
      loop_.Quit();
    }
  }

 private:
  raw_ptr<TabStripModel> tab_strip_model_;
  bool did_start_loading_;
  int number_of_loads_;
  base::RunLoop loop_;
};

// Waits for a new tab to open and a navigation or swap in it.
class NewTabNavigationOrSwapObserver : public TabStripModelObserver,
                                       public BrowserListObserver {
 public:
  NewTabNavigationOrSwapObserver() {
    BrowserList::AddObserver(this);
    for (const Browser* browser : *BrowserList::GetInstance())
      browser->tab_strip_model()->AddObserver(this);
  }

  NewTabNavigationOrSwapObserver(const NewTabNavigationOrSwapObserver&) =
      delete;
  NewTabNavigationOrSwapObserver& operator=(
      const NewTabNavigationOrSwapObserver&) = delete;

  ~NewTabNavigationOrSwapObserver() override {
    BrowserList::RemoveObserver(this);
  }

  void Wait() {
    new_tab_run_loop_.Run();
    swap_observer_->Wait();
  }

  // TabStripModelObserver:
  void OnTabStripModelChanged(
      TabStripModel* tab_strip_model,
      const TabStripModelChange& change,
      const TabStripSelectionChange& selection) override {
    if (change.type() != TabStripModelChange::kInserted || swap_observer_)
      return;

    content::WebContents* new_tab = change.GetInsert()->contents[0].contents;
    swap_observer_ =
        std::make_unique<NavigationOrSwapObserver>(tab_strip_model, new_tab);
    swap_observer_->set_did_start_loading();

    new_tab_run_loop_.Quit();
  }

  // BrowserListObserver:
  void OnBrowserAdded(Browser* browser) override {
    browser->tab_strip_model()->AddObserver(this);
  }

 private:
  base::RunLoop new_tab_run_loop_;
  std::unique_ptr<NavigationOrSwapObserver> swap_observer_;
};

class NoStatePrefetchBrowserTest
    : public test_utils::PrerenderInProcessBrowserTest {
 public:
  NoStatePrefetchBrowserTest() {}

  NoStatePrefetchBrowserTest(const NoStatePrefetchBrowserTest&) = delete;
  NoStatePrefetchBrowserTest& operator=(const NoStatePrefetchBrowserTest&) =
      delete;

  void SetUpDefaultCommandLine(base::CommandLine* command_line) override {
    test_utils::PrerenderInProcessBrowserTest::SetUpDefaultCommandLine(
        command_line);
    command_line->AppendSwitchASCII(embedder_support::kOriginTrialPublicKey,
                                    kOriginTrialPublicKeyForTesting);
    command_line->AppendSwitchASCII(switches::kEnableBlinkFeatures,
                                    "SpeculationRulesPrefetchProxy");
  }

  void SetUpOnMainThread() override {
    test_utils::PrerenderInProcessBrowserTest::SetUpOnMainThread();
    host_resolver()->AddRule("*", "127.0.0.1");
  }

  void OverrideNoStatePrefetchManagerTimeTicks() {
    // The default zero time causes the prerender manager to do strange things.
    clock_.Advance(base::Seconds(1));
    GetNoStatePrefetchManager()->SetTickClockForTesting(&clock_);
  }

 protected:
  // Loads kPrefetchLoaderPath and specifies |target_url| as a query param. The
  // |loader_url| looks something like:
  // http://127.0.0.1:port_number/prerender/prefetch_loader.html?replace_text=\
  // UkVQTEFDRV9XSVRIX1BSRUZFVENIX1VSTA==:aHR0cDovL3d3dy52dlci5odG1s.
  // When the embedded test server receives the request, it uses the specified
  // query params to replace the "REPLACE_WITH_PREFETCH_URL" string in the HTML
  // response with |target_url|. See method UpdateReplacedText() from embedded
  // test server.
  std::unique_ptr<TestPrerender> PrefetchFromURL(
      const GURL& target_url,
      FinalStatus expected_final_status,
      int expected_number_of_loads = 0) {
    GURL loader_url = ServeLoaderURL(
        kPrefetchLoaderPath, "REPLACE_WITH_PREFETCH_URL", target_url, "");
    std::vector<FinalStatus> expected_final_status_queue(1,
                                                         expected_final_status);
    std::vector<std::unique_ptr<TestPrerender>> prerenders =
        NavigateWithPrerenders(loader_url, expected_final_status_queue);
    prerenders[0]->WaitForLoads(0);

    if (ShouldAbortPrerenderBeforeSwap(expected_final_status_queue.front())) {
      // The prefetcher will abort on its own. Assert it does so correctly.
      prerenders[0]->WaitForStop();
      EXPECT_FALSE(prerenders[0]->contents());
    } else {
      // Otherwise, check that it prefetched correctly.
      test_utils::TestNoStatePrefetchContents* no_state_prefetch_contents =
          prerenders[0]->contents();
      if (no_state_prefetch_contents) {
        EXPECT_EQ(FINAL_STATUS_UNKNOWN,
                  no_state_prefetch_contents->final_status());
      }
    }

    return std::move(prerenders[0]);
  }

  // Returns true if the prerender is expected to abort on its own, before
  // attempting to swap it.
  bool ShouldAbortPrerenderBeforeSwap(FinalStatus status) {
    switch (status) {
      case FINAL_STATUS_USED:
      case FINAL_STATUS_APP_TERMINATING:
      case FINAL_STATUS_PROFILE_DESTROYED:
      case FINAL_STATUS_CACHE_OR_HISTORY_CLEARED:
      // We'll crash the renderer after it's loaded.
      case FINAL_STATUS_RENDERER_CRASHED:
      case FINAL_STATUS_CANCELLED:
        return false;
      default:
        return true;
    }
  }

  std::unique_ptr<TestPrerender> PrefetchFromFile(
      const std::string& html_file,
      FinalStatus expected_final_status,
      int expected_number_of_loads = 0) {
    return PrefetchFromURL(src_server()->GetURL(MakeAbsolute(html_file)),
                           expected_final_status, expected_number_of_loads);
  }

  // Returns length of |no_state_prefetch_manager_|'s history, or SIZE_MAX on
  // failure.
  size_t GetHistoryLength() const {
    std::unique_ptr<base::DictionaryValue> prerender_dict =
        GetNoStatePrefetchManager()->CopyAsValue();
    if (!prerender_dict)
      return std::numeric_limits<size_t>::max();
    base::ListValue* history_list;
    if (!prerender_dict->GetList("history", &history_list))
      return std::numeric_limits<size_t>::max();
    return history_list->GetList().size();
  }

  // Clears the specified data using BrowsingDataRemover.
  void ClearBrowsingData(Browser* browser, uint64_t remove_mask) {
    content::BrowsingDataRemover* remover =
        browser->profile()->GetBrowsingDataRemover();
    content::BrowsingDataRemoverCompletionObserver observer(remover);
    remover->RemoveAndReply(
        base::Time(), base::Time::Max(), remove_mask,
        content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB, &observer);
    observer.BlockUntilCompletion();
    // BrowsingDataRemover deletes itself.
  }

  // Opens the prerendered page using javascript functions in the loader
  // page. |javascript_function_name| should be a 0 argument function which is
  // invoked. |new_web_contents| is true if the navigation is expected to
  // happen in a new WebContents via OpenURL.
  void OpenURLWithJSImpl(const std::string& javascript_function_name,
                         const GURL& url,
                         const GURL& ping_url,
                         bool new_web_contents) const {
    content::WebContents* web_contents = GetActiveWebContents();
    content::RenderFrameHost* render_frame_host = web_contents->GetMainFrame();
    // Extra arguments in JS are ignored.
    std::string javascript =
        base::StringPrintf("%s('%s', '%s')", javascript_function_name.c_str(),
                           url.spec().c_str(), ping_url.spec().c_str());

    if (new_web_contents) {
      NewTabNavigationOrSwapObserver observer;
      render_frame_host->ExecuteJavaScriptWithUserGestureForTests(
          base::ASCIIToUTF16(javascript));
      observer.Wait();
    } else {
      NavigationOrSwapObserver observer(current_browser()->tab_strip_model(),
                                        web_contents);
      render_frame_host->ExecuteJavaScriptForTests(
          base::ASCIIToUTF16(javascript), base::NullCallback());
      observer.Wait();
    }
  }

  void OpenDestURLViaClickNewWindow(GURL& dest_url) const {
    OpenURLWithJSImpl("ShiftClick", dest_url, GURL(), true);
  }

  void OpenDestURLViaClickNewForegroundTab(GURL& dest_url) const {
#if BUILDFLAG(IS_MAC)
    OpenURLWithJSImpl("MetaShiftClick", dest_url, GURL(), true);
#else
    OpenURLWithJSImpl("CtrlShiftClick", dest_url, GURL(), true);
#endif
  }

  base::SimpleTestTickClock clock_;

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

class NoStatePrefetchBrowserTestHttpCache
    : public NoStatePrefetchBrowserTest,
      public testing::WithParamInterface<bool> {
 protected:
  void SetUp() override {
    bool split_cache_by_network_isolation_key = GetParam();
    if (split_cache_by_network_isolation_key) {
      feature_list_.InitAndEnableFeature(
          net::features::kSplitCacheByNetworkIsolationKey);
    } else {
      feature_list_.InitAndDisableFeature(
          net::features::kSplitCacheByNetworkIsolationKey);
    }

    NoStatePrefetchBrowserTest::SetUp();
  }

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

using NoStatePrefetchBrowserTestHttpCache_DefaultAndAppendFrameOrigin =
    NoStatePrefetchBrowserTestHttpCache;

// Test that the network isolation key is correctly populated during a prefetch.
IN_PROC_BROWSER_TEST_P(
    NoStatePrefetchBrowserTestHttpCache_DefaultAndAppendFrameOrigin,
    PrefetchTwoCrossOriginFrames) {
  GURL image_src =
      embedded_test_server()->GetURL("/prerender/cacheable_image.png");
  base::StringPairs replacement_text_img_src;
  replacement_text_img_src.push_back(
      std::make_pair("IMAGE_SRC", image_src.spec()));
  std::string iframe_path = net::test_server::GetFilePathWithReplacements(
      "/prerender/one_image.html", replacement_text_img_src);

  GURL iframe_src_1 = embedded_test_server()->GetURL("www.a.com", iframe_path);
  GURL iframe_src_2 = embedded_test_server()->GetURL("www.b.com", iframe_path);

  base::StringPairs replacement_text_iframe_src;
  replacement_text_iframe_src.push_back(
      std::make_pair("IFRAME_1_SRC", iframe_src_1.spec()));
  replacement_text_iframe_src.push_back(
      std::make_pair("IFRAME_2_SRC", iframe_src_2.spec()));
  std::string prerender_path = net::test_server::GetFilePathWithReplacements(
      "/prerender/two_iframes.html", replacement_text_iframe_src);
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      current_browser(), src_server()->GetURL(prerender_path)));

  WaitForRequestCount(image_src, 2);
}

INSTANTIATE_TEST_SUITE_P(
    All,
    NoStatePrefetchBrowserTestHttpCache_DefaultAndAppendFrameOrigin,
    ::testing::Values(true));

// Checks that a page is correctly prefetched in the case of a
// <link rel=prerender> tag and the JavaScript on the page is not executed.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchSimple) {
  std::unique_ptr<TestPrerender> test_prerender =
      PrefetchFromFile(kPrefetchPage, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);

  // Verify that the page load did not happen.
  test_prerender->WaitForLoads(0);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPage), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript2), 0);
}

// Checks that prefetching is not stopped forever by aggressive background load
// limits.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchBigger) {
  std::unique_ptr<TestPrerender> test_prerender = PrefetchFromFile(
      kPrefetchPageBigger, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);

  WaitForRequestCount(src_server()->GetURL(kPrefetchPageBigger), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchJpeg), 1);
  // The |kPrefetchPng| is requested twice because the |kPrefetchPngRedirect|
  // redirects to it.
  WaitForRequestCount(src_server()->GetURL(kPrefetchPng), 2);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPng2), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPngRedirect), 1);
}

using NoStatePrefetchBrowserTestHttpCache_DefaultAndDoubleKeyedHttpCache =
    NoStatePrefetchBrowserTestHttpCache;

// Checks that a page load following a prefetch reuses preload-scanned resources
// and link rel 'prerender' main resource from cache without failing over to
// network.
IN_PROC_BROWSER_TEST_P(
    NoStatePrefetchBrowserTestHttpCache_DefaultAndDoubleKeyedHttpCache,
    LoadAfterPrefetch) {
  {
    std::unique_ptr<TestPrerender> test_prerender = PrefetchFromFile(
        kPrefetchPageBigger, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
    WaitForRequestCount(src_server()->GetURL(kPrefetchPageBigger), 1);
    WaitForRequestCount(src_server()->GetURL(kPrefetchJpeg), 1);
    WaitForRequestCount(src_server()->GetURL(kPrefetchPng2), 1);
  }
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      current_browser(), src_server()->GetURL(kPrefetchPageBigger)));
  // Check that the request counts did not increase.
  WaitForRequestCount(src_server()->GetURL(kPrefetchPageBigger), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchJpeg), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPng2), 1);
}

// Checks that a page load following a cross origin prefetch reuses
// preload-scanned resources and link rel 'prerender' main resource
// from cache without failing over to network.
IN_PROC_BROWSER_TEST_P(
    NoStatePrefetchBrowserTestHttpCache_DefaultAndDoubleKeyedHttpCache,
    LoadAfterPrefetchCrossOrigin) {
  static const std::string kSecondaryDomain = "www.foo.com";
  GURL cross_domain_url =
      embedded_test_server()->GetURL(kSecondaryDomain, kPrefetchPageBigger);

  PrefetchFromURL(cross_domain_url, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPageBigger), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchJpeg), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPng2), 1);

  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(current_browser(), cross_domain_url));
  // Check that the request counts did not increase.
  WaitForRequestCount(src_server()->GetURL(kPrefetchPageBigger), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchJpeg), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPng2), 1);
}

INSTANTIATE_TEST_SUITE_P(
    All,
    NoStatePrefetchBrowserTestHttpCache_DefaultAndDoubleKeyedHttpCache,
    ::testing::Bool());

// Checks that the expected resource types are fetched via NoState Prefetch.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchAllResourceTypes) {
  std::unique_ptr<TestPrerender> test_prerender =
      PrefetchFromFile(kPrefetchPageMultipleResourceTypes,
                       FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);

  // Verify that the page load did not happen.
  test_prerender->WaitForLoads(0);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPageMultipleResourceTypes),
                      1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript2), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPng), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchCss), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchFont), 1);
}

// Test and Test Class for lightweight prefetch under the HTML configuration.
class HTMLOnlyNoStatePrefetchBrowserTest : public NoStatePrefetchBrowserTest {
 public:
  void SetUp() override {
    std::map<std::string, std::string> parameters;
    parameters["html_only"] = "true";
    feature_list_.InitWithFeaturesAndParameters(
        {{blink::features::kLightweightNoStatePrefetch, parameters}}, {});
    NoStatePrefetchBrowserTest::SetUp();
  }

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

// Checks that the expected resource types are fetched via NoState Prefetch.
IN_PROC_BROWSER_TEST_F(HTMLOnlyNoStatePrefetchBrowserTest, PrefetchHTMLOnly) {
  std::unique_ptr<TestPrerender> test_prerender =
      PrefetchFromFile(kPrefetchPageMultipleResourceTypes,
                       FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);

  // Verify that the page load did not happen.
  test_prerender->WaitForLoads(0);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPageMultipleResourceTypes),
                      1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript), 0);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript2), 0);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPng), 0);
  WaitForRequestCount(src_server()->GetURL(kPrefetchCss), 0);
  WaitForRequestCount(src_server()->GetURL(kPrefetchFont), 0);
}

// Test and Test Class for lightweight prefetch under the HTML+CSS
// configuration.
class HTMLCSSNoStatePrefetchBrowserTest : public NoStatePrefetchBrowserTest {
 public:
  void SetUp() override {
    std::map<std::string, std::string> parameters;
    parameters["skip_script"] = "true";
    parameters["skip_other"] = "true";
    feature_list_.InitWithFeaturesAndParameters(
        {{blink::features::kLightweightNoStatePrefetch, parameters}}, {});
    NoStatePrefetchBrowserTest::SetUp();
  }

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

// Checks that the expected resource types are fetched via NoState Prefetch.
IN_PROC_BROWSER_TEST_F(HTMLCSSNoStatePrefetchBrowserTest, PrefetchHTMLCSS) {
  std::unique_ptr<TestPrerender> test_prerender =
      PrefetchFromFile(kPrefetchPageMultipleResourceTypes,
                       FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);

  // Verify that the page load did not happen.
  test_prerender->WaitForLoads(0);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPageMultipleResourceTypes),
                      1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript), 0);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript2), 0);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPng), 0);
  WaitForRequestCount(src_server()->GetURL(kPrefetchCss), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchFont), 0);
}

// Test and Test Class for lightweight prefetch under the HTML+CSS+SyncScript
// configuration.
class HTMLCSSSyncScriptNoStatePrefetchBrowserTest
    : public NoStatePrefetchBrowserTest {
 public:
  void SetUp() override {
    std::map<std::string, std::string> parameters;
    parameters["skip_other"] = "true";
    parameters["skip_async_script"] = "true";
    feature_list_.InitWithFeaturesAndParameters(
        {{blink::features::kLightweightNoStatePrefetch, parameters}}, {});
    NoStatePrefetchBrowserTest::SetUp();
  }

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

// Checks that the expected resource types are fetched via NoState Prefetch.
IN_PROC_BROWSER_TEST_F(HTMLCSSSyncScriptNoStatePrefetchBrowserTest,
                       PrefetchHTMLCSSSyncScript) {
  std::unique_ptr<TestPrerender> test_prerender =
      PrefetchFromFile(kPrefetchPageMultipleResourceTypes,
                       FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);

  // Verify that the page load did not happen.
  test_prerender->WaitForLoads(0);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPageMultipleResourceTypes),
                      1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript2), 0);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPng), 0);
  WaitForRequestCount(src_server()->GetURL(kPrefetchCss), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchFont), 0);
}

// Test and Test Class for lightweight prefetch under the
// HTML+CSS+SyncScript+Font configuration.
class HTMLCSSSyncScriptFontNoStatePrefetchBrowserTest
    : public NoStatePrefetchBrowserTest {
 public:
  void SetUp() override {
    std::map<std::string, std::string> parameters;
    parameters["skip_other"] = "true";
    parameters["skip_async_script"] = "true";
    feature_list_.InitWithFeaturesAndParameters(
        {{blink::features::kLightweightNoStatePrefetch, parameters}}, {});
    NoStatePrefetchBrowserTest::SetUp();
  }

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

// Checks that the expected resource types are fetched via NoState Prefetch.
IN_PROC_BROWSER_TEST_F(HTMLCSSSyncScriptFontNoStatePrefetchBrowserTest,
                       PrefetchHTMLCSSSyncScript) {
  std::unique_ptr<TestPrerender> test_prerender =
      PrefetchFromFile(kPrefetchPageMultipleResourceTypes,
                       FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);

  // Verify that the page load did not happen.
  test_prerender->WaitForLoads(0);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPageMultipleResourceTypes),
                      1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript2), 0);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPng), 0);
  WaitForRequestCount(src_server()->GetURL(kPrefetchCss), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchFont), 0);
}

// Test and Test Class for lightweight prefetch under the HTML+CSS+Script
// configuration.
class HTMLCSSScriptNoStatePrefetchBrowserTest
    : public NoStatePrefetchBrowserTest {
 public:
  void SetUp() override {
    std::map<std::string, std::string> parameters;
    parameters["skip_other"] = "true";
    parameters["skip_async_script"] = "false";
    feature_list_.InitWithFeaturesAndParameters(
        {{blink::features::kLightweightNoStatePrefetch, parameters}}, {});
    NoStatePrefetchBrowserTest::SetUp();
  }

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

// Checks that the expected resource types are fetched via NoState Prefetch.
IN_PROC_BROWSER_TEST_F(HTMLCSSScriptNoStatePrefetchBrowserTest,
                       PrefetchHTMLCSSScript) {
  std::unique_ptr<TestPrerender> test_prerender =
      PrefetchFromFile(kPrefetchPageMultipleResourceTypes,
                       FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);

  // Verify that the page load did not happen.
  test_prerender->WaitForLoads(0);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPageMultipleResourceTypes),
                      1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript2), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPng), 0);
  WaitForRequestCount(src_server()->GetURL(kPrefetchCss), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchFont), 0);
}

void GetCookieCallback(base::RepeatingClosure callback,
                       const net::CookieAccessResultList& cookie_list,
                       const net::CookieAccessResultList& excluded_cookies) {
  bool found_chocolate = false;
  bool found_oatmeal = false;
  for (const auto& c : cookie_list) {
    if (c.cookie.Name() == "chocolate-chip") {
      EXPECT_EQ("the-best", c.cookie.Value());
      found_chocolate = true;
    }
    if (c.cookie.Name() == "oatmeal") {
      EXPECT_EQ("sublime", c.cookie.Value());
      found_oatmeal = true;
    }
  }
  CHECK(found_chocolate && found_oatmeal);
  callback.Run();
}

// Check cookie loading for prefetched pages.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchCookie) {
  GURL url = src_server()->GetURL(kPrefetchCookiePage);
  std::unique_ptr<TestPrerender> test_prerender =
      PrefetchFromURL(url, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);

  content::StoragePartition* storage_partition =
      current_browser()->profile()->GetStoragePartitionForUrl(url, false);
  net::CookieOptions options = net::CookieOptions::MakeAllInclusive();
  base::RunLoop loop;
  storage_partition->GetCookieManagerForBrowserProcess()->GetCookieList(
      url, options, net::CookiePartitionKeyCollection(),
      base::BindOnce(GetCookieCallback, loop.QuitClosure()));
  loop.Run();
}

// Check cookie loading for a cross-domain prefetched pages.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchCookieCrossDomain) {
  static const std::string secondary_domain = "www.foo.com";
  GURL cross_domain_url(base::StringPrintf(
      "http://%s:%d%s", secondary_domain.c_str(),
      embedded_test_server()->host_port_pair().port(), kPrefetchCookiePage));

  std::unique_ptr<TestPrerender> test_prerender =
      PrefetchFromURL(cross_domain_url, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);

  // While the request is cross-site, it's permitted to set (implicitly) lax
  // cookies on a cross-site navigation.
  content::StoragePartition* storage_partition =
      current_browser()->profile()->GetStoragePartitionForUrl(cross_domain_url,
                                                              false);
  net::CookieOptions options = net::CookieOptions::MakeAllInclusive();
  base::RunLoop loop;
  storage_partition->GetCookieManagerForBrowserProcess()->GetCookieList(
      cross_domain_url, options, net::CookiePartitionKeyCollection(),
      base::BindOnce(GetCookieCallback, loop.QuitClosure()));
  loop.Run();
}

// Check cookie loading for a cross-domain prefetched pages.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest,
                       PrefetchCookieCrossDomainSameSiteStrict) {
  constexpr char kSecondaryDomain[] = "www.foo.com";
  GURL cross_domain_url =
      embedded_test_server()->GetURL(kSecondaryDomain, "/echoall");

  EXPECT_TRUE(SetCookie(current_browser()->profile(), cross_domain_url,
                        "cookie_A=A; SameSite=Strict;"));
  EXPECT_TRUE(SetCookie(current_browser()->profile(), cross_domain_url,
                        "cookie_B=B; SameSite=Lax;"));

  std::unique_ptr<TestPrerender> test_prerender =
      PrefetchFromURL(cross_domain_url, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);

  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(current_browser(), cross_domain_url));

  EXPECT_TRUE(WaitForLoadStop(
      current_browser()->tab_strip_model()->GetActiveWebContents()));

  std::string html_content;
  EXPECT_TRUE(content::ExecuteScriptAndExtractString(
      current_browser()->tab_strip_model()->GetActiveWebContents(),
      "domAutomationController.send(document.body.innerHTML)", &html_content));

  // For any cross origin navigation (including prerender), SameSite Strict
  // cookies should not be sent, but Lax should.
  EXPECT_EQ(std::string::npos, html_content.find("cookie_A=A"));
  EXPECT_NE(std::string::npos, html_content.find("cookie_B=B"));
}

// Check cookie loading for a same-domain prefetched pages.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest,
                       PrefetchCookieSameDomainSameSiteStrict) {
  GURL same_domain_url = embedded_test_server()->GetURL("/echoall");

  EXPECT_TRUE(SetCookie(current_browser()->profile(), same_domain_url,
                        "cookie_A=A; SameSite=Strict;"));
  EXPECT_TRUE(SetCookie(current_browser()->profile(), same_domain_url,
                        "cookie_B=B; SameSite=Lax;"));

  std::unique_ptr<TestPrerender> test_prerender =
      PrefetchFromURL(same_domain_url, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);

  ASSERT_TRUE(ui_test_utils::NavigateToURL(current_browser(), same_domain_url));

  EXPECT_TRUE(WaitForLoadStop(
      current_browser()->tab_strip_model()->GetActiveWebContents()));

  std::string html_content;
  EXPECT_TRUE(content::ExecuteScriptAndExtractString(
      current_browser()->tab_strip_model()->GetActiveWebContents(),
      "domAutomationController.send(document.body.innerHTML)", &html_content));

  // For any same origin navigation (including prerender), SameSite Strict
  // cookies should not be sent, but Lax should.
  EXPECT_NE(std::string::npos, html_content.find("cookie_A=A"));
  EXPECT_NE(std::string::npos, html_content.find("cookie_B=B"));
}

// Check that the LOAD_PREFETCH flag is set.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchLoadFlag) {
  GURL prefetch_page = src_server()->GetURL(kPrefetchPage);
  GURL prefetch_script = src_server()->GetURL(kPrefetchScript);

  content::URLLoaderMonitor monitor({prefetch_page, prefetch_script});

  std::unique_ptr<TestPrerender> test_prerender =
      PrefetchFromFile(kPrefetchPage, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  WaitForRequestCount(prefetch_page, 1);
  WaitForRequestCount(prefetch_script, 1);

  // Verify that the page load did not happen.
  test_prerender->WaitForLoads(0);
  monitor.WaitForUrls();

  absl::optional<network::ResourceRequest> page_request =
      monitor.GetRequestInfo(prefetch_page);
  EXPECT_TRUE(page_request->load_flags & net::LOAD_PREFETCH);
  absl::optional<network::ResourceRequest> script_request =
      monitor.GetRequestInfo(prefetch_script);
  EXPECT_TRUE(script_request->load_flags & net::LOAD_PREFETCH);
}

// Check that prefetched resources and subresources set the 'Purpose: prefetch'
// header.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PurposeHeaderIsSet) {
  GURL prefetch_page = src_server()->GetURL(kPrefetchPage);
  GURL prefetch_script = src_server()->GetURL(kPrefetchScript);

  content::URLLoaderMonitor monitor({prefetch_page, prefetch_script});

  std::unique_ptr<TestPrerender> test_prerender =
      PrefetchFromFile(kPrefetchPage, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  WaitForRequestCount(prefetch_page, 1);
  WaitForRequestCount(prefetch_script, 1);
  monitor.WaitForUrls();
  for (const GURL& url : {prefetch_page, prefetch_script}) {
    absl::optional<network::ResourceRequest> request =
        monitor.GetRequestInfo(url);
    EXPECT_TRUE(request->load_flags & net::LOAD_PREFETCH);
    EXPECT_FALSE(request->headers.HasHeader(kExpectedPurposeHeaderOnPrefetch));
    EXPECT_TRUE(request->cors_exempt_headers.HasHeader(
        kExpectedPurposeHeaderOnPrefetch));
    std::string purpose_header;
    request->cors_exempt_headers.GetHeader(kExpectedPurposeHeaderOnPrefetch,
                                           &purpose_header);
    EXPECT_EQ("prefetch", purpose_header);
  }
}

// Check that on normal navigations the 'Purpose: prefetch' header is not set.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest,
                       PurposeHeaderNotSetWhenNotPrefetching) {
  GURL prefetch_page = src_server()->GetURL(kPrefetchPage);
  GURL prefetch_script = src_server()->GetURL(kPrefetchScript);
  GURL prefetch_script2 = src_server()->GetURL(kPrefetchScript2);

  content::URLLoaderMonitor monitor(
      {prefetch_page, prefetch_script, prefetch_script2});

  ASSERT_TRUE(ui_test_utils::NavigateToURL(current_browser(), prefetch_page));
  WaitForRequestCount(prefetch_page, 1);
  WaitForRequestCount(prefetch_script, 1);
  WaitForRequestCount(prefetch_script2, 1);
  monitor.WaitForUrls();
  for (const GURL& url : {prefetch_page, prefetch_script, prefetch_script2}) {
    absl::optional<network::ResourceRequest> request =
        monitor.GetRequestInfo(url);
    EXPECT_FALSE(request->load_flags & net::LOAD_PREFETCH);
    EXPECT_FALSE(request->headers.HasHeader(kExpectedPurposeHeaderOnPrefetch));
    EXPECT_FALSE(request->cors_exempt_headers.HasHeader(
        kExpectedPurposeHeaderOnPrefetch));
  }
}

// Checks the prefetch of an img tag.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchImage) {
  GURL main_page_url = GetURLWithReplacement(
      kPrefetchImagePage, "REPLACE_WITH_IMAGE_URL", kPrefetchJpeg);
  PrefetchFromURL(main_page_url, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  WaitForRequestCount(src_server()->GetURL(kPrefetchJpeg), 1);
}

// Checks that a cross-domain prefetching works correctly.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchCrossDomain) {
  static const std::string secondary_domain = "www.foo.com";
  GURL cross_domain_url(base::StringPrintf(
      "http://%s:%d%s", secondary_domain.c_str(),
      embedded_test_server()->host_port_pair().port(), kPrefetchPage));
  PrefetchFromURL(cross_domain_url, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPage), 1);
}

// Checks that prefetching from a cross-domain subframe works correctly.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest,
                       PrefetchFromCrossDomainSubframe) {
  const std::string secondary_domain = "www.foo.com";

  GURL target_url(base::StringPrintf(
      "http://%s:%d%s", secondary_domain.c_str(),
      embedded_test_server()->host_port_pair().port(), kPrefetchPage));

  GURL inner_frame_url = ServeLoaderURLWithHostname(
      kPrefetchLoaderPath, "REPLACE_WITH_PREFETCH_URL", target_url, "",
      secondary_domain);

  GURL outer_frame_url = ServeLoaderURL(
      kPrefetchFromSubframe, "REPLACE_WITH_SUBFRAME_URL", inner_frame_url, "");

  std::vector<FinalStatus> expected_final_status_queue(
      1, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  std::vector<std::unique_ptr<TestPrerender>> prerenders =
      NavigateWithPrerenders(outer_frame_url, expected_final_status_queue);
  prerenders[0]->WaitForStop();

  WaitForRequestCount(src_server()->GetURL(kPrefetchPage), 1);
}

// Checks that response header CSP is respected.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, ResponseHeaderCSP) {
  static const std::string secondary_domain = "foo.bar";
  GURL second_script_url(std::string("http://foo.bar") + kPrefetchScript2);
  GURL prefetch_response_header_csp = GetURLWithReplacement(
      kPrefetchResponseHeaderCSP, "REPLACE_WITH_PORT",
      base::NumberToString(src_server()->host_port_pair().port()));

  PrefetchFromURL(prefetch_response_header_csp,
                  FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  // The second script is in the correct domain for CSP, but the first script is
  // not.
  WaitForRequestCount(prefetch_response_header_csp, 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript2), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript), 0);
}

// Checks that CSP in the meta tag cancels the prefetch.
// TODO(mattcary): probably this behavior should be consistent with
// response-header CSP. See crbug/656581.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, MetaTagCSP) {
  static const std::string secondary_domain = "foo.bar";
  GURL second_script_url(std::string("http://foo.bar") + kPrefetchScript2);
  GURL prefetch_meta_tag_csp = GetURLWithReplacement(
      kPrefetchMetaCSP, "REPLACE_WITH_PORT",
      base::NumberToString(src_server()->host_port_pair().port()));

  PrefetchFromURL(prefetch_meta_tag_csp,
                  FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  // TODO(mattcary): See test comment above. If the meta CSP tag were parsed,
  // |second_script| would be loaded. Instead as the background scanner bails as
  // soon as the meta CSP tag is seen, only |main_page| is fetched.
  WaitForRequestCount(prefetch_meta_tag_csp, 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript2), 0);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript), 0);
}

// Checks that the second prefetch request succeeds. This test waits for
// Prerender Stop before starting the second request.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchMultipleRequest) {
  PrefetchFromFile(kPrefetchPage, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  PrefetchFromFile(kPrefetchPage2, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPage), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPage2), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript2), 1);
}

// Checks that a second prefetch request, started before the first stops,
// succeeds.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchSimultaneous) {
  // The test assumes the previous page gets deleted after navigation. Disable
  // back/forward cache to ensure that it doesn't get preserved in the cache.
  content::DisableBackForwardCacheForTesting(
      GetActiveWebContents(),
      content::BackForwardCache::TEST_ASSUMES_NO_CACHING);
  GURL first_url = src_server()->GetURL("/hung");

  // Start the first prefetch directly instead of via PrefetchFromFile for the
  // first prefetch to avoid the wait on prerender stop.
  GURL first_loader_url = ServeLoaderURL(
      kPrefetchLoaderPath, "REPLACE_WITH_PREFETCH_URL", first_url, "");
  std::vector<FinalStatus> first_expected_status_queue(1,
                                                       FINAL_STATUS_CANCELLED);
  NavigateWithPrerenders(first_loader_url, first_expected_status_queue);

  PrefetchFromFile(kPrefetchPage2, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPage2), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript2), 1);
}

// Checks that a prefetch does not recursively prefetch.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, NoPrefetchRecursive) {
  // A prefetch of a page with a prefetch of the image page should not load the
  // image page.
  PrefetchFromFile(kPrefetchRecursePage,
                   FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  WaitForRequestCount(src_server()->GetURL(kPrefetchRecursePage), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchNostorePage), 0);

  // When the first page is loaded, the image page should be prefetched. The
  // test may finish before the prefetcher is torn down, so
  // IgnoreNoStatePrefetchContents() is called to skip the final status check.
  no_state_prefetch_contents_factory()->IgnoreNoStatePrefetchContents();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      current_browser(), src_server()->GetURL(kPrefetchRecursePage)));
  WaitForRequestCount(src_server()->GetURL(kPrefetchNostorePage), 1);
}

// Checks a prefetch to a nonexisting page.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchNonexisting) {
  std::unique_ptr<TestPrerender> test_prerender = PrefetchFromFile(
      "/nonexisting-page.html", FINAL_STATUS_UNSUPPORTED_SCHEME);
}

// Checks that a 301 redirect is followed.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, Prefetch301Redirect) {
  PrefetchFromFile(CreateServerRedirect(kPrefetchPage),
                   FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript), 1);
}

// Checks that non-HTTP(S) main resource redirects are marked as unsupported
// scheme.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest,
                       PrefetchRedirectUnsupportedScheme) {
  PrefetchFromFile(
      CreateServerRedirect("invalidscheme://www.google.com/test.html"),
      FINAL_STATUS_UNSUPPORTED_SCHEME, 1);
}

// Checks that a 302 redirect is followed.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, Prefetch302Redirect) {
  PrefetchFromFile(k302RedirectPage, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript), 1);
}

// Checks that the load flags are set correctly for all resources in a 301
// redirect chain.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, Prefetch301LoadFlags) {
  std::string redirect_path = CreateServerRedirect(kPrefetchPage);
  GURL redirect_url = src_server()->GetURL(redirect_path);
  GURL page_url = src_server()->GetURL(kPrefetchPage);
  content::URLLoaderMonitor monitor({redirect_url});

  PrefetchFromFile(redirect_path, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  WaitForRequestCount(redirect_url, 1);
  WaitForRequestCount(page_url, 1);
  monitor.WaitForUrls();

  absl::optional<network::ResourceRequest> request =
      monitor.GetRequestInfo(redirect_url);
  EXPECT_TRUE(request->load_flags & net::LOAD_PREFETCH);
}

// Checks that a subresource 301 redirect is followed.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, Prefetch301Subresource) {
  PrefetchFromFile(kPrefetchSubresourceRedirectPage,
                   FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript), 1);
}

// Checks a client redirect is not followed.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchClientRedirect) {
  PrefetchFromFile(
      "/client-redirect/?" + net::EscapeQueryParamValue(kPrefetchPage, false),
      FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      current_browser(), src_server()->GetURL(kPrefetchPage2)));
  // A complete load of kPrefetchPage2 is used as a sentinel. Otherwise the test
  // ends before script_counter would reliably see the load of kPrefetchScript,
  // were it to happen.
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript2), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript), 0);
}

// Prefetches a page that contains an automatic download triggered through an
// iframe. The request to download should not reach the server.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchDownloadIframe) {
  PrefetchFromFile("/prerender/prerender_download_iframe.html",
                   FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  // A complete load of kPrefetchPage2 is used as a sentinel as in test
  // |PrefetchClientRedirect| above.
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript2), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchDownloadFile), 0);
}

IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest,
                       PrefetchDownloadViaClientRedirect) {
  PrefetchFromFile("/prerender/prerender_download_refresh.html",
                   FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  // A complete load of kPrefetchPage2 is used as a sentinel as in test
  // |PrefetchClientRedirect| above.
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript2), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchDownloadFile), 0);
}

IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchPageWithFragment) {
  std::unique_ptr<TestPrerender> test_prerender = PrefetchFromFile(
      kPrefetchPageWithFragment, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);

  test_prerender->WaitForLoads(0);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript2), 0);
}

// Checks that a prefetch of a CRX will result in a cancellation due to
// download.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchCrx) {
  PrefetchFromFile("/prerender/extension.crx", FINAL_STATUS_DOWNLOAD);
}

IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchHttps) {
  UseHttpsSrcServer();
  PrefetchFromFile(kPrefetchPage, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPage), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript), 1);
}

// Checks that an SSL error prevents prefetch.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, SSLError) {
  // Only send the loaded page, not the loader, through SSL.
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_MISMATCHED_NAME);
  https_server.ServeFilesFromSourceDirectory(GetChromeTestDataDir());
  ASSERT_TRUE(https_server.Start());
  std::unique_ptr<TestPrerender> prerender = PrefetchFromURL(
      https_server.GetURL(kPrefetchPage), FINAL_STATUS_SSL_ERROR);
  DestructionWaiter waiter(prerender->contents(), FINAL_STATUS_SSL_ERROR);
  EXPECT_TRUE(waiter.WaitForDestroy());
}

// Checks that a subresource failing SSL does not prevent prefetch on the rest
// of the page.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, SSLSubresourceError) {
  // First confirm that the image loads as expected.

  // A separate HTTPS server is started for the subresource; src_server() is
  // non-HTTPS.
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_MISMATCHED_NAME);
  https_server.ServeFilesFromSourceDirectory(GetChromeTestDataDir());
  ASSERT_TRUE(https_server.Start());
  GURL https_url = https_server.GetURL("/prerender/image.jpeg");
  GURL main_page_url = GetURLWithReplacement(
      kPrefetchImagePage, "REPLACE_WITH_IMAGE_URL", https_url.spec());

  std::unique_ptr<TestPrerender> prerender =
      PrefetchFromURL(main_page_url, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  // Checks that the presumed failure of the image load didn't affect the script
  // fetch. This assumes waiting for the script load is enough to see any error
  // from the image load.
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript), 1);
}

IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, Loop) {
  std::unique_ptr<TestPrerender> test_prerender = PrefetchFromFile(
      kPrefetchLoopPage, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  WaitForRequestCount(src_server()->GetURL(kPrefetchLoopPage), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript), 1);
}

IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, RendererCrash) {
  // Navigate to about:blank to get the session storage namespace.
  ASSERT_TRUE(ui_test_utils::NavigateToURL(current_browser(),
                                           GURL(url::kAboutBlankURL)));
  content::SessionStorageNamespace* storage_namespace =
      GetActiveWebContents()
          ->GetController()
          .GetDefaultSessionStorageNamespace();

  // Navigate to about:crash without an intermediate loader because chrome://
  // URLs are ignored in renderers, and the test server has no support for them.
  const gfx::Size kSize(640, 480);
  std::unique_ptr<TestPrerender> test_prerender =
      no_state_prefetch_contents_factory()->ExpectNoStatePrefetchContents(
          FINAL_STATUS_RENDERER_CRASHED);
  content::ScopedAllowRendererCrashes scoped_allow_renderer_crashes;
  std::unique_ptr<NoStatePrefetchHandle> no_state_prefetch_handle(
      GetNoStatePrefetchManager()->StartPrefetchingFromExternalRequest(
          GURL(blink::kChromeUICrashURL), content::Referrer(),
          storage_namespace, gfx::Rect(kSize)));
  ASSERT_EQ(no_state_prefetch_handle->contents(), test_prerender->contents());
  test_prerender->WaitForStop();
}

// Checks that the prefetch of png correctly loads the png.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, Png) {
  PrefetchFromFile(kPrefetchPng, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPng), 1);
}

// Checks that the prefetch of jpeg correctly loads the jpeg.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, Jpeg) {
  PrefetchFromFile(kPrefetchJpeg, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  WaitForRequestCount(src_server()->GetURL(kPrefetchJpeg), 1);
}

// If the main resource is unsafe, the whole prefetch is cancelled.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest,
                       PrerenderSafeBrowsingTopLevel) {
  GURL url = src_server()->GetURL(kPrefetchPage);
  GetFakeSafeBrowsingDatabaseManager()->AddDangerousUrl(
      url, safe_browsing::SB_THREAT_TYPE_URL_MALWARE);

  std::unique_ptr<TestPrerender> prerender =
      PrefetchFromFile(kPrefetchPage, FINAL_STATUS_SAFE_BROWSING);

  // The frame request may have been started, but SafeBrowsing must have already
  // blocked it. Verify that the page load did not happen.
  prerender->WaitForLoads(0);

  // The frame resource has been blocked by SafeBrowsing, the subresource on
  // the page shouldn't be requested at all.
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript), 0);
}

// Ensures that server redirects to a malware page will cancel prerenders.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, ServerRedirect) {
  GURL url = src_server()->GetURL("/prerender/prerender_page.html");
  GetFakeSafeBrowsingDatabaseManager()->AddDangerousUrl(
      url, safe_browsing::SB_THREAT_TYPE_URL_PHISHING);
  PrefetchFromURL(src_server()->GetURL(
                      CreateServerRedirect("/prerender/prerender_page.html")),
                  FINAL_STATUS_SAFE_BROWSING, 0);
}

// If a subresource is unsafe, the corresponding request is cancelled.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest,
                       PrerenderSafeBrowsingSubresource) {
  GURL url = src_server()->GetURL(kPrefetchScript);
  GetFakeSafeBrowsingDatabaseManager()->AddDangerousUrl(
      url, safe_browsing::SB_THREAT_TYPE_URL_MALWARE);

  constexpr char kPrefetchCanceledHistogram[] =
      "SB2Test.RequestDestination.UnsafePrefetchCanceled";

  base::RunLoop run_loop;
  bool prefetch_canceled_histogram_added = false;
  auto histogram_observer =
      std::make_unique<base::StatisticsRecorder::ScopedHistogramSampleObserver>(
          kPrefetchCanceledHistogram,
          base::BindRepeating(
              [](base::RepeatingClosure quit_closure, bool* called,
                 const char* histogram_name, uint64_t name_hash,
                 base::HistogramBase::Sample sample) {
                *called = true;
                quit_closure.Run();
              },
              run_loop.QuitClosure(), &prefetch_canceled_histogram_added));

  std::unique_ptr<TestPrerender> prerender =
      PrefetchFromFile(kPrefetchPage, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);

  // The frame resource was loaded.
  WaitForRequestCount(src_server()->GetURL(kPrefetchPage), 1);

  // There should be a histogram sample recorded for SafeBrowsing canceling an
  // unsafe prefetch, which corresponded to the subresource.
  run_loop.Run();
  EXPECT_TRUE(prefetch_canceled_histogram_added);
}

// Checks that prefetching a page does not add it to browsing history.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, HistoryUntouchedByPrefetch) {
  // Initialize.
  Profile* profile = current_browser()->profile();
  ASSERT_TRUE(profile);
  ui_test_utils::WaitForHistoryToLoad(HistoryServiceFactory::GetForProfile(
      profile, ServiceAccessType::EXPLICIT_ACCESS));

  // Prefetch a page.
  GURL prefetched_url = src_server()->GetURL(kPrefetchPage);
  PrefetchFromFile(kPrefetchPage, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  WaitForHistoryBackendToRun(profile);

  // Navigate to another page.
  GURL navigated_url = src_server()->GetURL(kPrefetchPage2);
  ASSERT_TRUE(ui_test_utils::NavigateToURL(current_browser(), navigated_url));
  WaitForHistoryBackendToRun(profile);

  // Check that the URL that was explicitly navigated to is already in history.
  ui_test_utils::HistoryEnumerator enumerator(profile);
  std::vector<GURL>& urls = enumerator.urls();
  EXPECT_TRUE(base::Contains(urls, navigated_url));

  // Check that the URL that was prefetched is not in history.
  EXPECT_FALSE(base::Contains(urls, prefetched_url));

  // The loader URL is the remaining entry.
  EXPECT_EQ(2U, urls.size());
}

// Checks that prefetch requests have net::IDLE priority.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, IssuesIdlePriorityRequests) {
  // TODO(pasko): Figure out how to test that while a prefetched URL is in IDLE
  // priority state, a high-priority request with the same URL from a foreground
  // navigation hits the server.
  GURL script_url = src_server()->GetURL(kPrefetchScript);
  content::URLLoaderMonitor monitor({script_url});

  PrefetchFromFile(kPrefetchPage, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  WaitForRequestCount(script_url, 1);
  monitor.WaitForUrls();

#if BUILDFLAG(IS_ANDROID)
  // On Android requests from prerenders do not get downgraded
  // priority. See: https://crbug.com/652746.
  constexpr net::RequestPriority kExpectedPriority = net::HIGHEST;
#else
  constexpr net::RequestPriority kExpectedPriority = net::IDLE;
#endif
  absl::optional<network::ResourceRequest> request =
      monitor.GetRequestInfo(script_url);
  EXPECT_EQ(kExpectedPriority, request->priority);
}

// Checks that a registered ServiceWorker (SW) that is not currently running
// will intercepts a prefetch request.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, ServiceWorkerIntercept) {
  // Register and launch a SW.
  std::u16string expected_title = u"SW READY";
  content::TitleWatcher title_watcher(GetActiveWebContents(), expected_title);
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      current_browser(), src_server()->GetURL(kServiceWorkerLoader)));
  EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());

  // Stop any SW, killing the render process in order to test that the
  // lightweight renderer created for NoState prefetch does not interfere with
  // SW startup.
  int host_count = 0;
  for (content::RenderProcessHost::iterator iter(
           content::RenderProcessHost::AllHostsIterator());
       !iter.IsAtEnd(); iter.Advance()) {
    // Don't count spare RenderProcessHosts.
    if (!iter.GetCurrentValue()->HostHasNotBeenUsed())
      ++host_count;

    content::RenderProcessHostWatcher process_exit_observer(
        iter.GetCurrentValue(),
        content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
    // TODO(wez): This used to use wait=true.
    iter.GetCurrentValue()->Shutdown(content::RESULT_CODE_KILLED);
    process_exit_observer.Wait();
  }
  // There should be at most one render_process_host, that created for the SW.
  EXPECT_EQ(1, host_count);

  // Open a new tab to replace the one closed with all the RenderProcessHosts.
  ui_test_utils::NavigateToURLWithDisposition(
      current_browser(), GURL(url::kAboutBlankURL),
      WindowOpenDisposition::NEW_FOREGROUND_TAB,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);

  // The SW intercepts kPrefetchPage and replaces it with a body that contains
  // an <img> tage for kPrefetchPng. This verifies that the SW ran correctly by
  // observing the fetch of the image.
  PrefetchFromFile(kPrefetchPage, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPng), 1);
}

class NoStatePrefetchIncognitoBrowserTest : public NoStatePrefetchBrowserTest {
 public:
  void SetUpOnMainThread() override {
    Profile* normal_profile = current_browser()->profile();
    set_browser(OpenURLOffTheRecord(normal_profile, GURL("about:blank")));
    NoStatePrefetchBrowserTest::SetUpOnMainThread();
    current_browser()->profile()->GetPrefs()->SetInteger(
        prefs::kCookieControlsMode,
        static_cast<int>(content_settings::CookieControlsMode::kOff));
  }
};

// Checks that prerendering works in incognito mode.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchIncognitoBrowserTest,
                       PrerenderIncognito) {
  std::unique_ptr<TestPrerender> test_prerender =
      PrefetchFromFile(kPrefetchPage, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);

  // Verify that the page load did not happen.
  test_prerender->WaitForLoads(0);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPage), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript2), 0);
}

// Checks that prerenders are aborted when an incognito profile is closed.
// TODO(crbug.com/994068): The test is crashing on multiple platforms.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchIncognitoBrowserTest,
                       DISABLED_PrerenderIncognitoClosed) {
  std::unique_ptr<TestPrerender> test_prerender =
      PrefetchFromFile(kHungPrerenderPage, FINAL_STATUS_PROFILE_DESTROYED);
  current_browser()->window()->Close();
  test_prerender->WaitForStop();
}

// Checks that when the history is cleared, NoStatePrefetch history is cleared.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, ClearHistory) {
  std::unique_ptr<TestPrerender> test_prerender = PrefetchFromFile(
      kHungPrerenderPage, FINAL_STATUS_CACHE_OR_HISTORY_CLEARED);

  ClearBrowsingData(current_browser(),
                    chrome_browsing_data_remover::DATA_TYPE_HISTORY);
  test_prerender->WaitForStop();

  // Make sure prerender history was cleared.
  EXPECT_EQ(0U, GetHistoryLength());
}

// Checks that when the cache is cleared, NoStatePrefetch history is not
// cleared.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, ClearCache) {
  std::unique_ptr<TestPrerender> prerender = PrefetchFromFile(
      kHungPrerenderPage, FINAL_STATUS_CACHE_OR_HISTORY_CLEARED);

  ClearBrowsingData(current_browser(),
                    content::BrowsingDataRemover::DATA_TYPE_CACHE);
  prerender->WaitForStop();

  // Make sure prerender history was not cleared.  Not a vital behavior, but
  // used to compare with ClearHistory test.
  EXPECT_EQ(1U, GetHistoryLength());
}

IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, CancelAll) {
  GURL url = src_server()->GetURL(kHungPrerenderPage);
  std::unique_ptr<TestPrerender> prerender =
      PrefetchFromURL(url, FINAL_STATUS_CANCELLED, 0);

  GetNoStatePrefetchManager()->CancelAllPrerenders();
  prerender->WaitForStop();

  EXPECT_FALSE(prerender->contents());
}

// Cancels the prerender of a page with its own prerender.  The second prerender
// should never be started.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest,
                       CancelPrerenderWithPrerender) {
  GURL url = src_server()->GetURL("/prerender/prerender_infinite_a.html");

  std::unique_ptr<TestPrerender> prerender =
      PrefetchFromURL(url, FINAL_STATUS_CANCELLED);

  GetNoStatePrefetchManager()->CancelAllPrerenders();
  prerender->WaitForStop();

  EXPECT_FALSE(prerender->contents());
}

// Checks shutdown code while a prerender is active.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrerenderQuickQuit) {
  GURL url = src_server()->GetURL(kHungPrerenderPage);
  std::unique_ptr<TestPrerender> prerender =
      PrefetchFromURL(url, FINAL_STATUS_APP_TERMINATING);
}

IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrerenderClickNewWindow) {
  GURL url = src_server()->GetURL("/prerender/prerender_page_with_link.html");
  std::unique_ptr<TestPrerender> prerender =
      PrefetchFromURL(url, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  OpenDestURLViaClickNewWindow(url);
}

IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest,
                       PrerenderClickNewForegroundTab) {
  GURL url = src_server()->GetURL("/prerender/prerender_page_with_link.html");
  std::unique_ptr<TestPrerender> prerender =
      PrefetchFromURL(url, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);

  OpenDestURLViaClickNewForegroundTab(url);
}

// Checks that renderers using excessive memory will be terminated.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrerenderExcessiveMemory) {
  ASSERT_TRUE(GetNoStatePrefetchManager());
  GetNoStatePrefetchManager()->mutable_config().max_bytes = 100;
  PrefetchFromURL(
      src_server()->GetURL("/prerender/prerender_excessive_memory.html"),
      FINAL_STATUS_MEMORY_LIMIT_EXCEEDED);
}

class NoStatePrefetchOmniboxBrowserTest : public NoStatePrefetchBrowserTest {
 public:
  LocationBar* GetLocationBar() {
    return current_browser()->window()->GetLocationBar();
  }

  OmniboxView* GetOmniboxView() { return GetLocationBar()->GetOmniboxView(); }

  predictors::AutocompleteActionPredictor* GetAutocompleteActionPredictor() {
    Profile* profile = current_browser()->profile();
    return predictors::AutocompleteActionPredictorFactory::GetForProfile(
        profile);
  }

  std::unique_ptr<TestPrerender> ExpectPrerender(
      FinalStatus expected_final_status) {
    return no_state_prefetch_contents_factory()->ExpectNoStatePrefetchContents(
        expected_final_status);
  }

  std::unique_ptr<TestPrerender> StartOmniboxPrerender(
      const GURL& url,
      FinalStatus expected_final_status) {
    std::unique_ptr<TestPrerender> prerender =
        ExpectPrerender(expected_final_status);
    content::WebContents* web_contents = GetActiveWebContents();
    GetAutocompleteActionPredictor()->StartPrerendering(url, *web_contents,
                                                        gfx::Size(50, 50));
    prerender->WaitForStart();
    return prerender;
  }
};

// Checks that closing the omnibox popup cancels an omnibox prerender.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchOmniboxBrowserTest,
                       PrerenderOmniboxCancel) {
  // Fake an omnibox prerender.
  std::unique_ptr<TestPrerender> prerender = StartOmniboxPrerender(
      embedded_test_server()->GetURL("/empty.html"), FINAL_STATUS_CANCELLED);

  // Revert the location bar. This should cancel the prerender.
  GetLocationBar()->Revert();
  prerender->WaitForStop();
}

IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, OpenTaskManager) {
  const std::u16string any_tab = MatchTaskManagerTab("*");
  const std::u16string original = MatchTaskManagerTab("Prefetch Loader");
  const std::u16string prefetch_page = MatchTaskManagerTab("Prefetch Page");

  // Show the task manager. This populates the model.
  chrome::OpenTaskManager(current_browser());
  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_tab));
  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, prefetch_page));

  // Prerender a page in addition to the original tab.
  PrefetchFromFile(kPrefetchPage, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);

  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, original));
  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_tab));

  // ui_test_utils::NavigateToURL(current_browser(),
  //                             src_server()->GetURL(kPrefetchPage));
  // Open a new tab to replace the one closed with all the RenderProcessHosts.
  ui_test_utils::NavigateToURLWithDisposition(
      current_browser(), src_server()->GetURL(kPrefetchPage),
      WindowOpenDisposition::NEW_FOREGROUND_TAB,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, prefetch_page));
}

// Renders a page that contains a prerender link to a page that contains an
// img with a source that requires http authentication. This should not
// prerender successfully.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest,
                       PrerenderHttpAuthentication) {
  GURL url =
      src_server()->GetURL("/prerender/prerender_http_auth_container.html");
  std::unique_ptr<TestPrerender> prerender =
      PrefetchFromURL(url, FINAL_STATUS_AUTH_NEEDED);
}

// Checks that the referrer is not set when prerendering and the source page is
// HTTPS.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrerenderNoSSLReferrer) {
  // Use http:// url for the prerendered page main resource.
  GURL url(
      embedded_test_server()->GetURL("/prerender/prerender_no_referrer.html"));

  // Use https:// for all resources.
  UseHttpsSrcServer();

  PrefetchFromURL(url, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  ASSERT_TRUE(ui_test_utils::NavigateToURL(current_browser(), url));
  EXPECT_TRUE(WaitForLoadStop(
      current_browser()->tab_strip_model()->GetActiveWebContents()));
  content::WebContents* web_contents =
      current_browser()->tab_strip_model()->GetActiveWebContents();
  const std::string referrer =
      EvalJs(web_contents, "document.referrer").ExtractString();
  EXPECT_TRUE(referrer.empty());
}

// Test class to verify speculation hints for non-private same origin no state
// prefetches.
class SpeculationNoStatePrefetchBrowserTest
    : public NoStatePrefetchBrowserTest {
 public:
  void SetUp() override {
    feature_list_.InitAndEnableFeature(
        blink::features::kSpeculationRulesPrefetchProxy);
    NoStatePrefetchBrowserTest::SetUp();
  }

  void InsertSpeculation(const GURL& prefetch_url,
                         FinalStatus expected_final_status,
                         bool should_navigate_away = false) {
    std::string speculation_script = R"(
      var script = document.createElement('script');
      script.type = 'speculationrules';
      script.text = `{)";
    speculation_script.append(R"("prefetch_with_subresources": [{)");
    speculation_script.append(R"("source": "list",
          "urls": [)");

    speculation_script.append("\"").append(prefetch_url.spec()).append("\"");

    speculation_script.append(R"(]
        }]
      }`;
      document.head.appendChild(script);)");
    std::unique_ptr<TestPrerender> test_prerender =
        no_state_prefetch_contents_factory()->ExpectNoStatePrefetchContents(
            expected_final_status);
    EXPECT_TRUE(ExecuteScript(GetActiveWebContents(), speculation_script));
    if (should_navigate_away) {
      ASSERT_TRUE(ui_test_utils::NavigateToURL(
          current_browser(), src_server()->GetURL("/defaultresponse?page")));
    }
    test_prerender->WaitForStop();
  }

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

IN_PROC_BROWSER_TEST_F(SpeculationNoStatePrefetchBrowserTest,
                       SpeculationPrefetch) {
  UseHttpsSrcServer();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      current_browser(), src_server()->GetURL("/defaultresponse?landing")));
  InsertSpeculation(src_server()->GetURL(kPrefetchPage),
                    FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPage), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript), 1);
}

IN_PROC_BROWSER_TEST_F(SpeculationNoStatePrefetchBrowserTest,
                       SpeculationDisallowsCrossOriginRedirect) {
  UseHttpsSrcServer();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      current_browser(), src_server()->GetURL("/defaultresponse?landing")));
  InsertSpeculation(
      src_server()->GetURL("/server-redirect-307?" +
                           src_server()->GetURL(kPrefetchPage).spec()),
      FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
  WaitForRequestCount(src_server()->GetURL(kPrefetchPage), 1);
  WaitForRequestCount(src_server()->GetURL(kPrefetchScript), 1);
}

IN_PROC_BROWSER_TEST_F(SpeculationNoStatePrefetchBrowserTest,
                       SpeculationAllowsSameOriginRedirectBlocked) {
  UseHttpsSrcServer();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      current_browser(), src_server()->GetURL("/defaultresponse?landing")));
  InsertSpeculation(src_server()->GetURL(
                        "/server-redirect-307?" +
                        embedded_test_server()->GetURL(kPrefetchPage).spec()),
                    FINAL_STATUS_UNSUPPORTED_SCHEME);
  EXPECT_EQ(0u, GetRequestCount(embedded_test_server()->GetURL(kPrefetchPage)));
  EXPECT_EQ(0u,
            GetRequestCount(embedded_test_server()->GetURL(kPrefetchScript)));
}

IN_PROC_BROWSER_TEST_F(SpeculationNoStatePrefetchBrowserTest,
                       HungSpeculationTimedOutByNavigation) {
  // The test assumes the previous page gets deleted after navigation. Disable
  // back/forward cache to ensure that it doesn't get preserved in the cache.
  content::DisableBackForwardCacheForTesting(
      browser()->tab_strip_model()->GetActiveWebContents(),
      content::BackForwardCache::TEST_ASSUMES_NO_CACHING);
  UseHttpsSrcServer();
  GetNoStatePrefetchManager()->mutable_config().abandon_time_to_live =
      base::Milliseconds(500);
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      current_browser(), src_server()->GetURL("/defaultresponse?landing")));
  InsertSpeculation(src_server()->GetURL("/hung"), FINAL_STATUS_TIMED_OUT,
                    /*should_navigate_away=*/true);
}

}  // namespace prerender
