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

#include "content/browser/back_forward_cache_browsertest.h"

#include <climits>
#include <optional>
#include <string_view>
#include <unordered_map>

#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/functional/callback_helpers.h"
#include "base/location.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/metrics_hashes.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/system/sys_info.h"
#include "base/task/common/task_annotator.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/test_timeouts.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"
#include "base/trace_event/trace_log.h"
#include "build/build_config.h"
#include "build/chromecast_buildflags.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/browser/bad_message.h"
#include "content/browser/renderer_host/back_forward_cache_can_store_document_result.h"
#include "content/browser/renderer_host/back_forward_cache_disable.h"
#include "content/browser/renderer_host/back_forward_cache_impl.h"
#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/should_swap_browsing_instance.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/content_navigation_policy.h"
#include "content/common/features.h"
#include "content/public/browser/back_forward_cache.h"
#include "content/public/browser/document_service.h"
#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/web_contents.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/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/commit_message_delayer.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/fenced_frame_test_util.h"
#include "content/public/test/navigation_handle_observer.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_navigation_throttle.h"
#include "content/public/test/test_navigation_throttle_inserter.h"
#include "content/public/test/test_utils.h"
#include "content/public/test/text_input_test_utils.h"
#include "content/public/test/url_loader_interceptor.h"
#include "content/public/test/web_contents_observer_test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/shell/browser/shell_javascript_dialog_manager.h"
#include "content/test/content_browser_test_utils_internal.h"
#include "media/base/media_switches.h"
#include "mojo/public/cpp/bindings/message.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "net/base/filename_util.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/controllable_http_response.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/install_default_websocket_handlers.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "services/network/public/cpp/features.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/common/device_memory/approximated_device_memory.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/features_generated.h"
#include "third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h"
#include "third_party/blink/public/common/switches.h"
#include "third_party/blink/public/mojom/back_forward_cache_not_restored_reasons.mojom.h"
#include "third_party/blink/public/mojom/frame/back_forward_cache_controller.mojom.h"
#include "third_party/blink/public/mojom/frame/frame.mojom.h"
#include "third_party/blink/public/mojom/render_accessibility.mojom.h"
#include "third_party/blink/public/mojom/script_source_location.mojom.h"

// This file has too many tests.
//
// Before adding new tests to this file, consider if they will fit better into
// one of the other back_forward_cache_*_browsertest.cc files or if there are
// enough new tests to justify a new file.

using testing::_;
using testing::Each;
using testing::ElementsAre;
using testing::Not;
using testing::UnorderedElementsAreArray;

namespace content {

using NotRestoredReasons =
    BackForwardCacheCanStoreDocumentResult::NotRestoredReasons;
using NotRestoredReason = BackForwardCacheMetrics::NotRestoredReason;

EvalJsResult GetLocalStorage(RenderFrameHostImpl* rfh, std::string key) {
  return EvalJs(rfh, JsReplace("localStorage.getItem($1)", key));
}

[[nodiscard]] bool WaitForLocalStorage(RenderFrameHostImpl* rfh,
                                       std::string key,
                                       std::string expected_value) {
  auto value = EvalJs(rfh, JsReplace(R"(
    new Promise((resolve) => {
      let key = $1;
      let expected_value = $2;
      if (localStorage.getItem(key) == expected_value) {
        resolve(localStorage.getItem(key));
        return;
      }
      let listener = window.addEventListener("storage", e => {
        if (e.storageArea == localStorage && e.key == key
                && e.newValue == expected_value) {
          resolve(localStorage.getItem(key));
          removeEventListener("storage", listener);
          return;
        }
      });
    });
    )",
                                     key, expected_value));
  return value == expected_value;
}

BackForwardCacheBrowserTest::BackForwardCacheBrowserTest() = default;

BackForwardCacheBrowserTest::~BackForwardCacheBrowserTest() {
  if (fail_for_unexpected_messages_while_cached_) {
    // If this is triggered, see MojoInterfaceName in
    // tools/metrics/histograms/metadata/navigation/enums.xml for which values
    // correspond which messages.
    std::vector<base::Bucket> samples = histogram_tester().GetAllSamples(
        "BackForwardCache.UnexpectedRendererToBrowserMessage."
        "InterfaceName");
    // TODO(crbug.com/40244391): Remove this.
    // This bucket corresponds to the LocalFrameHost interface. It is known to
    // be flaky due calls to `LocalFrameHost::DidFocusFrame()` after entering
    // BFCache. So we ignore it for now by removing it if it's present until we
    // can fix the root cause.
    // TODO(crbug.com/40925798): Remove this.
    // As above but `LocalMainFrameHost::DidFirstVisuallyNonEmptyPaint()`.
    std::erase_if(samples, [](base::Bucket bucket) {
      return bucket.min ==
                 static_cast<base::HistogramBase::Sample32>(base::HashMetricName(
                     blink::mojom::LocalFrameHost::Name_)) ||
             bucket.min ==
                 static_cast<base::HistogramBase::Sample32>(base::HashMetricName(
                     blink::mojom::LocalMainFrameHost::Name_));
    });

    EXPECT_THAT(samples, testing::ElementsAre());
  }
}

void BackForwardCacheBrowserTest::NotifyNotRestoredReasons(
    std::unique_ptr<BackForwardCacheCanStoreTreeResult> tree_result) {
  tree_result_ = std::move(tree_result);
}

void BackForwardCacheBrowserTest::SetUpCommandLine(
    base::CommandLine* command_line) {
  mock_cert_verifier_.SetUpCommandLine(command_line);

  command_line->AppendSwitch(switches::kUseFakeUIForMediaStream);
  command_line->AppendSwitch(switches::kEnableExperimentalWebPlatformFeatures);
  // TODO(sreejakshetty): Initialize ScopedFeatureLists from test constructor.
  EnableFeatureAndSetParams(features::kBackForwardCacheTimeToLiveControl,
                            "time_to_live_seconds", "3600");
  // Entry to the cache can be slow during testing and cause flakiness.
  DisableFeature(features::kBackForwardCacheEntryTimeout);
  EnableFeatureAndSetParams(features::kBackForwardCache,
                            "message_handling_when_cached", "log");
  EnableFeatureAndSetParams(
      blink::features::kLogUnexpectedIPCPostedToBackForwardCachedDocuments,
      "delay_before_tracking_ms", "0");
  // Allow unlimited network during tests. Override this if you want to test the
  // network limiting.
  EnableFeatureAndSetParams(blink::features::kLoadingTasksUnfreezable,
                            "max_buffered_bytes_per_process",
                            base::NumberToString(INT_MAX));
  EnableFeatureAndSetParams(blink::features::kLoadingTasksUnfreezable,
                            "grace_period_to_finish_loading_in_seconds",
                            base::NumberToString(INT_MAX));
  // Enable capturing not-restored-reasons tree.
  EnableFeatureAndSetParams(
      blink::features::kBackForwardCacheSendNotRestoredReasons, "", "");

  // Do not trigger DumpWithoutCrashing() for JavaScript execution.
  DisableFeature(blink::features::kBackForwardCacheDWCOnJavaScriptExecution);
#if BUILDFLAG(IS_ANDROID)
  EnableFeatureAndSetParams(features::kBackForwardCache,
                            "process_binding_strength", "NORMAL");
#endif
    // Allow BackForwardCache for all devices regardless of their memory.
    DisableFeature(features::kBackForwardCacheMemoryControls);
    // Many browser tests assume a cache size of 1.
    EnableCacheSize(1, std::nullopt);

    SetupFeaturesAndParameters();

    command_line->AppendSwitchASCII(
        switches::kAutoplayPolicy,
        switches::autoplay::kNoUserGestureRequiredPolicy);
    // Unfortunately needed for one test on slow bots, TextInputStateUpdated,
    // where deferred commits delays input too much.
    command_line->AppendSwitch(blink::switches::kAllowPreCommitInput);
    ContentBrowserTest::SetUpCommandLine(command_line);
}

void BackForwardCacheBrowserTest::SetUpInProcessBrowserTestFixture() {
  ContentBrowserTest::SetUpInProcessBrowserTestFixture();
  mock_cert_verifier_.SetUpInProcessBrowserTestFixture();
}

void BackForwardCacheBrowserTest::TearDownInProcessBrowserTestFixture() {
  ContentBrowserTest::TearDownInProcessBrowserTestFixture();
  mock_cert_verifier_.TearDownInProcessBrowserTestFixture();
}

void BackForwardCacheBrowserTest::SetupFeaturesAndParameters() {
  std::vector<base::test::FeatureRefAndParams> enabled_features;

  for (const auto& [feature_ref, params] : features_with_params_) {
    enabled_features.emplace_back(*feature_ref, params);
  }

  feature_list_.InitWithFeaturesAndParameters(enabled_features,
                                              disabled_features_);
  vmodule_switches_.InitWithSwitches("back_forward_cache_impl=1");
}

void BackForwardCacheBrowserTest::EnableFeatureAndSetParams(
    const base::Feature& feature,
    std::string param_name,
    std::string param_value) {
  const auto& it = features_with_params_.find(feature);
  if (it != features_with_params_.end()) {
    // If the feature-param has been set already, do not update it.
    if (it->second.contains(param_name)) {
      return;
    }
  }
  features_with_params_[feature][param_name] = param_value;
}

void BackForwardCacheBrowserTest::DisableFeature(const base::Feature& feature) {
  if (features_with_params_.contains(feature)) {
    // If the feature has been explicitly enabled, ignore any subsequent
    // disables.
    return;
  }
  disabled_features_.push_back(feature);
}

void BackForwardCacheBrowserTest::EnableCacheSize(
    std::optional<int> cache_size,
    std::optional<int> foreground_cache_size) {
  if (cache_size) {
    EnableFeatureAndSetParams(content::kBackForwardCacheSize,
                              kBackForwardCacheSizeCacheSize.name,
                              base::NumberToString(cache_size.value()));
  }
  if (foreground_cache_size) {
    EnableFeatureAndSetParams(
        content::kBackForwardCacheSize,
        kBackForwardCacheSizeForegroundCacheSize.name,
        base::NumberToString(foreground_cache_size.value()));
  }
}

void BackForwardCacheBrowserTest::SetUpOnMainThread() {
  // Set up WebSocket handlers, as a number of tests use them.
  net::test_server::InstallDefaultWebSocketHandlers(embedded_test_server());

  mock_cert_verifier_.mock_cert_verifier()->set_default_result(net::OK);
  host_resolver()->AddRule("*", "127.0.0.1");
  // TestAutoSetUkmRecorder's constructor requires a sequenced context.
  ukm_recorder_ = std::make_unique<ukm::TestAutoSetUkmRecorder>();
  histogram_tester_ = std::make_unique<base::HistogramTester>();
  ContentBrowserTest::SetUpOnMainThread();
}

void BackForwardCacheBrowserTest::TearDownOnMainThread() {
  ukm_recorder_.reset();
  ContentBrowserTest::TearDownOnMainThread();
}

WebContentsImpl* BackForwardCacheBrowserTest::web_contents() const {
  return static_cast<WebContentsImpl*>(shell()->web_contents());
}

RenderFrameHostImpl* BackForwardCacheBrowserTest::current_frame_host() {
  return web_contents()->GetPrimaryFrameTree().root()->current_frame_host();
}

RenderFrameHostManager*
BackForwardCacheBrowserTest::render_frame_host_manager() {
  return web_contents()->GetPrimaryFrameTree().root()->render_manager();
}

std::string BackForwardCacheBrowserTest::DepictFrameTree(FrameTreeNode* node) {
  return visualizer_.DepictFrameTree(node);
}

bool BackForwardCacheBrowserTest::HistogramContainsIntValue(
    base::HistogramBase::Sample32 sample,
    std::vector<base::Bucket> histogram_values) {
  return base::Contains(histogram_values, static_cast<int>(sample),
                        &base::Bucket::min);
}

void BackForwardCacheBrowserTest::EvictByJavaScript(RenderFrameHostImpl* rfh) {
  // Run JavaScript on a page in the back-forward cache. The page should be
  // evicted. As the frame is deleted, ExecJs returns false without executing.
  // Run without user gesture to prevent UpdateUserActivationState message
  // being sent back to browser.
  EXPECT_FALSE(
      ExecJs(rfh, "console.log('hi');", EXECUTE_SCRIPT_NO_USER_GESTURE));
}

void BackForwardCacheBrowserTest::StartRecordingEvents(
    RenderFrameHostImpl* rfh) {
  EXPECT_TRUE(ExecJs(rfh, R"(
      window.testObservedEvents = [];
      let event_list = [
        'visibilitychange',
        'pagehide',
        'pageshow',
        'freeze',
        'resume',
      ];
      for (event_name of event_list) {
        let result = event_name;
        window.addEventListener(event_name, event => {
          if (event.persisted)
            result += '.persisted';
          window.testObservedEvents.push('window.' + result);
        });
        document.addEventListener(event_name,
            () => window.testObservedEvents.push('document.' + result));
      }
    )"));
}

void BackForwardCacheBrowserTest::MatchEventList(RenderFrameHostImpl* rfh,
                                                 base::Value list,
                                                 base::Location location) {
  EXPECT_EQ(list, EvalJs(rfh, "window.testObservedEvents"))
      << location.ToString();
}

// Creates a minimal HTTPS server, accessible through https_server().
// Returns a pointer to the server.
net::EmbeddedTestServer* BackForwardCacheBrowserTest::CreateHttpsServer() {
  https_server_ = std::make_unique<net::EmbeddedTestServer>(
      net::EmbeddedTestServer::TYPE_HTTPS);
  https_server_->AddDefaultHandlers(GetTestDataFilePath());
  https_server_->SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES);
  return https_server();
}

net::EmbeddedTestServer* BackForwardCacheBrowserTest::https_server() {
  return https_server_.get();
}

// Do not fail this test if a message from a renderer arrives at the browser
// for a cached page.
void BackForwardCacheBrowserTest::DoNotFailForUnexpectedMessagesWhileCached() {
  fail_for_unexpected_messages_while_cached_ = false;
}

  // Navigates to a page at |page_url| with an img element with src set to
  // "image.png".
RenderFrameHostImpl* BackForwardCacheBrowserTest::NavigateToPageWithImage(
    const GURL& page_url) {
  EXPECT_TRUE(NavigateToURL(shell(), page_url));
  RenderFrameHostImpl* rfh = current_frame_host();
  // Wait for the document to load DOM to ensure that kLoading is not
  // one of the reasons why the document wasn't cached.
  EXPECT_TRUE(WaitForDOMContentLoaded(rfh));

  EXPECT_TRUE(ExecJs(rfh, R"(
      var image = document.createElement("img");
      image.src = "image.png";
      document.body.appendChild(image);

      var image_load_status = new Promise((resolve, reject) => {
        image.onload = () => { resolve("loaded"); }
        image.onerror = () => { resolve("error"); }
      });
    )"));
  return rfh;
}

void BackForwardCacheBrowserTest::AcquireKeyboardLock(
    RenderFrameHostImpl* rfh) {
  EXPECT_EQ(42, EvalJs(rfh, R"(
        new Promise(resolve => {
          navigator.keyboard.lock();
          resolve(42);
        });
      )"));
}

void BackForwardCacheBrowserTest::ReleaseKeyboardLock(
    RenderFrameHostImpl* rfh) {
  EXPECT_EQ(42, EvalJs(rfh, R"(
        new Promise(resolve => {
          navigator.keyboard.unlock();
          resolve(42);
        });
      )"));
}

void BackForwardCacheBrowserTest::NavigateAndBlock(GURL url,
                                                   int history_offset) {
  // Block the navigation with an error.
  std::unique_ptr<URLLoaderInterceptor> url_interceptor =
      URLLoaderInterceptor::SetupRequestFailForURL(url,
                                                   net::ERR_BLOCKED_BY_CLIENT);
  if (history_offset) {
    shell()->GoBackOrForward(history_offset);
  } else {
    shell()->LoadURL(url);
  }
  WaitForLoadStop(web_contents());
  ASSERT_EQ(current_frame_host()->GetLastCommittedURL(), url);
  ASSERT_TRUE(current_frame_host()->IsErrorDocument());
}

ReasonsMatcher BackForwardCacheBrowserTest::MatchesNotRestoredReasons(
    const std::optional<testing::Matcher<std::string>>& id,
    const std::optional<testing::Matcher<std::string>>& name,
    const std::optional<testing::Matcher<std::string>>& src,
    const std::vector<BlockingDetailsReasonsMatcher>& reasons,
    const std::optional<SameOriginMatcher>& same_origin_details) {
  // TODO(crbug.com/41496143) Make this matcher display human-friendly messages.
  return testing::Pointee(testing::AllOf(
      id.has_value()
          ? testing::Field(
                "id", &blink::mojom::BackForwardCacheNotRestoredReasons::id,
                testing::Optional(id.value()))
          : testing::Field(
                "id", &blink::mojom::BackForwardCacheNotRestoredReasons::id,
                std::optional<std::string>(std::nullopt)),
      name.has_value()
          ? testing::Field(
                "name", &blink::mojom::BackForwardCacheNotRestoredReasons::name,
                testing::Optional(name.value()))
          : testing::Field(
                "name", &blink::mojom::BackForwardCacheNotRestoredReasons::name,
                std::optional<std::string>(std::nullopt)),
      src.has_value()
          ? testing::Field(
                "src", &blink::mojom::BackForwardCacheNotRestoredReasons::src,
                testing::Optional(src.value()))
          : testing::Field(
                "src", &blink::mojom::BackForwardCacheNotRestoredReasons::src,
                std::optional<std::string>(std::nullopt)),
      testing::Field("reasons",
                     &blink::mojom::BackForwardCacheNotRestoredReasons::reasons,
                     testing::UnorderedElementsAreArray(reasons)),
      testing::Field(
          "same_origin_details",
          &blink::mojom::BackForwardCacheNotRestoredReasons::
              same_origin_details,
          same_origin_details.has_value()
              ? same_origin_details.value()
              : testing::Property(
                    "is_null",
                    &blink::mojom::SameOriginBfcacheNotRestoredDetailsPtr::
                        is_null,
                    true))));
}

SameOriginMatcher BackForwardCacheBrowserTest::MatchesSameOriginDetails(
    const testing::Matcher<GURL>& url,
    const std::vector<ReasonsMatcher>& children) {
  // TODO(crbug.com/41496143) Make this matcher display human-friendly messages.
  return testing::Pointee(testing::AllOf(
      testing::Field(
          "url", &blink::mojom::SameOriginBfcacheNotRestoredDetails::url, url),
      testing::Field(
          "children",
          &blink::mojom::SameOriginBfcacheNotRestoredDetails::children,
          testing::ElementsAreArray(children))));
}

BlockingDetailsReasonsMatcher
BackForwardCacheBrowserTest::MatchesDetailedReason(
    const testing::Matcher<std::string>& name,
    const std::optional<SourceLocationMatcher>& source) {
  // TODO(crbug.com/41496143) Make this matcher display human-friendly
  // messages.
  return testing::Pointee(testing::AllOf(
      testing::Field("name", &blink::mojom::BFCacheBlockingDetailedReason::name,
                     name),
      testing::Field(
          "source", &blink::mojom::BFCacheBlockingDetailedReason::source,
          source.has_value()
              ? source.value()
              : testing::Property(
                    "is_null", &blink::mojom::ScriptSourceLocationPtr::is_null,
                    true))));
}

BlockingDetailsMatcher BackForwardCacheBrowserTest::MatchesBlockingDetails(
    const std::optional<SourceLocationMatcher>& source) {
  // TODO(crbug.com/41496143) Make this matcher display human-friendly messages.
  return testing::Pointee(testing::Field(
      "source", &blink::mojom::BlockingDetails::source,
      source.has_value()
          ? source.value()
          : testing::Property("is_null",
                              &blink::mojom::ScriptSourceLocationPtr::is_null,
                              true)));
}

SourceLocationMatcher BackForwardCacheBrowserTest::MatchesSourceLocation(
    const testing::Matcher<GURL>& url,
    const testing::Matcher<std::string>& function_name,
    const testing::Matcher<uint64_t>& line_number,
    const testing::Matcher<uint64_t>& column_number) {
  // TODO(crbug.com/41496143) Make this matcher display human-friendly
  // messages.
  return testing::Pointee(testing::AllOf(
      testing::Field("url", &blink::mojom::ScriptSourceLocation::url, url),
      testing::Field("function_name",
                     &blink::mojom::ScriptSourceLocation::function_name,
                     function_name),
      testing::Field("line_number",
                     &blink::mojom::ScriptSourceLocation::line_number,
                     line_number),
      testing::Field("column_number",
                     &blink::mojom::ScriptSourceLocation::column_number,
                     column_number)));
}

void BackForwardCacheUnloadBrowserTest::SetUpCommandLine(
    base::CommandLine* command_line) {
  BackForwardCacheBrowserTest::SetUpCommandLine(command_line);
  scoped_feature_list_.InitAndEnableFeature(kBackForwardCacheUnloadAllowed);
}

std::initializer_list<RenderFrameHostImpl*> Elements(
    std::initializer_list<RenderFrameHostImpl*> t) {
  return t;
}

// Execute a custom callback when navigation is ready to commit. This is
// useful for simulating race conditions happening when a page enters the
// BackForwardCache and receive inflight messages sent when it wasn't frozen
// yet.
class ReadyToCommitNavigationCallback : public WebContentsObserver {
 public:
  ReadyToCommitNavigationCallback(
      WebContents* content,
      base::OnceCallback<void(NavigationHandle*)> callback)
      : WebContentsObserver(content), callback_(std::move(callback)) {}

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

 private:
  // WebContentsObserver:
  void ReadyToCommitNavigation(NavigationHandle* navigation_handle) override {
    if (callback_)
      std::move(callback_).Run(navigation_handle);
  }

  base::OnceCallback<void(NavigationHandle*)> callback_;
};

class FirstVisuallyNonEmptyPaintObserver : public WebContentsObserver {
 public:
  explicit FirstVisuallyNonEmptyPaintObserver(WebContents* contents)
      : WebContentsObserver(contents) {}
  void DidFirstVisuallyNonEmptyPaint() override {
    if (observed_)
      return;
    observed_ = true;
    run_loop_.Quit();
  }

  bool did_fire() const { return observed_; }

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

 private:
  bool observed_ = false;
  base::RunLoop run_loop_{base::RunLoop::Type::kNestableTasksAllowed};
};

void WaitForFirstVisuallyNonEmptyPaint(WebContents* contents) {
  if (contents->CompletedFirstVisuallyNonEmptyPaint())
    return;
  FirstVisuallyNonEmptyPaintObserver observer(contents);
  observer.Wait();
}

class ThemeColorObserver : public WebContentsObserver {
 public:
  explicit ThemeColorObserver(WebContents* contents)
      : WebContentsObserver(contents) {}

  // Can only be called once.
  [[nodiscard]] bool WaitUntilThemeColorChange() {
    CHECK(!loop_);
    loop_ = std::make_unique<base::RunLoop>();
    if (observed_) {
      return true;
    }
    loop_->Run();
    return observed_;
  }

  void DidChangeThemeColor() override {
    observed_ = true;
    if (loop_) {
      loop_->Quit();
    }
  }

  bool did_fire() const { return observed_; }

 private:
  std::unique_ptr<base::RunLoop> loop_;
  bool observed_ = false;
};

PageLifecycleStateManagerTestDelegate::PageLifecycleStateManagerTestDelegate(
    PageLifecycleStateManager* manager)
    : manager_(manager) {
  manager->SetDelegateForTesting(this);
}

PageLifecycleStateManagerTestDelegate::
    ~PageLifecycleStateManagerTestDelegate() {
  if (manager_)
    manager_->SetDelegateForTesting(nullptr);
}

bool PageLifecycleStateManagerTestDelegate::WaitForInBackForwardCacheAck() {
  DCHECK(manager_);
  if (manager_->last_acknowledged_state().is_in_back_forward_cache) {
    return true;
  }
  base::RunLoop loop;
  store_in_back_forward_cache_ack_received_ = loop.QuitClosure();
  loop.Run();
  return manager_->last_acknowledged_state().is_in_back_forward_cache;
}

void PageLifecycleStateManagerTestDelegate::OnStoreInBackForwardCacheSent(
    base::OnceClosure cb) {
  store_in_back_forward_cache_sent_ = std::move(cb);
}

void PageLifecycleStateManagerTestDelegate::OnDisableJsEvictionSent(
    base::OnceClosure cb) {
  disable_eviction_sent_ = std::move(cb);
}

void PageLifecycleStateManagerTestDelegate::OnRestoreFromBackForwardCacheSent(
    base::OnceClosure cb) {
  restore_from_back_forward_cache_sent_ = std::move(cb);
}

void PageLifecycleStateManagerTestDelegate::OnLastAcknowledgedStateChanged(
    const blink::mojom::PageLifecycleState& old_state,
    const blink::mojom::PageLifecycleState& new_state) {
  if (store_in_back_forward_cache_ack_received_ &&
      new_state.is_in_back_forward_cache)
    std::move(store_in_back_forward_cache_ack_received_).Run();
}

void PageLifecycleStateManagerTestDelegate::OnUpdateSentToRenderer(
    const blink::mojom::PageLifecycleState& new_state) {
  if (store_in_back_forward_cache_sent_ && new_state.is_in_back_forward_cache) {
    std::move(store_in_back_forward_cache_sent_).Run();
  }

  if (disable_eviction_sent_ && new_state.eviction_enabled == false) {
    std::move(disable_eviction_sent_).Run();
  }

  if (restore_from_back_forward_cache_sent_ &&
      !new_state.is_in_back_forward_cache) {
    std::move(restore_from_back_forward_cache_sent_).Run();
  }
}

void PageLifecycleStateManagerTestDelegate::OnDeleted() {
  manager_ = nullptr;
}

// Check the visible URL in the omnibox is properly updated when restoring a
// document from the BackForwardCache.
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, VisibleURL) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
  GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));

  // 1) Go to A.
  EXPECT_TRUE(NavigateToURL(shell(), url_a));

  // 2) Go to B.
  EXPECT_TRUE(NavigateToURL(shell(), url_b));

  // 3) Go back to A.
  ASSERT_TRUE(HistoryGoBack(web_contents()));
  EXPECT_EQ(url_a, web_contents()->GetVisibleURL());

  // 4) Go forward to B.
  ASSERT_TRUE(HistoryGoForward(web_contents()));
  EXPECT_EQ(url_b, web_contents()->GetVisibleURL());
}

// Test only 1 document is kept in the at a time BackForwardCache.
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
                       CacheSizeLimitedToOneDocumentPerTab) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
  GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));
  GURL url_c(embedded_test_server()->GetURL("c.com", "/title1.html"));

  EXPECT_TRUE(NavigateToURL(shell(), url_a));
  // BackForwardCache is empty.
  RenderFrameHostImpl* rfh_a = current_frame_host();
  RenderFrameDeletedObserver delete_observer_rfh_a(rfh_a);

  EXPECT_TRUE(NavigateToURL(shell(), url_b));
  // BackForwardCache contains only rfh_a.
  RenderFrameHostImpl* rfh_b = current_frame_host();
  RenderFrameDeletedObserver delete_observer_rfh_b(rfh_b);

  EXPECT_TRUE(NavigateToURL(shell(), url_c));
  // BackForwardCache contains only rfh_b.
  delete_observer_rfh_a.WaitUntilDeleted();
  EXPECT_FALSE(delete_observer_rfh_b.deleted());

  // If/when the cache size is increased, this can be tested iteratively, see
  // deleted code in: https://crrev.com/c/1782902.

  ASSERT_TRUE(HistoryGoToOffset(web_contents(), -2));
  ExpectNotRestored({BackForwardCacheMetrics::NotRestoredReason::kCacheLimit},
                    {}, {}, {}, {}, FROM_HERE);
}

IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, ResponseHeaders) {
  CreateHttpsServer();
  ASSERT_TRUE(https_server()->Start());

  GURL url_a(https_server()->GetURL("a.test", "/set-header?X-Foo: bar"));
  GURL url_b(https_server()->GetURL("b.test", "/title1.html"));

  // 1) Navigate to A.
  NavigationHandleObserver observer1(web_contents(), url_a);
  EXPECT_TRUE(NavigateToURL(shell(), url_a));
  RenderFrameHostImpl* rfh_a = current_frame_host();
  RenderFrameDeletedObserver delete_observer_rfh_a(rfh_a);
  EXPECT_TRUE(observer1.has_committed());
  EXPECT_EQ("bar", observer1.GetNormalizedResponseHeader("x-foo"));

  // 2) Navigate to B.
  NavigationHandleObserver observer2(web_contents(), url_b);
  EXPECT_TRUE(NavigateToURL(shell(), url_b));
  RenderFrameHostImpl* rfh_b = current_frame_host();
  RenderFrameDeletedObserver delete_observer_rfh_b(rfh_b);
  EXPECT_FALSE(delete_observer_rfh_a.deleted());
  EXPECT_TRUE(rfh_a->IsInBackForwardCache());
  EXPECT_FALSE(rfh_b->IsInBackForwardCache());
  EXPECT_TRUE(observer2.has_committed());

  // 3) Go back to A.
  NavigationHandleObserver observer3(web_contents(), url_a);
  ASSERT_TRUE(HistoryGoBack(web_contents()));
  EXPECT_FALSE(delete_observer_rfh_a.deleted());
  EXPECT_FALSE(delete_observer_rfh_b.deleted());
  EXPECT_EQ(rfh_a, current_frame_host());
  EXPECT_FALSE(rfh_a->IsInBackForwardCache());
  EXPECT_TRUE(rfh_b->IsInBackForwardCache());
  EXPECT_TRUE(observer3.has_committed());
  EXPECT_EQ("bar", observer3.GetNormalizedResponseHeader("x-foo"));

  ExpectRestored(FROM_HERE);
}

void HighCacheSizeBackForwardCacheBrowserTest::SetUpCommandLine(
    base::CommandLine* command_line) {
  EnableCacheSize(kBackForwardCacheSize, std::nullopt);
  BackForwardCacheBrowserTest::SetUpCommandLine(command_line);
}

// Test documents are evicted from the BackForwardCache at some point.
IN_PROC_BROWSER_TEST_F(HighCacheSizeBackForwardCacheBrowserTest,
                       CacheEvictionWithIncreasedCacheSize) {
  ASSERT_TRUE(embedded_test_server()->Start());

  GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
  GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));

  EXPECT_TRUE(NavigateToURL(shell(), url_a));  // BackForwardCache size is 0.
  RenderFrameHostImpl* rfh_a = current_frame_host();
  RenderFrameDeletedObserver delete_observer_rfh_a(rfh_a);

  EXPECT_TRUE(NavigateToURL(shell(), url_b));  // BackForwardCache size is 1.
  RenderFrameHostImpl* rfh_b = current_frame_host();
  RenderFrameDeletedObserver delete_observer_rfh_b(rfh_b);

  for (size_t i = 2; i < kBackForwardCacheSize; ++i) {
    EXPECT_TRUE(NavigateToURL(shell(), i % 2 ? url_b : url_a));
    // After |i+1| navigations, |i| documents went into the BackForwardCache.
    // When |i| is greater than the BackForwardCache size limit, they are
    // evicted:
    EXPECT_EQ(i >= kBackForwardCacheSize + 1, delete_observer_rfh_a.deleted());
    EXPECT_EQ(i >= kBackForwardCacheSize + 2, delete_observer_rfh_b.deleted());
  }
}

// Tests that evicting a page in between the time the back/forward cache
// NavigationRequest restore was created and when the NavigationRequest actually
// starts after finishing beforeunload won't result in a crash.
// See https://crbug.com/1218114.
IN_PROC_BROWSER_TEST_F(HighCacheSizeBackForwardCacheBrowserTest,
                       EvictedWhileWaitingForBeforeUnload) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
  GURL url_b(embedded_test_server()->GetURL("b.com", "/title2.html"));
  GURL url_c(embedded_test_server()->GetURL("c.com", "/title3.html"));

  // 1) Navigate to A.
  EXPECT_TRUE(NavigateToURL(shell(), url_a));
  RenderFrameHostImplWrapper rfh_a(current_frame_host());

  // 2) Navigate to B.
  EXPECT_TRUE(NavigateToURL(shell(), url_b));
  RenderFrameHostImplWrapper rfh_b(current_frame_host());
  EXPECT_TRUE(rfh_a->IsInBackForwardCache());

  // 3) Navigate to C, which has a beforeunload handler that never finishes.
  EXPECT_TRUE(NavigateToURL(shell(), url_c));
  RenderFrameHostImplWrapper rfh_c(current_frame_host());
  EXPECT_TRUE(ExecJs(rfh_c.get(), R"(
    window.onbeforeunload = () => {
      while (true) {}
    }
  )"));
  // Both A & B are in the back/forward cache.
  EXPECT_TRUE(rfh_a->IsInBackForwardCache());
  EXPECT_TRUE(rfh_b->IsInBackForwardCache());

  // 4) Evict entry A. This will post a task that destroys all evicted entries
  // when it runs (task #1).
  DisableBFCacheForRFHForTesting(rfh_a->GetGlobalId());
  EXPECT_FALSE(rfh_a.IsDestroyed());
  EXPECT_TRUE(rfh_a->is_evicted_from_back_forward_cache());

  // 5) Trigger a back navigation to B. This will create a BFCache restore
  // navigation to B, but will wait for C's beforeunload handler to finish
  // running before continuing.
  // The BFCache entry will be evicted before the back navigation completes, so
  // the old navigation will be reset and a new navigation will be restarted.
  // This observer is waiting for the two navigation requests to complete.
  TestNavigationObserver observer(web_contents(),
                                  /* expected_number_of_navigations= */ 2,
                                  MessageLoopRunner::QuitMode::IMMEDIATE,
                                  /* ignore_uncommitted_navigations= */ false);
  web_contents()->GetController().GoBack();

  // 6) Post a task to run BeforeUnloadCompleted (task #2). This will continue
  // the BFCache restore navigation to B from step 5, which is currently waiting
  // for a BeforeUnloadCompleted call.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
      FROM_HERE, base::BindLambdaForTesting([&]() {
        root->navigator().BeforeUnloadCompleted(
            root, /*proceed=*/true, base::TimeTicks::Now(),
            /*for_legacy=*/false, /*showed_dialog=*/false);
      }));

  // 7) Evict entry B. This will post a task (task #3) to restart the navigation
  // to B, and also another task (task #4) to destroy all evicted entries.
  DisableBFCacheForRFHForTesting(rfh_b->GetGlobalId());
  EXPECT_FALSE(rfh_b.IsDestroyed());
  EXPECT_TRUE(rfh_b->is_evicted_from_back_forward_cache());

  // 8) Wait until the back navigation to B finishes. This will run posted tasks
  // in order. So:
  // - Task #1 from step 4 will run and destroy all evicted entries. As both the
  // entries for A & B have been evicted, they are both destroyed.
  // - Task #2 from step 6 will run and continue the back/forward cache restore
  // NavigationRequest to B. However, it would notice that the entry for B is
  // now gone, and should handle it gracefully.
  // - Task #3 from step 7 to restart navigation to B runs, and should create a
  // NavigationRequest to replace the previous NavigationRequest to B.
  // - Task #4 from step 7 to destroy evicted entries runs and won't destroy
  // any entry since there's no longer any entry in the back/forward cache.
  observer.Wait();
  EXPECT_EQ(web_contents()->GetLastCommittedURL(), url_b);
  ExpectNotRestored({BackForwardCacheMetrics::NotRestoredReason::
                         kDisableForRenderFrameHostCalled},
                    {}, {}, {RenderFrameHostDisabledForTestingReason()}, {},
                    FROM_HERE);
}

IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
                       SubframeWithOngoingNavigationNotCached) {
  net::test_server::ControllableHttpResponse response(embedded_test_server(),
                                                      "/hung");
  ASSERT_TRUE(embedded_test_server()->Start());

  // Navigate to a page with an iframe.
  TestNavigationObserver navigation_observer1(web_contents());
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/back_forward_cache/page_with_hung_iframe.html"));
  shell()->LoadURL(main_url);
  navigation_observer1.WaitForNavigationFinished();

  RenderFrameHostImpl* main_frame = current_frame_host();
  RenderFrameDeletedObserver frame_deleted_observer(main_frame);
  response.WaitForRequest();

  // Navigate away.
  TestNavigationObserver navigation_observer2(web_contents());
  shell()->LoadURL(embedded_test_server()->GetURL("b.com", "/title1.html"));
  navigation_observer2.WaitForNavigationFinished();

  // The page with the unsupported feature should be deleted (not cached).
  frame_deleted_observer.WaitUntilDeleted();
}

// Only HTTP/HTTPS main document can enter the BackForwardCache.
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, CacheHTTPDocumentOnly) {
  ASSERT_TRUE(embedded_test_server()->Start());
  ASSERT_TRUE(CreateHttpsServer()->Start());

  GURL http_url(embedded_test_server()->GetURL("a.test", "/title1.html"));
  GURL https_url(https_server()->GetURL("a.test", "/title1.html"));
  GURL file_url = net::FilePathToFileURL(GetTestFilePath("", "title1.html"));
  GURL data_url = GURL("data:text/html,");
  GURL blank_url = GURL(url::kAboutBlankURL);
  GURL webui_url = GetWebUIURL("gpu");

  enum { STORED, DELETED };
  struct {
    int expectation;
    GURL url;
  } test_cases[] = {
      // Only document with HTTP/HTTPS URLs are allowed to enter the
      // BackForwardCache.
      {STORED, http_url},
      {STORED, https_url},

      // Others aren't allowed.
      {DELETED, file_url},
      {DELETED, data_url},
      {DELETED, webui_url},
      {DELETED, blank_url},
  };

  char hostname[] = "a.unique";
  for (auto& test_case : test_cases) {
    SCOPED_TRACE(testing::Message()
                 << std::endl
                 << "expectation = " << test_case.expectation << std::endl
                 << "url = " << test_case.url << std::endl);

    // 1) Navigate to.
    EXPECT_TRUE(NavigateToURL(shell(), test_case.url));
    RenderFrameHostImplWrapper rfh(current_frame_host());

    // 2) Navigate away.
    hostname[0]++;
    GURL reset_url(embedded_test_server()->GetURL(hostname, "/title1.html"));
    EXPECT_TRUE(NavigateToURL(shell(), reset_url));

    if (test_case.expectation == STORED) {
      EXPECT_FALSE(rfh.IsRenderFrameDeleted());
      EXPECT_TRUE(rfh->IsInBackForwardCache());
      continue;
    }

    if (rfh.get() == current_frame_host()) {
      // If the RenderFrameHost is reused, it won't be deleted, so don't wait
      // for deletion. Just check that it's not saved in the back-forward cache.
      EXPECT_FALSE(rfh.IsRenderFrameDeleted());
      EXPECT_FALSE(rfh->IsInBackForwardCache());
      continue;
    }

    // When the RenderFrameHost is not reused and it's not stored in the
    // back-forward cache, it will eventually be deleted.
    ASSERT_TRUE(rfh.WaitUntilRenderFrameDeleted());
  }
}

// Regression test for https://crbug.com/993337.
//
// A note about sharing BrowsingInstances and the BackForwardCache:
//
// We should never keep around more than one main frame that belongs to the same
// BrowsingInstance. When swapping two pages, when one is stored in the
// back-forward cache or one is restored from it, the current code expects the
// two to live in different BrowsingInstances.
//
// History navigation can recreate a page with the same BrowsingInstance as the
// one stored in the back-forward cache. This case must to be handled. When it
// happens, the back-forward cache page is evicted.
//
// Since cache eviction is asynchronous, it's is possible for two main frames
// belonging to the same BrowsingInstance to be alive for a brief period of time
// (the new page being navigated to, and a page in the cache, until it is
// destroyed asynchronously via eviction).
//
// The test below tests that the brief period of time where two main frames are
// alive in the same BrowsingInstance does not cause anything to blow up.

// TODO(crbug.com/1127979, crbug.com/1446206): Flaky on Linux, Windows and
// ChromeOS, iOS, and Mac.
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS) || \
    BUILDFLAG(IS_MAC) || BUILDFLAG(IS_IOS)
#define MAYBE_NavigateToTwoPagesOnSameSite DISABLED_NavigateToTwoPagesOnSameSite
#else
#define MAYBE_NavigateToTwoPagesOnSameSite NavigateToTwoPagesOnSameSite
#endif
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
                       MAYBE_NavigateToTwoPagesOnSameSite) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url_a1(embedded_test_server()->GetURL("a.com", "/title1.html"));
  GURL url_a2(embedded_test_server()->GetURL("a.com", "/title2.html"));
  GURL url_b3(embedded_test_server()->GetURL("b.com", "/title1.html"));

  // 1) Navigate to A1.
  EXPECT_TRUE(NavigateToURL(shell(), url_a1));

  // 2) Navigate to A2.
  EXPECT_TRUE(NavigateToURL(shell(), url_a2));
  RenderFrameHostImpl* rfh_a2 = current_frame_host();
  RenderFrameDeletedObserver delete_rfh_a2(current_frame_host());

  // 3) Navigate to B3.
  EXPECT_TRUE(NavigateToURL(shell(), url_b3));
  EXPECT_TRUE(rfh_a2->IsInBackForwardCache());
  RenderFrameHostImpl* rfh_b3 = current_frame_host();

  // 4) Do a history navigation back to A1.
  ASSERT_TRUE(HistoryGoToIndex(web_contents(), 0));
  EXPECT_TRUE(rfh_b3->IsInBackForwardCache());

  // Note that the frame for A1 gets created before A2 is deleted from the
  // cache, so there will be a brief period where two the main frames (A1 and
  // A2) are alive in the same BrowsingInstance/SiteInstance, at the same time.
  // That is the scenario this test is covering. This used to cause a CHECK,
  // because the two main frames shared a single RenderViewHost (no longer the
  // case after https://crrev.com/c/1833616).

  // A2 should be evicted from the cache and asynchronously deleted, due to the
  // cache size limit (B3 took its place in the cache).
  delete_rfh_a2.WaitUntilDeleted();
}

IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
                       NavigateToTwoPagesOnSameSiteWithSubframes) {
  ASSERT_TRUE(embedded_test_server()->Start());
  // This test covers the same scenario as NavigateToTwoPagesOnSameSite, except
  // the pages contain subframes:
  // A1(B) -> A2(B(C)) -> D3 -> A1(B)
  //
  // The subframes shouldn't make a difference, so the expected behavior is the
  // same as NavigateToTwoPagesOnSameSite.
  GURL url_a1(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  GURL url_a2(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(c))"));
  GURL url_d3(embedded_test_server()->GetURL("d.com", "/title1.html"));

  // 1) Navigate to A1(B).
  EXPECT_TRUE(NavigateToURL(shell(), url_a1));

  // 2) Navigate to A2(B(C)).
  EXPECT_TRUE(NavigateToURL(shell(), url_a2));
  RenderFrameHostImpl* rfh_a2 = current_frame_host();
  RenderFrameDeletedObserver delete_rfh_a2(current_frame_host());

  // 3) Navigate to D3.
  EXPECT_TRUE(NavigateToURL(shell(), url_d3));
  EXPECT_TRUE(rfh_a2->IsInBackForwardCache());
  RenderFrameHostImpl* rfh_d3 = current_frame_host();

  // 4) Do a history navigation back to A1(B).
  ASSERT_TRUE(HistoryGoToIndex(web_contents(), 0));

  // D3 takes A2(B(C))'s place in the cache.
  EXPECT_TRUE(rfh_d3->IsInBackForwardCache());
  delete_rfh_a2.WaitUntilDeleted();
}

// Sub-frame doesn't transition from LifecycleStateImpl::kInBackForwardCache to
// LifecycleStateImpl::kRunningUnloadHandlers even when the sub-frame having
// unload handlers is being evicted from BackForwardCache.
IN_PROC_BROWSER_TEST_F(BackForwardCacheUnloadBrowserTest,
                       SubframeWithUnloadHandler) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a.com(a.com)"));
  GURL child_url = embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a.com()");
  GURL url_2(embedded_test_server()->GetURL("a.com", "/title1.html"));

  // 1) Navigate to |main_url|.
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  RenderFrameHostImpl* main_rfh = current_frame_host();
  ASSERT_EQ(1U, main_rfh->child_count());
  RenderFrameHostImpl* child_rfh = main_rfh->child_at(0)->current_frame_host();
  RenderFrameDeletedObserver main_rfh_observer(main_rfh),
      child_rfh_observer(child_rfh);

  // 2) Add an unload handler to the child RFH.
  EXPECT_TRUE(ExecJs(child_rfh, "window.onunload = () => {} "));

  // 3) Navigate to |url_2|.
  EXPECT_TRUE(NavigateToURL(shell(), url_2));

  // 4) The previous main RFH and child RFH should be in the back-forward
  // cache.
  EXPECT_FALSE(main_rfh_observer.deleted());
  EXPECT_FALSE(child_rfh_observer.deleted());
  EXPECT_TRUE(main_rfh->IsInBackForwardCache());
  EXPECT_TRUE(child_rfh->IsInBackForwardCache());

  // Destruction of bfcached page happens after shutdown and it should not
  // trigger unload handlers and be destroyed directly.
}

// Do a same document navigation and make sure we do not fire the
// DidFirstVisuallyNonEmptyPaint again
IN_PROC_BROWSER_TEST_F(
    BackForwardCacheBrowserTest,
    DoesNotFireDidFirstVisuallyNonEmptyPaintForSameDocumentNavigation) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url_a_1(embedded_test_server()->GetURL(
      "a.com", "/accessibility/html/a-name.html"));
  GURL url_a_2(embedded_test_server()->GetURL(
      "a.com", "/accessibility/html/a-name.html#id"));

  EXPECT_TRUE(NavigateToURL(shell(), url_a_1));
  WaitForFirstVisuallyNonEmptyPaint(shell()->web_contents());

  FirstVisuallyNonEmptyPaintObserver observer(web_contents());
  EXPECT_TRUE(NavigateToURL(shell(), url_a_2));
  // Make sure the bfcache restore code does not fire the event during commit
  // navigation.
  EXPECT_FALSE(observer.did_fire());
  EXPECT_TRUE(web_contents()->CompletedFirstVisuallyNonEmptyPaint());
}

// Make sure we fire DidFirstVisuallyNonEmptyPaint when restoring from bf-cache.
// TODO(crbug.com/327195951): Re-enable this test
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_FiresDidFirstVisuallyNonEmptyPaintWhenRestoredFromCache \
  DISABLED_FiresDidFirstVisuallyNonEmptyPaintWhenRestoredFromCache
#else
#define MAYBE_FiresDidFirstVisuallyNonEmptyPaintWhenRestoredFromCache \
  FiresDidFirstVisuallyNonEmptyPaintWhenRestoredFromCache
#endif
IN_PROC_BROWSER_TEST_F(
    BackForwardCacheBrowserTest,
    MAYBE_FiresDidFirstVisuallyNonEmptyPaintWhenRestoredFromCache) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
  GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));

  // 1) Navigate to A.
  ASSERT_TRUE(NavigateToURL(shell(), url_a));
  WaitForFirstVisuallyNonEmptyPaint(shell()->web_contents());
  RenderFrameHostImpl* rfh_a = current_frame_host();
  RenderFrameDeletedObserver delete_observer_rfh_a(rfh_a);

  // 2) Navigate to B.
  ASSERT_TRUE(NavigateToURL(shell(), url_b));
  ASSERT_FALSE(delete_observer_rfh_a.deleted());
  ASSERT_TRUE(rfh_a->IsInBackForwardCache());
  WaitForFirstVisuallyNonEmptyPaint(shell()->web_contents());

  // 3) Navigate to back to A.
  FirstVisuallyNonEmptyPaintObserver observer(web_contents());
  ASSERT_TRUE(HistoryGoBack(web_contents()));
  // Make sure the bfcache restore code does fire the event during commit
  // navigation.
  EXPECT_TRUE(web_contents()->CompletedFirstVisuallyNonEmptyPaint());
  EXPECT_TRUE(observer.did_fire());
}
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_SetsThemeColorWhenRestoredFromCache \
  DISABLED_SetsThemeColorWhenRestoredFromCache
#else
#define MAYBE_SetsThemeColorWhenRestoredFromCache \
  SetsThemeColorWhenRestoredFromCache
#endif
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
                       MAYBE_SetsThemeColorWhenRestoredFromCache) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url_a(embedded_test_server()->GetURL("a.com", "/theme_color.html"));
  GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));

  ASSERT_TRUE(NavigateToURL(shell(), url_a));
  WaitForFirstVisuallyNonEmptyPaint(web_contents());
  RenderFrameHostImplWrapper rfh_a(current_frame_host());
  EXPECT_EQ(web_contents()->GetThemeColor(), 0xFFFF0000u);

  ASSERT_TRUE(NavigateToURL(shell(), url_b));
  WaitForFirstVisuallyNonEmptyPaint(web_contents());
  ASSERT_TRUE(rfh_a->IsInBackForwardCache());
  EXPECT_EQ(web_contents()->GetThemeColor(), std::nullopt);

  ThemeColorObserver observer(web_contents());
  ASSERT_TRUE(HistoryGoBack(web_contents()));
  ASSERT_TRUE(observer.WaitUntilThemeColorChange());
  EXPECT_EQ(web_contents()->GetThemeColor(), 0xFFFF0000u);
}

IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
                       ContentsMimeTypeWhenRestoredFromCache) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
  GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));

  // Navigate to A.
  EXPECT_TRUE(NavigateToURL(shell(), url_a));
  RenderFrameHostImpl* rfh_a = current_frame_host();
  RenderFrameDeletedObserver delete_observer_rfh_a(rfh_a);
  EXPECT_EQ(web_contents()->GetContentsMimeType(), "text/html");

  // Navigate to B.
  EXPECT_TRUE(NavigateToURL(shell(), url_b));
  ASSERT_FALSE(delete_observer_rfh_a.deleted());
  EXPECT_TRUE(rfh_a->IsInBackForwardCache());

  // Go back to A, which restores A from bfcache. ContentsMimeType should be
  // restored as well.
  ASSERT_TRUE(HistoryGoBack(web_contents()));
  EXPECT_EQ(rfh_a, current_frame_host());
  ExpectRestored(FROM_HERE);
  EXPECT_EQ(web_contents()->GetContentsMimeType(), "text/html");
}

// Check BackForwardCache is enabled and works for devices with very low memory.
// Navigate from A -> B and go back.
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
                       BackForwardCacheEnabledOnLowMemoryDevices) {
  // Set device physical memory to 10 MB.
  blink::ApproximatedDeviceMemory::SetPhysicalMemoryMBForTesting(10);
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
  GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));

  // 1) Navigate to A.
  EXPECT_TRUE(NavigateToURL(shell(), url_a));
  RenderFrameDeletedObserver delete_observer_rfh_a(current_frame_host());
  RenderFrameHostImpl* rfh_a = current_frame_host();

  // 2) Navigate to B. A should be in BackForwardCache.
  EXPECT_TRUE(NavigateToURL(shell(), url_b));
  RenderFrameHostImpl* rfh_b = current_frame_host();
  RenderFrameDeletedObserver delete_observer_rfh_b(rfh_b);
  EXPECT_FALSE(delete_observer_rfh_a.deleted());
  EXPECT_TRUE(rfh_a->IsInBackForwardCache());

  // 3) Go back to A. B should be in BackForwardCache.
  ASSERT_TRUE(HistoryGoBack(web_contents()));
  EXPECT_FALSE(delete_observer_rfh_b.deleted());
  EXPECT_TRUE(rfh_b->IsInBackForwardCache());
}

// Test for functionality of memory controls in back-forward cache for low
// memory devices.
class BackForwardCacheBrowserTestForLowMemoryDevices
    : public BackForwardCacheBrowserTest {
 protected:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    BackForwardCacheBrowserTest::SetUpCommandLine(command_line);

    // Set the value of memory threshold more than the physical memory and check
    // if back-forward cache is disabled or not.
    std::string memory_threshold = base::NumberToString(
        base::SysInfo::AmountOfPhysicalMemory().InMiB() + 1);
    scoped_feature_list_.InitWithFeaturesAndParameters(
        {{features::kBackForwardCacheMemoryControls,
          {{"memory_threshold_for_back_forward_cache_in_mb",
            memory_threshold}}},
         {blink::features::kLoadingTasksUnfreezable, {}}},
        {});
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

// Ensure that the BackForwardCache trial is not activated as expected on
// low-memory devices.
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTestForLowMemoryDevices,
                       DisableBFCacheForLowEndDevices) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
  GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));

  // Ensure that the BackForwardCache trial starts inactive.
  EXPECT_FALSE(base::FieldTrialList::IsTrialActive(
      base::FeatureList::GetFieldTrial(features::kBackForwardCache)
          ->trial_name()));

  EXPECT_FALSE(IsBackForwardCacheEnabled());

  // Ensure that we do not activate the BackForwardCache trial when querying
  // bfcache status.
  EXPECT_FALSE(base::FieldTrialList::IsTrialActive(
      base::FeatureList::GetFieldTrial(features::kBackForwardCache)
          ->trial_name()));

  // 1) Navigate to A.
  EXPECT_TRUE(NavigateToURL(shell(), url_a));
  RenderFrameHostImpl* rfh_a = current_frame_host();
  RenderFrameDeletedObserver delete_observer_rfh_a(rfh_a);

  // 2) Navigate to B.
  EXPECT_TRUE(NavigateToURL(shell(), url_b));

  // 3) A shouldn't be stored in back-forward cache because the physical
  // memory is less than the memory threshold.
  delete_observer_rfh_a.WaitUntilDeleted();

  // 4) Go back to check the
  // NotRestoredReasons.kBackForwardCacheDisabledByLowMemory is recorded when
  // the memory is less than the threshold value.
  ASSERT_TRUE(HistoryGoBack(web_contents()));

  ExpectNotRestored(
      {
          BackForwardCacheMetrics::NotRestoredReason::kBackForwardCacheDisabled,
          BackForwardCacheMetrics::NotRestoredReason::
              kBackForwardCacheDisabledByLowMemory,
      },
      {}, {}, {}, {}, FROM_HERE);

  // Ensure that the BackForwardCache trial still hasn't been activated.
  EXPECT_FALSE(base::FieldTrialList::IsTrialActive(
      base::FeatureList::GetFieldTrial(features::kBackForwardCache)
          ->trial_name()));
}

// Trigger network reqeuests, then navigate from A to B, then go back.
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTestForLowMemoryDevices,
                       DisableBFCacheForLowEndDevices_NetworkRequests) {
  net::test_server::ControllableHttpResponse image_response(
      embedded_test_server(), "/image.png");
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
  GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));

  // Ensure that the trials starts inactive.
  EXPECT_FALSE(base::FieldTrialList::IsTrialActive(
      base::FeatureList::GetFieldTrial(features::kBackForwardCache)
          ->trial_name()));
  EXPECT_FALSE(base::FieldTrialList::IsTrialActive(
      base::FeatureList::GetFieldTrial(
          blink::features::kLoadingTasksUnfreezable)
          ->trial_name()));

  EXPECT_FALSE(IsBackForwardCacheEnabled());

  // Ensure that we do not activate the trials for kBackForwardCache and
  // kLoadingTasksUnfreezable when querying bfcache or unfreezable loading tasks
  // status.
  EXPECT_FALSE(base::FieldTrialList::IsTrialActive(
      base::FeatureList::GetFieldTrial(features::kBackForwardCache)
          ->trial_name()));
  EXPECT_FALSE(base::FieldTrialList::IsTrialActive(
      base::FeatureList::GetFieldTrial(
          blink::features::kLoadingTasksUnfreezable)
          ->trial_name()));

  // 1) Navigate to A.
  EXPECT_TRUE(NavigateToURL(shell(), url_a));
  RenderFrameHostImpl* rfh_a = current_frame_host();
  RenderFrameDeletedObserver delete_observer_rfh_a(rfh_a);

  // Request for an image and send a response to trigger loading code. This is
  // to ensure kLoadingTasksUnfreezable won't trigger bfcache activation.
  EXPECT_TRUE(ExecJs(rfh_a, R"(
      var image = document.createElement("img");
      image.src = "image.png";
      document.body.appendChild(image);
    )"));
  image_response.WaitForRequest();
  image_response.Send(net::HTTP_OK, "image/png");
  image_response.Send("image_body");
  image_response.Done();

  // 2) Navigate to B.
  EXPECT_TRUE(NavigateToURL(shell(), url_b));

  // 3) A shouldn't be stored in back-forward cache because the physical
  // memory is less than the memory threshold.
  delete_observer_rfh_a.WaitUntilDeleted();

  // Nothing is recorded when the memory is less than the threshold value.
  ExpectOutcomeDidNotChange(FROM_HERE);
  ExpectNotRestoredDidNotChange(FROM_HERE);

  // Ensure that the trials still haven't been activated.
  EXPECT_FALSE(base::FieldTrialList::IsTrialActive(
      base::FeatureList::GetFieldTrial(features::kBackForwardCache)
          ->trial_name()));
  EXPECT_FALSE(base::FieldTrialList::IsTrialActive(
      base::FeatureList::GetFieldTrial(
          blink::features::kLoadingTasksUnfreezable)
          ->trial_name()));
}

// Test for functionality of memory controls in back-forward cache for high
// memory devices.
class BackForwardCacheBrowserTestForHighMemoryDevices
    : public BackForwardCacheBrowserTest {
 protected:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    BackForwardCacheBrowserTest::SetUpCommandLine(command_line);

    // Set the value of memory threshold less than the physical memory and check
    // if back-forward cache is enabled or not.
    std::string memory_threshold = base::NumberToString(
        base::SysInfo::AmountOfPhysicalMemory().InMiB() - 1);
    scoped_feature_list_.InitWithFeaturesAndParameters(
        {{features::kBackForwardCacheMemoryControls,
          {{"memory_threshold_for_back_forward_cache_in_mb",
            memory_threshold}}},
         {blink::features::kLoadingTasksUnfreezable, {}}},
        {});
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

// Ensure that the BackForwardCache trial got activated as expected on
// high-memory devices when the BackForwardCache feature is enabled.
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTestForHighMemoryDevices,
                       EnableBFCacheForHighMemoryDevices) {
  // Ensure that the BackForwardCache trial starts active on high-memory devices
  // when the BackForwardCache feature is enabled, because
  // IsBackForwardCacheEnabled() got queried already before the test starts.
  EXPECT_TRUE(base::FieldTrialList::IsTrialActive(
      base::FeatureList::GetFieldTrial(features::kBackForwardCache)
          ->trial_name()));

  EXPECT_TRUE(IsBackForwardCacheEnabled());

  // Ensure that the BackForwardCache trial stays active after querying
  // IsBackForwardCacheEnabled().
  EXPECT_TRUE(base::FieldTrialList::IsTrialActive(
      base::FeatureList::GetFieldTrial(features::kBackForwardCache)
          ->trial_name()));

  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
  GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));

  // 1) Navigate to A.
  EXPECT_TRUE(NavigateToURL(shell(), url_a));
  RenderFrameHostImpl* rfh_a = current_frame_host();

  // 2) Navigate to B.
  EXPECT_TRUE(NavigateToURL(shell(), url_b));

  // 3) A should be stored in back-forward cache because the physical memory is
  // greater than the memory threshold.
  EXPECT_TRUE(rfh_a->IsInBackForwardCache());

  // Ensure that the BackForwardCache trial stays active.
  EXPECT_TRUE(base::FieldTrialList::IsTrialActive(
      base::FeatureList::GetFieldTrial(features::kBackForwardCache)
          ->trial_name()));
}

// Trigger network reqeuests, then navigate from A to B, then go back.
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTestForHighMemoryDevices,
                       EnableBFCacheForHighMemoryDevices_NetworkRequests) {
  net::test_server::ControllableHttpResponse image_response(
      embedded_test_server(), "/image.png");
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
  GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));

  // Ensure that back-forward cache flag is enabled and the trial is active.
  EXPECT_TRUE(IsBackForwardCacheEnabled());
  EXPECT_TRUE(base::FieldTrialList::IsTrialActive(
      base::FeatureList::GetFieldTrial(features::kBackForwardCache)
          ->trial_name()));

  // Ensure that the LoadingTasksUnfreezable trials starts as inactive.
  EXPECT_FALSE(base::FieldTrialList::IsTrialActive(
      base::FeatureList::GetFieldTrial(
          blink::features::kLoadingTasksUnfreezable)
          ->trial_name()));

  // 1) Navigate to A.
  EXPECT_TRUE(NavigateToURL(shell(), url_a));
  RenderFrameHostImpl* rfh_a = current_frame_host();
  RenderFrameDeletedObserver delete_observer_rfh_a(rfh_a);

  // Request for an image and send a response to trigger loading code.
  EXPECT_TRUE(ExecJs(rfh_a, R"(
      var image = document.createElement("img");
      image.src = "image.png";
      document.body.appendChild(image);
    )"));
  image_response.WaitForRequest();
  image_response.Send(net::HTTP_OK, "image/png");
  image_response.Send("image_body");
  image_response.Done();

  // The loading code activates the LoadingTasksUnfreezable trial.
  EXPECT_TRUE(base::FieldTrialList::IsTrialActive(
      base::FeatureList::GetFieldTrial(
          blink::features::kLoadingTasksUnfreezable)
          ->trial_name()));

  // 2) Navigate to B.
  EXPECT_TRUE(NavigateToURL(shell(), url_b));

  // 3) A should be stored in back-forward cache because the physical memory is
  // greater than the memory threshold.
  EXPECT_TRUE(rfh_a->IsInBackForwardCache());

  // Ensure that the trials stay activated.
  EXPECT_TRUE(base::FieldTrialList::IsTrialActive(
      base::FeatureList::GetFieldTrial(features::kBackForwardCache)
          ->trial_name()));
  EXPECT_TRUE(base::FieldTrialList::IsTrialActive(
      base::FeatureList::GetFieldTrial(
          blink::features::kLoadingTasksUnfreezable)
          ->trial_name()));
}

// Tests for high memory devices that have the BackForwardCache feature flag
// disabled.
class BackForwardCacheBrowserTestForHighMemoryDevicesWithBFCacheDisabled
    : public BackForwardCacheBrowserTest {
 protected:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    BackForwardCacheBrowserTest::SetUpCommandLine(command_line);

    // Set the value of memory threshold less than the physical memory and check
    // if back-forward cache is enabled or not.
    std::string memory_threshold = base::NumberToString(
        base::SysInfo::AmountOfPhysicalMemory().InMiB() - 1);
    scoped_feature_list_.InitWithFeaturesAndParameters(
        /*enabled_features=*/
        {{features::kBackForwardCacheMemoryControls,
          {{"memory_threshold_for_back_forward_cache_in_mb",
            memory_threshold}}},
         {blink::features::kLoadingTasksUnfreezable, {}}},
        /*disabled_features=*/
        {features::kBackForwardCache});
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

IN_PROC_BROWSER_TEST_F(
    BackForwardCacheBrowserTestForHighMemoryDevicesWithBFCacheDisabled,
    HighMemoryDevicesWithBFacheDisabled) {
  // Ensure that IsBackForwardCacheEnabled() returns false, because the
  // BackForwardCache feature is disabled.
  EXPECT_FALSE(IsBackForwardCacheEnabled());

  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
  GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));

  // 1) Navigate to A.
  EXPECT_TRUE(NavigateToURL(shell(), url_a));
  RenderFrameHostImpl* rfh_a = current_frame_host();
  RenderFrameDeletedObserver delete_observer_rfh_a(rfh_a);

  // 2) Navigate to B.
  EXPECT_TRUE(NavigateToURL(shell(), url_b));

  // 3) A shouldn't be stored in back-forward cache because the BackForwardCache
  // feature is disabled.
  delete_observer_rfh_a.WaitUntilDeleted();

  // 4) Go back to check that only kBackForwardCacheDisabled is recorded.
  ASSERT_TRUE(HistoryGoBack(web_contents()));

  ExpectNotRestored(
      {
          BackForwardCacheMetrics::NotRestoredReason::kBackForwardCacheDisabled,
      },
      {}, {}, {}, {}, FROM_HERE);
}

// Start an inifite dialogs in JS, yielding after each. The first dialog should
// be dismissed by navigation. The later dialogs should be handled gracefully
// and not appear while in BFCache. Finally, when the page comes out of BFCache,
// dialogs should appear again.
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
                       CanUseCacheWhenPageAlertsInTimeoutLoop) {
  ASSERT_TRUE(embedded_test_server()->Start());

  GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
  GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));

  // Navigate to A.
  EXPECT_TRUE(NavigateToURL(shell(), url_a));
  RenderFrameHostImpl* rfh_a = current_frame_host();
  RenderFrameDeletedObserver delete_observer_rfh_a(rfh_a);

  AppModalDialogWaiter dialog_waiter(shell());

  EXPECT_TRUE(ExecJs(rfh_a, R"(
    function alertLoop() {
      setTimeout(alertLoop, 0);
      window.alert("alert");
    }
    // Don't block this script.
    setTimeout(alertLoop, 0);
  )"));

  dialog_waiter.Wait();

  // Navigate to B.
  ASSERT_TRUE(NavigateToURL(shell(), url_b));
  RenderFrameHostImpl* rfh_b = current_frame_host();

  ASSERT_FALSE(delete_observer_rfh_a.deleted());
  ASSERT_THAT(rfh_a, InBackForwardCache());
  ASSERT_NE(rfh_a, rfh_b);

  dialog_waiter.Restart();

  // Go back.
  ASSERT_TRUE(HistoryGoBack(web_contents()));
  EXPECT_EQ(rfh_a, current_frame_host());
  EXPECT_FALSE(rfh_a->IsInBackForwardCache());

  // The page should still be requesting dialogs in a loop. Wait for one to be
  // requested.
  dialog_waiter.Wait();
}

// UnloadOldFrame will clear all dialogs. We test that further requests for
// dialogs coming from JS do not result in the creation of a dialog. This test
// posts some dialog creation JS to the render from inside the
// CommitNavigationCallback task. This JS is then able to post a task back to
// the renders to show a dialog. By the time this task runs, we the
// RenderFrameHostImpl's is_active() should be false.
//
// This test is not perfect, it can pass simply because the renderer thread does
// not run the JS in time. Ideally it would block until the renderer posts the
// request for a dialog but it's possible to do that without creating a nested
// message loop and if we do that, we risk processing the dialog request.
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
                       DialogsCancelledAndSuppressedWhenCached) {
  ASSERT_TRUE(embedded_test_server()->Start());

  GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
  GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));

  // Navigate to A.
  EXPECT_TRUE(NavigateToURL(shell(), url_a));
  RenderFrameHostImpl* rfh_a = current_frame_host();
  RenderFrameDeletedObserver delete_observer_rfh_a(rfh_a);

  // Let's us know whether the following callback ran. Not strictly necessary
  // since it really should run.
  bool posted_dialog_js = false;
  // Create a callback that will be called during the DidCommitNavigation task.
  WillEnterBackForwardCacheCallbackForTesting
      will_enter_back_forward_cache_callback =
          base::BindLambdaForTesting([&]() {
            // Post a dialog, it should not result in a dialog being created.
            ExecuteScriptAsync(rfh_a, R"(window.alert("alert");)");
            posted_dialog_js = true;
          });
  rfh_a->render_view_host()->SetWillEnterBackForwardCacheCallbackForTesting(
      will_enter_back_forward_cache_callback);

  AppModalDialogWaiter dialog_waiter(shell());

  // Try show another dialog. It should work.
  ExecuteScriptAsync(rfh_a, R"(window.alert("alert");)");
  dialog_waiter.Wait();

  dialog_waiter.Restart();

  // Navigate to B.
  ASSERT_TRUE(NavigateToURL(shell(), url_b));
  RenderFrameHostImpl* rfh_b = current_frame_host();

  ASSERT_FALSE(delete_observer_rfh_a.deleted());
  ASSERT_THAT(rfh_a, InBackForwardCache());
  ASSERT_NE(rfh_a, rfh_b);
  // Test that the JS was run and that it didn't result in a dialog.
  ASSERT_TRUE(posted_dialog_js);
  ASSERT_FALSE(dialog_waiter.WasDialogRequestedCallbackCalled());

  // Go back.
  ASSERT_TRUE(HistoryGoBack(web_contents()));

  EXPECT_EQ(rfh_a, current_frame_host());
  EXPECT_FALSE(rfh_a->IsInBackForwardCache());

  // Try show another dialog. It should work.
  ExecuteScriptAsync(rfh_a, R"(window.alert("alert");)");
  dialog_waiter.Wait();
}

// Tests that pagehide handlers of the old RFH are run for bfcached pages even
// if the page is already hidden (and visibilitychange won't run).
// Disabled on Linux and Win because of flakiness, see crbug.com/40165901.
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN)
#define MAYBE_PagehideRunsWhenPageIsHidden DISABLED_PagehideRunsWhenPageIsHidden
#else
#define MAYBE_PagehideRunsWhenPageIsHidden PagehideRunsWhenPageIsHidden
#endif
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
                       MAYBE_PagehideRunsWhenPageIsHidden) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url_1(embedded_test_server()->GetURL("a.com", "/title1.html"));
  GURL url_2(embedded_test_server()->GetURL("b.com", "/title2.html"));
  GURL url_3(embedded_test_server()->GetURL("a.com", "/title2.html"));
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());

  // 1) Navigate to |url_1| and hide the tab.
  EXPECT_TRUE(NavigateToURL(shell(), url_1));
  RenderFrameHostImplWrapper main_frame_1(web_contents->GetPrimaryMainFrame());
  // We need to set it to Visibility::VISIBLE first in case this is the first
  // time the visibility is updated.
  web_contents->UpdateWebContentsVisibility(Visibility::VISIBLE);
  web_contents->UpdateWebContentsVisibility(Visibility::HIDDEN);
  EXPECT_EQ(Visibility::HIDDEN, web_contents->GetVisibility());

  // Create a pagehide handler that sets item "pagehide_storage" and a
  // visibilitychange handler that sets item "visibilitychange_storage" in
  // localStorage.
  EXPECT_TRUE(ExecJs(main_frame_1.get(),
                     R"(
    localStorage.setItem('pagehide_storage', 'not_dispatched');
    var dispatched_pagehide = false;
    window.onpagehide = function(e) {
      if (dispatched_pagehide) {
        // We shouldn't dispatch pagehide more than once.
        localStorage.setItem('pagehide_storage', 'dispatched_more_than_once');
      } else if (!e.persisted) {
        localStorage.setItem('pagehide_storage', 'wrong_persisted');
      } else {
        localStorage.setItem('pagehide_storage', 'dispatched_once');
      }
      dispatched_pagehide = true;
    }
    localStorage.setItem('visibilitychange_storage', 'not_dispatched');
    document.onvisibilitychange = function(e) {
      localStorage.setItem('visibilitychange_storage',
        'should_not_be_dispatched');
    }
  )"));
  // |visibilitychange_storage| should be set to its initial correct value.
  EXPECT_EQ("not_dispatched",
            GetLocalStorage(main_frame_1.get(), "visibilitychange_storage"));

  // 2) Navigate cross-site to |url_2|. We need to navigate cross-site to make
  // sure we won't run pagehide and visibilitychange during new page's commit,
  // which is tested in ProactivelySwapBrowsingInstancesSameSiteTest.
  EXPECT_TRUE(NavigateToURL(shell(), url_2));

  // |main_frame_1| should be in the back-forward cache.
  EXPECT_TRUE(main_frame_1->IsInBackForwardCache());

  // 3) Navigate to |url_3| which is same-origin with |url_1|, so we can check
  // the localStorage values.
  EXPECT_TRUE(NavigateToURL(shell(), url_3));
  RenderFrameHostImpl* main_frame_3 = web_contents->GetPrimaryMainFrame();

  // Check that the value for 'pagehide_storage' and 'visibilitychange_storage'
  // are set correctly.
  EXPECT_TRUE(
      WaitForLocalStorage(main_frame_3, "pagehide_storage", "dispatched_once"));
  EXPECT_TRUE(WaitForLocalStorage(main_frame_3, "visibilitychange_storage",
                                  "not_dispatched"));
}

// Tests that we're getting the correct TextInputState and focus updates when a
// page enters the back-forward cache and when it gets restored.
// TODO(b/324570785): Re-enable the test for Android.
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
#define MAYBE_TextInputStateUpdated DISABLED_TextInputStateUpdated
#else
#define MAYBE_TextInputStateUpdated TextInputStateUpdated
#endif
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
                       MAYBE_TextInputStateUpdated) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url_1(embedded_test_server()->GetURL("a.com", "/title1.html"));
  GURL url_2(embedded_test_server()->GetURL("b.com", "/title2.html"));

  // 1) Navigate to |url_1| and add a text input with "foo" as the value.
  EXPECT_TRUE(NavigateToURL(shell(), url_1));
  SimulateEndOfPaintHoldingOnPrimaryMainFrame(web_contents());
  RenderFrameHostImpl* rfh_1 = current_frame_host();
  EXPECT_TRUE(ExecJs(rfh_1,
                     "document.title='bfcached';"
                     "var input = document.createElement('input');"
                     "input.setAttribute('type', 'text');"
                     "input.setAttribute('value', 'foo');"
                     "document.body.appendChild(input);"
                     "var focusCount = 0;"
                     "var blurCount = 0;"
                     "input.onfocus = () => { focusCount++;};"
                     "input.onblur = () => { blurCount++; };"));

  {
    TextInputManagerTypeObserver type_observer(web_contents(),
                                               ui::TEXT_INPUT_TYPE_TEXT);
    TextInputManagerValueObserver value_observer(web_contents(), "foo");
    // 2) Press tab key to focus the <input>, and verify the type & value.
    SimulateKeyPress(web_contents(), ui::DomKey::TAB, ui::DomCode::TAB,
                     ui::VKEY_TAB, false, false, false, false);
    type_observer.Wait();
    value_observer.Wait();

    EXPECT_EQ(rfh_1, web_contents()->GetFocusedFrame());
    EXPECT_EQ(EvalJs(rfh_1, "focusCount").ExtractInt(), 1);
    EXPECT_EQ(EvalJs(rfh_1, "blurCount").ExtractInt(), 0);
  }

  {
    TextInputManagerTester tester(web_contents());
    TextInputManagerValueObserver value_observer(web_contents(), "A");
    // 3) Press the "A" key to change the text input value. This should notify
    // the browser that the text input value has changed.
    SimulateKeyPress(web_contents(), ui::DomKey::FromCharacter('A'),
                     ui::DomCode::US_A, ui::VKEY_A, false, false, false, false);
    value_observer.Wait();

    EXPECT_EQ(rfh_1, web_contents()->GetFocusedFrame());
    EXPECT_EQ(EvalJs(rfh_1, "focusCount").ExtractInt(), 1);
    EXPECT_EQ(EvalJs(rfh_1, "blurCount").ExtractInt(), 0);
  }

  {
    TextInputManagerTypeObserver type_observer(web_contents(),
                                               ui::TEXT_INPUT_TYPE_NONE);
    // 4) Navigating to |url_2| should reset type to TEXT_INPUT_TYPE_NONE.
    EXPECT_TRUE(NavigateToURL(shell(), url_2));
    type_observer.Wait();
    // |rfh_1| should get into the back-forward cache.
    EXPECT_TRUE(rfh_1->IsInBackForwardCache());
    EXPECT_EQ(current_frame_host(), web_contents()->GetFocusedFrame());
    EXPECT_NE(rfh_1, web_contents()->GetFocusedFrame());
  }

  {
    // 5) Navigating back to |url_1|, we shouldn't restore the focus to the
    // text input, but |rfh_1| will be focused again as we will restore focus
    // to main frame after navigation.
    ASSERT_TRUE(HistoryGoBack(web_contents()));

    EXPECT_EQ(rfh_1, web_contents()->GetFocusedFrame());
    EXPECT_EQ(EvalJs(rfh_1, "focusCount").ExtractInt(), 1);
    EXPECT_EQ(EvalJs(rfh_1, "blurCount").ExtractInt(), 1);
  }

  {
    TextInputManagerTypeObserver type_observer(web_contents(),
                                               ui::TEXT_INPUT_TYPE_TEXT);
    TextInputManagerValueObserver value_observer(web_contents(), "A");
    // 6) Press tab key to focus the <input> again. Note that we need to press
    // the tab key twice here, because the last "tab focus" point was the
    // <input> element. The first tab key press would focus on the UI/url bar,
    // then the second tab key would go back to the <input>.
    SimulateKeyPress(web_contents(), ui::DomKey::TAB, ui::DomCode::TAB,
                     ui::VKEY_TAB, false, false, false, false);
    SimulateKeyPress(web_contents(), ui::DomKey::TAB, ui::DomCode::TAB,
                     ui::VKEY_TAB, false, false, false, false);
    type_observer.Wait();
    value_observer.Wait();

    EXPECT_EQ(rfh_1, web_contents()->GetFocusedFrame());
    EXPECT_EQ(EvalJs(rfh_1, "focusCount").ExtractInt(), 2);
    EXPECT_EQ(EvalJs(rfh_1, "blurCount").ExtractInt(), 1);
  }
}

#if (BUILDFLAG(IS_MAC) || BUILDFLAG(IS_ANDROID))
#define MAYBE_SubframeTextInputStateUpdated DISABLED_SubframeTextInputStateUpdated
#else
#define MAYBE_SubframeTextInputStateUpdated SubframeTextInputStateUpdated
#endif
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
                       MAYBE_SubframeTextInputStateUpdated) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url_1(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(a))"));
  GURL url_2(embedded_test_server()->GetURL("b.com", "/title2.html"));

  // 1) Navigate to |url_1| and add a text input with "foo" as the value in the
  // a.com subframe.
  EXPECT_TRUE(NavigateToURL(shell(), url_1));
  SimulateEndOfPaintHoldingOnPrimaryMainFrame(web_contents());
  RenderFrameHostImpl* rfh_a = current_frame_host();
  RenderFrameHostImpl* rfh_b = rfh_a->child_at(0)->current_frame_host();
  RenderFrameHostImpl* rfh_subframe_a =
      rfh_b->child_at(0)->current_frame_host();
  EXPECT_TRUE(ExecJs(rfh_subframe_a,
                     "var input = document.createElement('input');"
                     "input.setAttribute('type', 'text');"
                     "input.setAttribute('value', 'foo');"
                     "document.body.appendChild(input);"
                     "var focusCount = 0;"
                     "var blurCount = 0;"
                     "input.onfocus = () => { focusCount++;};"
                     "input.onblur = () => { blurCount++; };"));

  {
    TextInputManagerTypeObserver type_observer(web_contents(),
                                               ui::TEXT_INPUT_TYPE_TEXT);
    TextInputManagerValueObserver value_observer(web_contents(), "foo");
    // 2) Press tab key to focus the <input>, and verify the type & value.
    SimulateKeyPress(web_contents(), ui::DomKey::TAB, ui::DomCode::TAB,
                     ui::VKEY_TAB, false, false, false, false);
    type_observer.Wait();
    value_observer.Wait();

    EXPECT_EQ(rfh_subframe_a, web_contents()->GetFocusedFrame());
    EXPECT_EQ(EvalJs(rfh_subframe_a, "focusCount").ExtractInt(), 1);
    EXPECT_EQ(EvalJs(rfh_subframe_a, "blurCount").ExtractInt(), 0);
  }

  {
    TextInputManagerTester tester(web_contents());
    TextInputManagerValueObserver value_observer(web_contents(), "A");
    // 3) Press the "A" key to change the text input value. This should notify
    // the browser that the text input value has changed.
    SimulateKeyPress(web_contents(), ui::DomKey::FromCharacter('A'),
                     ui::DomCode::US_A, ui::VKEY_A, false, false, false, false);
    value_observer.Wait();

    EXPECT_EQ(rfh_subframe_a, web_contents()->GetFocusedFrame());
    EXPECT_EQ(EvalJs(rfh_subframe_a, "focusCount").ExtractInt(), 1);
    EXPECT_EQ(EvalJs(rfh_subframe_a, "blurCount").ExtractInt(), 0);
  }

  {
    TextInputManagerTypeObserver type_observer(web_contents(),
                                               ui::TEXT_INPUT_TYPE_NONE);
    // 4) Navigating to |url_2| should reset type to TEXT_INPUT_TYPE_NONE and
    // changed focus to the new page's main frame.
    EXPECT_TRUE(NavigateToURL(shell(), url_2));
    type_observer.Wait();

    // |rfh_a| and its subframes should get into the back-forward cache.
    EXPECT_TRUE(rfh_a->IsInBackForwardCache());
    EXPECT_TRUE(rfh_b->IsInBackForwardCache());
    EXPECT_TRUE(rfh_subframe_a->IsInBackForwardCache());
    EXPECT_NE(rfh_subframe_a, web_contents()->GetFocusedFrame());
  }

  {
    // 5) Navigating back to |url_1|, we shouldn't restore the focus to the
    // text input in the subframe (we will focus on the main frame |rfh_a|
    // instead).
    ASSERT_TRUE(HistoryGoBack(web_contents()));

    EXPECT_EQ(rfh_a, web_contents()->GetFocusedFrame());
    EXPECT_EQ(EvalJs(rfh_subframe_a, "focusCount").ExtractInt(), 1);
    EXPECT_EQ(EvalJs(rfh_subframe_a, "blurCount").ExtractInt(), 1);
  }

  {
    TextInputManagerTypeObserver type_observer(web_contents(),
                                               ui::TEXT_INPUT_TYPE_TEXT);
    TextInputManagerValueObserver value_observer(web_contents(), "A");
    // 6) Press tab key to focus the <input> again.
    SimulateKeyPress(web_contents(), ui::DomKey::TAB, ui::DomCode::TAB,
                     ui::VKEY_TAB, false, false, false, false);
    type_observer.Wait();
    value_observer.Wait();

    EXPECT_EQ(rfh_subframe_a, web_contents()->GetFocusedFrame());
    EXPECT_EQ(EvalJs(rfh_subframe_a, "focusCount").ExtractInt(), 2);
    EXPECT_EQ(EvalJs(rfh_subframe_a, "blurCount").ExtractInt(), 1);
  }
}

// Tests that trying to focus on a BFCached cross-site iframe won't crash.
// See https://crbug.com/1250218.
// TODO(crbug.com/40856039): Flaky on linux tsan
#if BUILDFLAG(IS_LINUX) && defined(THREAD_SANITIZER)
#define MAYBE_FocusSameSiteSubframeOnPagehide \
  DISABLED_FocusSameSiteSubframeOnPagehide
#else
#define MAYBE_FocusSameSiteSubframeOnPagehide FocusSameSiteSubframeOnPagehide
#endif
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
                       MAYBE_FocusSameSiteSubframeOnPagehide) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL main_url(
      embedded_test_server()->GetURL("a.com", "/page_with_iframe.html"));
  GURL main_url_2(embedded_test_server()->GetURL("b.com", "/title2.html"));

  // 1) Navigate to a page with a same-site iframe.
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  RenderFrameHostImplWrapper rfh_1(current_frame_host());
  EXPECT_EQ(rfh_1.get(), web_contents()->GetFocusedFrame());

  // 2) Navigate away from the page while trying to focus the subframe on
  // pagehide. The DidFocusFrame IPC should arrive after the page gets into
  // BFCache and should be ignored by the browser. The focus after navigation
  // should go to the new main frame.
  EXPECT_TRUE(ExecJs(rfh_1.get(), R"(
    window.onpagehide = function(e) {
      document.getElementById("test_iframe").focus();
  })"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url_2));
  EXPECT_TRUE(rfh_1->IsInBackForwardCache());
  EXPECT_NE(rfh_1.get(), web_contents()->GetFocusedFrame());
  EXPECT_EQ(current_frame_host(), web_contents()->GetFocusedFrame());

  // 3) Navigate back to the page. The focus should be on the main frame.
  ASSERT_TRUE(HistoryGoBack(web_contents()));
  EXPECT_EQ(rfh_1.get(), web_contents()->GetFocusedFrame());
  ExpectRestored(FROM_HERE);
}

// Tests that trying to focus on a BFCached cross-site iframe won't crash.
// See https://crbug.com/1250218.
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
                       FocusCrossSiteSubframeOnPagehide) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  GURL main_url_2(embedded_test_server()->GetURL("b.com", "/title2.html"));

  // 1) Navigate to a page with a cross-site iframe.
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  RenderFrameHostImplWrapper rfh_1(current_frame_host());
  EXPECT_EQ(rfh_1.get(), web_contents()->GetFocusedFrame());

  // 2) Navigate away from the page while trying to focus the subframe on
  // pagehide. The DidFocusFrame IPC should arrive after the page gets into
  // BFCache and should be ignored by the browser. The focus after navigation
  // should go to the new main frame.
  EXPECT_TRUE(ExecJs(rfh_1.get(), R"(
    window.onpagehide = function(e) {
      document.getElementById("child-0").focus();
    })"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url_2));
  EXPECT_TRUE(rfh_1->IsInBackForwardCache());
  EXPECT_NE(rfh_1.get(), web_contents()->GetFocusedFrame());

  // 3) Navigate back to the page. The focus should be on the original page's
  // main frame.
  ASSERT_TRUE(HistoryGoBack(web_contents()));
  EXPECT_EQ(rfh_1.get(), current_frame_host());
  ExpectRestored(FROM_HERE);
}

IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
                       MainDocumentCSPHeadersAreRestored) {
  ASSERT_TRUE(embedded_test_server()->Start());

  GURL url_a(embedded_test_server()->GetURL(
      "a.com",
      "/set-header?"
      "Content-Security-Policy: frame-src 'none'"));
  GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));

  // 1) Navigate to A, which should set CSP.
  EXPECT_TRUE(NavigateToURL(shell(), url_a));
  RenderFrameHostImpl* rfh_a = current_frame_host();

  // Check that CSP was set.
  {
    const std::vector<network::mojom::ContentSecurityPolicyPtr>& root_csp =
        current_frame_host()
            ->policy_container_host()
            ->policies()
            .content_security_policies;
    EXPECT_EQ(1u, root_csp.size());
    EXPECT_EQ("frame-src 'none'", root_csp[0]->header->header_value);
  }

  // 2) Navigate to B.
  EXPECT_TRUE(NavigateToURL(shell(), url_b));

  // 3) Navigate back and expect that the CSP headers are present on the main
  // frame.
  ASSERT_TRUE(HistoryGoBack(web_contents()));
  EXPECT_EQ(rfh_a, current_frame_host());
  ExpectRestored(FROM_HERE);

  // Check that CSP was restored.
  {
    const std::vector<network::mojom::ContentSecurityPolicyPtr>& root_csp =
        current_frame_host()
            ->policy_container_host()
            ->policies()
            .content_security_policies;
    EXPECT_EQ(1u, root_csp.size());
    EXPECT_EQ("frame-src 'none'", root_csp[0]->header->header_value);
  }
}

// Check that sandboxed documents are cached and won't lose their sandbox flags
// after restoration.
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, CspSandbox) {
  ASSERT_TRUE(embedded_test_server()->Start());

  GURL url_a(
      embedded_test_server()->GetURL("a.com",
                                     "/set-header?"
                                     "Content-Security-Policy: sandbox"));
  GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));

  // 1) Navigate to A, which should set CSP.
  EXPECT_TRUE(NavigateToURL(shell(), url_a));
  RenderFrameHostImpl* rfh_a = current_frame_host();
  RenderFrameDeletedObserver delete_observer_rfh_a(rfh_a);
  {
    const std::vector<network::mojom::ContentSecurityPolicyPtr>& root_csp =
        current_frame_host()
            ->policy_container_host()
            ->policies()
            .content_security_policies;
    ASSERT_EQ(1u, root_csp.size());
    ASSERT_EQ("sandbox", root_csp[0]->header->header_value);
    ASSERT_EQ(network::mojom::WebSandboxFlags::kAll,
              current_frame_host()->active_sandbox_flags());
  }

  // 2) Navigate to B. Expect the previous RenderFrameHost to enter the bfcache.
  EXPECT_TRUE(NavigateToURL(shell(), url_b));
  EXPECT_FALSE(delete_observer_rfh_a.deleted());
  EXPECT_TRUE(rfh_a->IsInBackForwardCache());
  {
    const std::vector<network::mojom::ContentSecurityPolicyPtr>& root_csp =
        current_frame_host()
            ->policy_container_host()
            ->policies()
            .content_security_policies;
    ASSERT_EQ(0u, root_csp.size());
    ASSERT_EQ(network::mojom::WebSandboxFlags::kNone,
              current_frame_host()->active_sandbox_flags());
  }

  // 3) Navigate back and expect the page to be restored, with the correct
  // CSP and sandbox flags.
  ASSERT_TRUE(HistoryGoBack(web_contents()));
  EXPECT_FALSE(delete_observer_rfh_a.deleted());
  EXPECT_EQ(current_frame_host(), rfh_a);
  {
    const std::vector<network::mojom::ContentSecurityPolicyPtr>& root_csp =
        current_frame_host()
            ->policy_container_host()
            ->policies()
            .content_security_policies;
    ASSERT_EQ(1u, root_csp.size());
    ASSERT_EQ("sandbox", root_csp[0]->header->header_value);
    ASSERT_EQ(network::mojom::WebSandboxFlags::kAll,
              current_frame_host()->active_sandbox_flags());
  }
}

// Check that about:blank is not cached.
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, AboutBlankWillNotBeCached) {
  ASSERT_TRUE(embedded_test_server()->Start());

  // 1) Navigate to about:blank.
  GURL blank_url(url::kAboutBlankURL);
  EXPECT_TRUE(NavigateToURL(shell(), blank_url));
  RenderFrameHostImplWrapper rfh_blank(current_frame_host());

  // 2) Navigate to a.com.
  GURL url_a(embedded_test_server()->GetURL("a.com", "/empty.html"));
  EXPECT_TRUE(NavigateToURL(shell(), url_a));

  // 3) Navigate back to about:blank.
  ASSERT_TRUE(HistoryGoBack(web_contents()));

  // This about:blank document does not have a SiteInstance and then loading a
  // page on it doesn't swap the browsing instance.

  if (ShouldCreateNewHostForAllFrames()) {
    EXPECT_TRUE(rfh_blank.WaitUntilRenderFrameDeleted());
    ExpectNotRestored(
        {
            BackForwardCacheMetrics::NotRestoredReason::kHTTPStatusNotOK,
            BackForwardCacheMetrics::NotRestoredReason::kSchemeNotHTTPOrHTTPS,
            BackForwardCacheMetrics::NotRestoredReason::
                kBrowsingInstanceNotSwapped,
        },
        {}, {ShouldSwapBrowsingInstance::kNo_DoesNotHaveSite}, {}, {},
        FROM_HERE);

  } else {
    EXPECT_FALSE(rfh_blank->IsInBackForwardCache());
    ExpectNotRestored(
        {
            BackForwardCacheMetrics::NotRestoredReason::
                kBrowsingInstanceNotSwapped,
        },
        {}, {ShouldSwapBrowsingInstance::kNo_DoesNotHaveSite}, {}, {},
        FROM_HERE);
  }
}

// Check that browsing instances are not swapped when a navigation redirects
// toward the last committed URL and the reasons are recorded correctly.
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, RedirectToSelf) {
  ASSERT_TRUE(embedded_test_server()->Start());
  NavigationControllerImpl& controller = web_contents()->GetController();

  // 1) Navigate to a.com/empty.html.
  GURL url_a(embedded_test_server()->GetURL("a.com", "/empty.html"));
  EXPECT_TRUE(NavigateToURL(shell(), url_a));
  RenderFrameHostImplWrapper rfh_a(current_frame_host());
  EXPECT_EQ(1, controller.GetEntryCount());
  EXPECT_EQ(url_a, controller.GetLastCommittedEntry()->GetURL());

  // 2) Navigate to the same page by redirection.
  GURL url_a2(embedded_test_server()->GetURL(
      "a.com", "/server-redirect-301?" + url_a.spec()));
  EXPECT_TRUE(NavigateToURL(shell(), url_a2, url_a));
  RenderFrameHostImplWrapper rfh_b(current_frame_host());
  EXPECT_EQ(2, controller.GetEntryCount());

  if (ShouldCreateNewHostForAllFrames()) {
    EXPECT_TRUE(rfh_a.WaitUntilRenderFrameDeleted());
  } else {
    EXPECT_FALSE(rfh_a->IsInBackForwardCache());
    EXPECT_TRUE(rfh_a->GetSiteInstance()->IsRelatedSiteInstance(
        rfh_b->GetSiteInstance()));
  }

  EXPECT_EQ(url_a, controller.GetLastCommittedEntry()->GetURL());

  // 3) Navigate back to the previous page.
  ASSERT_TRUE(HistoryGoBack(web_contents()));
  EXPECT_EQ(2, controller.GetEntryCount());
  EXPECT_EQ(url_a, controller.GetLastCommittedEntry()->GetURL());

  // TODO(crbug.com/40760515): Investigate whether these navigation results are
  // expected.
  ExpectNotRestored(
      {
          BackForwardCacheMetrics::NotRestoredReason::
              kBrowsingInstanceNotSwapped,
      },
      {}, {ShouldSwapBrowsingInstance::kNo_SameUrlNavigation}, {}, {},
      FROM_HERE);
}

// Check that reloading doesn't affect the back-forward cache usage.
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, ReloadDoesntAffectCache) {
  ASSERT_TRUE(embedded_test_server()->Start());
  NavigationControllerImpl& controller = web_contents()->GetController();

  // 1) Navigate to a.com.
  GURL url_a(embedded_test_server()->GetURL("a.com", "/empty.html"));
  EXPECT_TRUE(NavigateToURL(shell(), url_a));
  EXPECT_EQ(1, controller.GetEntryCount());
  EXPECT_EQ(url_a, controller.GetLastCommittedEntry()->GetURL());

  // 2) Navigate to b.com.
  GURL url_b(embedded_test_server()->GetURL("b.com", "/empty.html"));
  EXPECT_TRUE(NavigateToURL(shell(), url_b));
  EXPECT_EQ(2, controller.GetEntryCount());
  EXPECT_EQ(url_b, controller.GetLastCommittedEntry()->GetURL());

  // 3) Go back to a.com and reload.
  ASSERT_TRUE(HistoryGoBack(web_contents()));
  EXPECT_EQ(2, controller.GetEntryCount());
  EXPECT_EQ(url_a, controller.GetLastCommittedEntry()->GetURL());

  ExpectRestored(FROM_HERE);

  // 4) Reload the tab.
  web_contents()->GetController().Reload(content::ReloadType::NORMAL, false);
  EXPECT_TRUE(WaitForLoadStop(web_contents()));
  EXPECT_EQ(2, controller.GetEntryCount());
  EXPECT_EQ(url_a, controller.GetLastCommittedEntry()->GetURL());

  // By reloading the tab, ShouldSwapBrowsingInstance::
  // kNo_AlreadyHasMatchingBrowsingInstance is set once. This should be reset
  // when the navigation 4)'s commit finishes and should not prevent putting the
  // page into the back-forward cache.
  //
  // Note that SetBrowsingInstanceSwapResult might not be called for every
  // navigation because we might not get to this point for some navigations,
  // e.g. if the navigation uses a pre-existing RenderFrameHost and SiteInstance
  // for navigation.
  //
  // TODO(crbug.com/40747698): Tie BrowsingInstanceSwapResult to
  // NavigationRequest instead and move the SetBrowsingInstanceSwapResult call
  // for navigations to happen at commit time instead.

  // 5) Go forward to b.com and reload.
  ASSERT_TRUE(HistoryGoForward(web_contents()));
  EXPECT_EQ(2, controller.GetEntryCount());
  EXPECT_EQ(url_b, controller.GetLastCommittedEntry()->GetURL());

  // The page loaded at B) is correctly cached and restored. Reloading doesn't
  // affect the cache usage.
  ExpectRestored(FROM_HERE);

  // 6) Go back to a.com.
  ASSERT_TRUE(HistoryGoBack(web_contents()));
  EXPECT_EQ(2, controller.GetEntryCount());
  EXPECT_EQ(url_a, controller.GetLastCommittedEntry()->GetURL());

  // The page loaded at 3) is correctly cached and restored. Reloading doesn't
  // affect the cache usage.
  ExpectRestored(FROM_HERE);
}

// Regression test for crbug.com/1183313. Checks that CommitNavigationParam's
// |has_user_gesture| value reflects the gesture from the latest navigation
// after the commit finished.
IN_PROC_BROWSER_TEST_F(
    BackForwardCacheBrowserTest,
    SameDocumentNavAfterRestoringDocumentLoadedWithUserGesture) {
  ASSERT_TRUE(embedded_test_server()->Start());

  GURL start_url(embedded_test_server()->GetURL("/title1.html"));
  GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
  GURL url_a_foo(embedded_test_server()->GetURL("a.com", "/title1.html#foo"));
  GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));
  NavigationControllerImpl& controller = web_contents()->GetController();
  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetPrimaryFrameTree()
                            .root();

  // Initial navigation (so that we can initiate a navigation from renderer).
  EXPECT_TRUE(NavigateToURL(shell(), start_url));

  // 1) Navigate to A with user gesture.
  {
    FrameNavigateParamsCapturer params_capturer(root);
    EXPECT_TRUE(NavigateToURLFromRenderer(shell(), url_a));
    params_capturer.Wait();
    EXPECT_TRUE(params_capturer.has_user_gesture());
    EXPECT_TRUE(root->current_frame_host()
                    ->last_committed_common_params_has_user_gesture());
  }
  RenderFrameHostImpl* rfh_a = current_frame_host();

  // 2) Navigate to B. A should be stored in the back-forward cache.
  EXPECT_TRUE(NavigateToURL(shell(), url_b));
  EXPECT_TRUE(rfh_a->IsInBackForwardCache());
  EXPECT_FALSE(root->current_frame_host()
                   ->last_committed_common_params_has_user_gesture());

  // 3) GoBack to A. RenderFrameHost of A should be restored from the
  // back-forward cache, and "has_user_gesture" is set to false correctly.
  // Note that since this is a back-forward cache restore we create the
  // DidCommitProvisionalLoadParams completely in the browser, so we got the
  // correct value from the latest navigation. However, we did not update the
  // renderer's navigation-related values, so the renderer's DocumentLoader
  // still thinks the last "gesture" value is "true", which will get corrected
  // on the next navigation.
  {
    FrameNavigateParamsCapturer params_capturer(root);
    controller.GoBack();
    params_capturer.Wait();
    EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
    EXPECT_EQ(rfh_a, current_frame_host());
    // The navigation doesn't have user gesture.
    EXPECT_FALSE(params_capturer.has_user_gesture());
    EXPECT_FALSE(root->current_frame_host()
                     ->last_committed_common_params_has_user_gesture());
  }

  // 4) Same-document navigation to A#foo without user gesture. At this point
  // we will update the renderer's DocumentLoader's latest gesture value to
  // "no user gesture", and we'll get the correct gesture value in
  // DidCommitProvisionalLoadParams.
  {
    FrameNavigateParamsCapturer params_capturer(root);
    EXPECT_TRUE(
        NavigateToURLFromRendererWithoutUserGesture(shell(), url_a_foo));
    params_capturer.Wait();
    // The navigation doesn't have user gesture.
    EXPECT_FALSE(params_capturer.has_user_gesture());
    EXPECT_FALSE(root->current_frame_host()
                     ->last_committed_common_params_has_user_gesture());
  }
}

testing::Matcher<BackForwardCacheCanStoreTreeResult> MatchesTreeResult(
    testing::Matcher<bool> same_origin,
    GURL url) {
  return testing::AllOf(
      testing::Property("IsSameOrigin",
                        &BackForwardCacheCanStoreTreeResult::IsSameOrigin,
                        same_origin),
      testing::Property("GetUrl", &BackForwardCacheCanStoreTreeResult::GetUrl,
                        url));
}

RenderFrameHostImpl* ChildFrame(RenderFrameHostImpl* rfh, int child_index) {
  return rfh->child_at(child_index)->current_frame_host();
}

// Verifies that the reasons match those given and no others.
testing::Matcher<BackForwardCacheCanStoreDocumentResult>
BackForwardCacheBrowserTest::MatchesDocumentResult(
    testing::Matcher<NotRestoredReasons> not_stored,
    BlockListedFeatures block_listed) {
  return testing::AllOf(
      testing::Property(
          "not_restored_reasons",
          &BackForwardCacheCanStoreDocumentResult::not_restored_reasons,
          not_stored),
      testing::Property(
          "blocklisted_features",
          &BackForwardCacheCanStoreDocumentResult::blocklisted_features,
          block_listed),
      testing::Property(
          "disabled_reasons",
          &BackForwardCacheCanStoreDocumentResult::disabled_reasons,
          BackForwardCacheCanStoreDocumentResult::DisabledReasonsMap()),
      testing::Property(
          "disallow_activation_reasons",
          &BackForwardCacheCanStoreDocumentResult::disallow_activation_reasons,
          std::set<uint64_t>()));
}

// Check the contents of the BackForwardCacheCanStoreTreeResult of a page.
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, TreeResultFeatureUsage) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url_a(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a, b, c)"));
  GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));

  // 1) Navigate to a(a, b, c).
  ASSERT_TRUE(NavigateToURL(shell(), url_a));
  RenderFrameHostImplWrapper rfh(current_frame_host());

  // 2) Add a blocking feature to the main frame A and the sub frame B.
  current_frame_host()
      ->UseDummyStickyBackForwardCacheDisablingFeatureForTesting();
  current_frame_host()
      ->child_at(1)
      ->current_frame_host()
      ->UseDummyStickyBackForwardCacheDisablingFeatureForTesting();

  GURL url_subframe_a = ChildFrame(rfh.get(), 0)->GetLastCommittedURL();
  GURL url_subframe_b = ChildFrame(rfh.get(), 1)->GetLastCommittedURL();
  GURL url_subframe_c = ChildFrame(rfh.get(), 2)->GetLastCommittedURL();

  // 3) Initialize the reasons tree and navigate away to ensure that everything
  // from the old frame has been destroyed.
  BackForwardCacheCanStoreDocumentResultWithTree can_store_result =
      web_contents()
          ->GetController()
          .GetBackForwardCache()
          .GetCurrentBackForwardCacheEligibility(rfh.get());
  ASSERT_TRUE(NavigateToURL(shell(), url_b));
  ASSERT_TRUE(rfh.WaitUntilRenderFrameDeleted());

  // 4) Check IsSameOrigin() and GetUrl().
  // a
  EXPECT_THAT(*can_store_result.tree_reasons,
              MatchesTreeResult(/*same_origin=*/true,
                                /*url=*/url_a));
  // a->a
  EXPECT_THAT(*can_store_result.tree_reasons->GetChildren().at(0),
              MatchesTreeResult(/*same_origin=*/true,
                                /*url=*/url_subframe_a));
  // a->b
  EXPECT_THAT(*can_store_result.tree_reasons->GetChildren().at(1),
              MatchesTreeResult(/*same_origin=*/false,
                                /*url=*/url_subframe_b));
  // a->c
  EXPECT_THAT(*can_store_result.tree_reasons->GetChildren().at(2),
              MatchesTreeResult(/*same_origin=*/false,
                                /*url=*/url_subframe_c));

  // 5) Check that the blocking reasons match.
  // a
  EXPECT_THAT(can_store_result.tree_reasons->GetDocumentResult(),
              MatchesDocumentResult(
                  NotRestoredReasons({NotRestoredReason::kBlocklistedFeatures}),
                  BlockListedFeatures(
                      {blink::scheduler::WebSchedulerTrackedFeature::kDummy})));
  // a->a
  EXPECT_THAT(
      can_store_result.tree_reasons->GetChildren().at(0)->GetDocumentResult(),
      MatchesDocumentResult(NotRestoredReasons(),
                            BlockListedFeatures(BlockListedFeatures())));
  // a->b
  EXPECT_THAT(
      can_store_result.tree_reasons->GetChildren().at(1)->GetDocumentResult(),
      MatchesDocumentResult(
          NotRestoredReasons({NotRestoredReason::kBlocklistedFeatures}),
          BlockListedFeatures(
              {blink::scheduler::WebSchedulerTrackedFeature::kDummy})));
  // a->c
  EXPECT_THAT(
      can_store_result.tree_reasons->GetChildren().at(2)->GetDocumentResult(),
      MatchesDocumentResult(NotRestoredReasons(),
                            BlockListedFeatures(BlockListedFeatures())));
}

// Check the contents of the BackForwardCacheCanStoreTreeResult of a page when
// it is evicted.
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
                       TreeResultEvictionMainFrame) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
  GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));

  // 1) Navigate to a.
  ASSERT_TRUE(NavigateToURL(shell(), url_a));
  RenderFrameHostImplWrapper rfh_a(current_frame_host());
  rfh_a->GetBackForwardCacheMetrics()->SetObserverForTesting(this);

  // 2) Navigate to B and evict A by JavaScript execution.
  ASSERT_TRUE(NavigateToURL(shell(), url_b));
  EvictByJavaScript(rfh_a.get());
  ASSERT_TRUE(rfh_a.WaitUntilRenderFrameDeleted());

  // 3) Go back to A.
  ASSERT_TRUE(HistoryGoBack(web_contents()));
  ExpectNotRestored({NotRestoredReason::kJavaScriptExecution}, {}, {}, {}, {},
                    FROM_HERE);
  EXPECT_THAT(GetTreeResult()->GetDocumentResult(),
              MatchesDocumentResult(
                  NotRestoredReasons({NotRestoredReason::kJavaScriptExecution}),
                  BlockListedFeatures()));
}

// Check the contents of the BackForwardCacheCanStoreTreeResult of a page when
// its subframe is evicted.
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
                       TreeResultEvictionSubFrame) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url_a(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  GURL url_c(embedded_test_server()->GetURL("c.com", "/title1.html"));

  // 1) Navigate to A.
  ASSERT_TRUE(NavigateToURL(shell(), url_a));
  RenderFrameHostImplWrapper rfh_a(current_frame_host());
  RenderFrameHostImplWrapper rfh_b(
      current_frame_host()->child_at(0)->current_frame_host());
  rfh_a->GetBackForwardCacheMetrics()->SetObserverForTesting(this);

  // 2) Navigate to C and evict A's subframe B by JavaScript execution.
  ASSERT_TRUE(NavigateToURL(shell(), url_c));
  EvictByJavaScript(rfh_b.get());
  ASSERT_TRUE(rfh_a.WaitUntilRenderFrameDeleted());

  // 3) Go back to A.
  ASSERT_TRUE(HistoryGoBack(web_contents()));
  ExpectNotRestored({NotRestoredReason::kJavaScriptExecution}, {}, {}, {}, {},
                    FROM_HERE);
  // Main frame result in the tree is empty.
  EXPECT_THAT(
      GetTreeResult()->GetDocumentResult(),
      MatchesDocumentResult(NotRestoredReasons(), BlockListedFeatures()));
  // Subframe result in the tree contains the reason.
  EXPECT_THAT(GetTreeResult()->GetChildren().at(0)->GetDocumentResult(),
              MatchesDocumentResult(
                  NotRestoredReasons({NotRestoredReason::kJavaScriptExecution}),
                  BlockListedFeatures()));
}

// Check the contents of the BackForwardCacheCanStoreTreeResult of a page when
// its subframe's subframe is evicted.
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
                       TreeResultEvictionSubFramesSubframe) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url_a(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(c))"));
  GURL url_d(embedded_test_server()->GetURL("d.com", "/title1.html"));

  // 1) Navigate to A.
  ASSERT_TRUE(NavigateToURL(shell(), url_a));
  RenderFrameHostImplWrapper rfh_a(current_frame_host());
  RenderFrameHostImplWrapper rfh_c(current_frame_host()
                                       ->child_at(0)
                                       ->current_frame_host()
                                       ->child_at(0)
                                       ->current_frame_host());
  rfh_a->GetBackForwardCacheMetrics()->SetObserverForTesting(this);

  // 2) Navigate to D and evict C by JavaScript execution.
  ASSERT_TRUE(NavigateToURL(shell(), url_d));
  EvictByJavaScript(rfh_c.get());
  ASSERT_TRUE(rfh_a.WaitUntilRenderFrameDeleted());

  // 3) Go back to A.
  ASSERT_TRUE(HistoryGoBack(web_contents()));
  ExpectNotRestored({NotRestoredReason::kJavaScriptExecution}, {}, {}, {}, {},
                    FROM_HERE);
  // Main frame result in the tree is empty.
  EXPECT_THAT(
      GetTreeResult()->GetDocumentResult(),
      MatchesDocumentResult(NotRestoredReasons(), BlockListedFeatures()));
  // The first level subframe result in the tree is empty.
  EXPECT_THAT(
      GetTreeResult()->GetChildren().at(0)->GetDocumentResult(),
      MatchesDocumentResult(NotRestoredReasons(), BlockListedFeatures()));
  // The second level subframe result in the tree contains the reason.
  EXPECT_THAT(GetTreeResult()
                  ->GetChildren()
                  .at(0)
                  ->GetChildren()
                  .at(0)
                  ->GetDocumentResult(),
              MatchesDocumentResult(
                  NotRestoredReasons({NotRestoredReason::kJavaScriptExecution}),
                  BlockListedFeatures()));
}

void BackForwardCacheBrowserTest::InstallUnloadHandlerOnMainFrame() {
  EXPECT_TRUE(ExecJs(current_frame_host(), R"(
      localStorage["unload_run_count"] = 0;
      window.onunload = () => {
        localStorage["unload_run_count"] =
            1 + parseInt(localStorage["unload_run_count"]);
      };
    )"));
  EXPECT_EQ("0", GetUnloadRunCount());
}

void BackForwardCacheBrowserTest::InstallUnloadHandlerOnSubFrame() {
  TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
  EXPECT_TRUE(ExecJs(current_frame_host(), R"(
      const iframeElement = document.createElement("iframe");
      iframeElement.src = "%s";
      document.body.appendChild(iframeElement);
    )"));
  navigation_observer.Wait();
  RenderFrameHostImpl* subframe_render_frame_host =
      current_frame_host()->child_at(0)->current_frame_host();
  EXPECT_TRUE(ExecJs(subframe_render_frame_host, R"(
      localStorage["unload_run_count"] = 0;
      window.onunload = () => {
        localStorage["unload_run_count"] =
            1 + parseInt(localStorage["unload_run_count"]);
      };
    )"));
  EXPECT_EQ("0", GetUnloadRunCount());
}

EvalJsResult BackForwardCacheBrowserTest::GetUnloadRunCount() {
  return GetLocalStorage(current_frame_host(), "unload_run_count");
}

bool BackForwardCacheBrowserTest::AddBlocklistedFeature(RenderFrameHost* rfh) {
  // Add kDummy as blocking feature.
  RenderFrameHostImplWrapper rfh_a(rfh);
  rfh_a->UseDummyStickyBackForwardCacheDisablingFeatureForTesting();
  return true;
}

void BackForwardCacheBrowserTest::ExpectNotRestoredDueToBlocklistedFeature(
    base::Location location) {
  ExpectNotRestored({NotRestoredReason::kBlocklistedFeatures},
                    {blink::scheduler::WebSchedulerTrackedFeature::kDummy}, {},
                    {}, {}, location);
}

const ukm::TestAutoSetUkmRecorder& BackForwardCacheBrowserTest::ukm_recorder() {
  return *ukm_recorder_;
}

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

// Ensure that psges with unload are only allowed to enter back/forward cache by
// default on Android.
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, UnloadAllowedFlag) {
#if BUILDFLAG(IS_ANDROID)
  ASSERT_TRUE(BackForwardCacheImpl::IsUnloadAllowed());
#else
  ASSERT_FALSE(BackForwardCacheImpl::IsUnloadAllowed());
#endif
}

IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
                       FrameWithBlocklistedFeatureNotCached) {
  ASSERT_TRUE(embedded_test_server()->Start());

  // Navigate to a page that contains a blocklisted feature.
  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL("a.com", "/title1.html")));

  RenderFrameHostWrapper rfh(current_frame_host());

  ASSERT_TRUE(AddBlocklistedFeature(rfh.get()));

  // Navigate away.
  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL("b.com", "/title1.html")));

  // The page with the unsupported feature should be deleted (not cached).
  ASSERT_TRUE(rfh.WaitUntilRenderFrameDeleted());

  // Go back.
  ASSERT_TRUE(HistoryGoBack(web_contents()));
  ExpectNotRestoredDueToBlocklistedFeature(FROM_HERE);
}

IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
                       SubframeWithBlocklistedFeatureNotCached) {
  ASSERT_TRUE(embedded_test_server()->Start());

  // Navigate to a page with an iframe that contains a blocklisted feature.
  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL(
                   "a.com", "/cross_site_iframe_factory.html?a(b)")));

  RenderFrameHostWrapper rfh(
      current_frame_host()->child_at(0)->current_frame_host());

  ASSERT_TRUE(AddBlocklistedFeature(rfh.get()));

  // Navigate away.
  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL("b.com", "/title1.html")));

  // The page with the unsupported feature should be deleted (not cached).
  ASSERT_TRUE(rfh.WaitUntilRenderFrameDeleted());

  // Go back.
  ASSERT_TRUE(HistoryGoBack(web_contents()));
  ExpectNotRestoredDueToBlocklistedFeature(FROM_HERE);
}

class BackForwardCacheBrowserUnloadHandlerTest
    : public BackForwardCacheBrowserTest,
      public ::testing::WithParamInterface<
          std::tuple<bool, bool, bool, TestFrameType>> {
 public:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    if (IsUnloadAllowed()) {
      EnableFeatureAndSetParams(kBackForwardCacheUnloadAllowed, "", "");
    } else {
      DisableFeature(kBackForwardCacheUnloadAllowed);
    }
    if (IsUnloadBlocklisted()) {
      EnableFeatureAndSetParams(blink::features::kUnloadBlocklisted, "", "");
    } else {
      DisableFeature(blink::features::kUnloadBlocklisted);
    }
    if (IsUnloadDeprecationOptedOut()) {
      EnableFeatureAndSetParams(blink::features::kDeprecateUnloadOptOut, "",
                                "");
    } else {
      DisableFeature(blink::features::kDeprecateUnloadOptOut);
    }

    BackForwardCacheBrowserTest::SetUpCommandLine(command_line);
  }

  bool IsUnloadAllowed() { return std::get<0>(GetParam()); }
  bool IsUnloadBlocklisted() { return std::get<1>(GetParam()); }
  bool IsUnloadDeprecationOptedOut() { return std::get<2>(GetParam()); }

  TestFrameType GetTestFrameType() { return std::get<3>(GetParam()); }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

// Ensure that unload handlers in main frames and subframes block caching,
// depending on unload deprecation status and OS.
IN_PROC_BROWSER_TEST_P(BackForwardCacheBrowserUnloadHandlerTest,
                       UnloadHandlerPresent) {
  ASSERT_TRUE(embedded_test_server()->Start());

  GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
  GURL url_b(embedded_test_server()->GetURL("b.com", "/title2.html"));

  // 1) Navigate to A.
  EXPECT_TRUE(NavigateToURL(shell(), url_a));

  BackForwardCacheCanStoreDocumentResult::NotRestoredReasons
      expected_blocking_reasons;
  std::vector<blink::scheduler::WebSchedulerTrackedFeature>
      expected_blocklisted_reason;
  if (IsUnloadBlocklisted()) {
    expected_blocking_reasons.Put(
        BackForwardCacheMetrics::NotRestoredReason::kBlocklistedFeatures);
    expected_blocklisted_reason.push_back(
        blink::scheduler::WebSchedulerTrackedFeature::kUnloadHandler);
  }
  switch (GetTestFrameType()) {
    case content::TestFrameType::kMainFrame:
      InstallUnloadHandlerOnMainFrame();
      expected_blocking_reasons.Put(BackForwardCacheMetrics::NotRestoredReason::
                                        kUnloadHandlerExistsInMainFrame);
      break;
    case content::TestFrameType::kSubFrame:
      InstallUnloadHandlerOnSubFrame();
      expected_blocking_reasons.Put(BackForwardCacheMetrics::NotRestoredReason::
                                        kUnloadHandlerExistsInSubFrame);
      break;
    default:
      NOTREACHED();
  }

  // 2) Navigate to B.
  EXPECT_TRUE(NavigateToURL(shell(), url_b));

  // 3) Go back.
  ASSERT_TRUE(HistoryGoBack(web_contents()));

  bool unload_never_blocks = IsUnloadAllowed();
  bool unload_deprecated_and_not_opted_out =
      (base::FeatureList::IsEnabled(network::features::kDeprecateUnload) &&
       !IsUnloadDeprecationOptedOut());
  if (unload_never_blocks || unload_deprecated_and_not_opted_out) {
    // Pages with unload handlers are eligible for bfcache only if it is
    // specifically allowed (happens on Android). Also, when unload is
    // deprecated and `kDeprecateUnloadOptOut` doesn't override it, unload
    // handlers cannot be installed so there should be no blocker for BFCache.
    ExpectRestored(FROM_HERE);
    EXPECT_EQ("0", GetUnloadRunCount());
  } else {
    ExpectNotRestored(expected_blocking_reasons, expected_blocklisted_reason,
                      {}, {}, {}, FROM_HERE);
    EXPECT_EQ("1", GetUnloadRunCount());
  }
}

// First param: whether unload is allowed or not.
// Second one: whether unload is blocklisted or not.
// Third one: whether it's opted out from unload deprecation or not.
INSTANTIATE_TEST_SUITE_P(
    All,
    BackForwardCacheBrowserUnloadHandlerTest,
    ::testing::Combine(::testing::Bool(),
                       ::testing::Bool(),
                       ::testing::Bool(),
                       ::testing::Values(TestFrameType::kMainFrame,
                                         TestFrameType::kSubFrame)));

IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, DisableForRenderFrameHost) {
  ASSERT_TRUE(embedded_test_server()->Start());

  GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
  GURL url_b(embedded_test_server()->GetURL("b.com", "/title2.html"));

  // 1) Navigate to A.
  EXPECT_TRUE(NavigateToURL(shell(), url_a));
  RenderFrameHostWrapper rfh_wrapper_a(current_frame_host());

  // 2) Navigate to B.
  EXPECT_TRUE(NavigateToURL(shell(), url_b));
  RenderFrameHostWrapper rfh_wrapper_b(current_frame_host());

  // Regardless of whether the source Id is set or not, it shouldn't affect the
  // result of the BFCache eviction.
  BackForwardCache::DisabledReason test_reason =
      BackForwardCacheDisable::DisabledReason(
          BackForwardCacheDisable::DisabledReasonId::kUnknown);

  // 3) Disable BFCache for A with UKM source Id and go back.
  BackForwardCache::DisableForRenderFrameHost(
      rfh_wrapper_a.get(), test_reason, ukm::UkmRecorder::GetNewSourceID());
  ASSERT_TRUE(HistoryGoBack(web_contents()));
  ASSERT_TRUE(rfh_wrapper_a.WaitUntilRenderFrameDeleted());
  // Page A should be evicted properly.
  ExpectNotRestored({BackForwardCacheMetrics::NotRestoredReason::
                         kDisableForRenderFrameHostCalled},
                    {}, {}, {test_reason}, {}, FROM_HERE);

  // 4) Disable BFCache for B without UKM source Id and go forward.
  BackForwardCache::DisableForRenderFrameHost(rfh_wrapper_b.get(), test_reason);
  ASSERT_TRUE(HistoryGoForward(web_contents()));
  ASSERT_TRUE(rfh_wrapper_b.WaitUntilRenderFrameDeleted());
  // Page B should be evicted properly.
  ExpectNotRestored({BackForwardCacheMetrics::NotRestoredReason::
                         kDisableForRenderFrameHostCalled},
                    {}, {}, {test_reason}, {}, FROM_HERE);
}

namespace {
enum class SubframeType { SameSite, CrossSite };
}

class BackForwardCacheEvictionDueToSubframeNavigationBrowserTest
    : public BackForwardCacheBrowserTest,
      public ::testing::WithParamInterface<SubframeType> {
 public:
  // Provides meaningful param names instead of /0 and /1.
  static std::string DescribeParams(
      const ::testing::TestParamInfo<ParamType>& info) {
    switch (info.param) {
      case SubframeType::SameSite:
        return "SameSite";
      case SubframeType::CrossSite:
        return "CrossSite";
    }
  }

 protected:
  bool UseCrossOriginSubframe() const {
    return GetParam() == SubframeType::CrossSite;
  }
};

IN_PROC_BROWSER_TEST_P(
    BackForwardCacheEvictionDueToSubframeNavigationBrowserTest,
    SubframePendingCommitShouldPreventCache) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL a_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  GURL subframe_url = embedded_test_server()->GetURL(
      UseCrossOriginSubframe() ? "b.com" : "a.com", "/title1.html");

  IsolateOriginsForTesting(embedded_test_server(), web_contents(),
                           std::vector<std::string>{"a.com", "b.com"});

  // 1) Navigate to a.com.
  EXPECT_TRUE(NavigateToURL(shell(), a_url));
  RenderFrameHostImpl* main_frame = current_frame_host();

  // 2) Add subframe and wait for empty document to commit.
  CreateSubframe(web_contents(), "child", GURL(""), true);

  CommitMessageDelayer commit_message_delayer(
      web_contents(), subframe_url,
      base::BindLambdaForTesting([&](RenderFrameHost*) {
        // 5) Test that page cannot be stored in bfcache when subframe is
        // pending commit.
        BackForwardCacheCanStoreDocumentResultWithTree can_store_result =
            web_contents()
                ->GetController()
                .GetBackForwardCache()
                .GetCurrentBackForwardCacheEligibility(
                    static_cast<RenderFrameHostImpl*>(main_frame));
        EXPECT_TRUE(can_store_result.flattened_reasons.HasNotRestoredReason(
            BackForwardCacheMetrics::NotRestoredReason::kSubframeIsNavigating));
      }));

  // 3) Start navigation in subframe to |subframe_url|.
  ExecuteScriptAsync(
      main_frame,
      JsReplace("document.querySelector('#child').src = $1;", subframe_url));
  // 4) Wait until subframe navigation is pending commit.
  commit_message_delayer.Wait();
}

// Check that when the main frame gets BFCached while the subframe navigation
// deferring NavigationThrottles has already ran, the issue that the subframe
// navigation escapes the throttle deferral is addressed.
IN_PROC_BROWSER_TEST_P(
    BackForwardCacheEvictionDueToSubframeNavigationBrowserTest,
    MainFrameCommitFirstAndSubframePendingCommitShouldBeEvicted) {
  ASSERT_TRUE(embedded_test_server()->Start());
  // Prepare the main frame and the sub frame, where both of them are same-site.
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* child = root->child_at(0);
  RenderFrameHostImplWrapper child_rfh(child->current_frame_host());

  // Navigate both frames simultaneously.
  const std::string subframe_origin =
      UseCrossOriginSubframe() ? "b.com" : "a.com";
  GURL new_url_1(
      embedded_test_server()->GetURL(subframe_origin, "/title1.html"));
  GURL new_url_2(
      embedded_test_server()->GetURL(subframe_origin, "/title2.html"));
  TestNavigationManager manager1(web_contents(), new_url_1);
  TestNavigationManager manager2(web_contents(), new_url_2);
  auto script = JsReplace("location = $1; frames[0].location = $2;", new_url_1,
                          new_url_2);
  EXPECT_TRUE(ExecJs(web_contents(), script));

  // Wait for main frame request, but don't commit it yet. This should create
  // a speculative RenderFrameHost.
  ASSERT_TRUE(manager1.WaitForRequestStart());

  // Wait for subframe request, but don't commit it yet.
  ASSERT_TRUE(manager2.WaitForRequestStart());

  // Now let the main frame commit.
  ASSERT_TRUE(manager1.WaitForNavigationFinished());
  // Make sure the main frame is at the new URL.
  ASSERT_TRUE(root->current_frame_host()->IsRenderFrameLive());
  ASSERT_EQ(new_url_1, root->current_frame_host()->GetLastCommittedURL());

  // The subframe should be gone now: it should have been evicted from BFCache
  // because the subframe is still navigating; otherwise, this will cause a
  // crash.
  ASSERT_TRUE(manager2.WaitForNavigationFinished());
  EXPECT_TRUE(child_rfh.IsDestroyed());
  ASSERT_TRUE(HistoryGoBack(web_contents()));
  ExpectNotRestored(
      {BackForwardCacheMetrics::NotRestoredReason::kSubframeIsNavigating}, {},
      {}, {}, {}, FROM_HERE);
}

INSTANTIATE_TEST_SUITE_P(
    All,
    BackForwardCacheEvictionDueToSubframeNavigationBrowserTest,
    ::testing::Values(SubframeType::SameSite, SubframeType::CrossSite),
    &BackForwardCacheEvictionDueToSubframeNavigationBrowserTest::
        DescribeParams);

namespace {
enum class SubframeNavigationType { WithoutURLLoader, WithURLLoader };
}

// Test for pages which has subframe(s) with ongoing navigation(s).
class BackForwardCacheWithSubframeNavigationBrowserTest
    : public BackForwardCacheBrowserTest {
 protected:
  void SetUpOnMainThread() override {
    BackForwardCacheBrowserTest::SetUpOnMainThread();
    ASSERT_TRUE(embedded_test_server()->Start());
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    EnableCacheSize(2, std::nullopt);
    BackForwardCacheBrowserTest::SetUpCommandLine(command_line);
  }

  // Start a subframe navigation and pause it when we get the confirmation
  // dialog triggered by beforeunload event, which is before
  // WillCommitWithoutUrlLoader or WillStartRequest.
  void NavigateSubframeAndPauseAtBeforeUnload(
      BeforeUnloadBlockingDelegate& beforeunload_pauser,
      RenderFrameHostImpl* sub_rfh,
      const GURL& subframe_navigate_url,
      std::string_view iframe_id) {
    ASSERT_TRUE(ExecJs(sub_rfh, R"(
      window.addEventListener('beforeunload', e =>
        e.returnValue='blocked'
      );)"));

    // Start a subframe navigation which will trigger the beforeunload dialog
    // that pauses that navigation. Using `BeginNavigateIframeToURL` is
    // necessary here, since we pause this navigation on beforeunload event. So,
    // we don't want to wait for the navigation to finish.
    BeginNavigateIframeToURL(web_contents(), iframe_id, subframe_navigate_url);
    beforeunload_pauser.Wait();
  }

  // Start a subframe navigation and pause it before `DidCommitNavigation`.
  void NavigateSubframeAndPauseAtDidCommit(FrameTreeNode* ftn,
                                           const GURL& subframe_navigate_url) {
    // Enforce the creation of speculative RFH to correctly wait for
    // the commit event.
    SpeculativeRenderFrameHostObserver observer(web_contents(),
                                                subframe_navigate_url);
    // We have to pause a navigation before `DidCommitNavigation`, so we don't
    // want to wait for the navigation to finish.
    ASSERT_TRUE(BeginNavigateToURLFromRenderer(ftn, subframe_navigate_url));
    // Navigation without a URL loader shall always create the speculative RFH
    // immediately or never create one.
    // The same-site navigation to the subframe will not create a new
    // speculative RFH if render document is not enabled for subframes.
    if (subframe_navigate_url.SchemeIsHTTPOrHTTPS() &&
        ShouldCreateNewRenderFrameHostOnSameSiteNavigation(
            /*is_main_frame=*/false, /*is_local_root=*/true)) {
      observer.Wait();
    }

    // Wait until the navigation is pending commit. Note that the navigation
    // might use a speculative RenderFrameHost, so use that if necessary.
    RenderFrameHostImpl* speculative_rfh =
        ftn->render_manager()->speculative_frame_host();
    CommitNavigationPauser commit_pauser(
        speculative_rfh ? speculative_rfh : ftn->current_frame_host());
    commit_pauser.WaitForCommitAndPause();
  }

  // Put a page which has a subframe with a navigation which hasn't reached the
  // "pending commit" stage nor sent a network request into BackForwardCache and
  // confirm the subframe navigation has been deferred.
  void BFCachePageWithSubframeNavigationBeforeDidStartNavigation(
      const GURL& main_frame_navigate_url,
      const GURL& subframe_navigate_url,
      RenderFrameHostImplWrapper& sub_rfh,
      TestNavigationManager& subframe_navigation_manager,
      std::string_view iframe_id) {
    FrameTreeNode* child_ftn =
        web_contents()->GetPrimaryFrameTree().root()->child_at(0);
    {
      BeforeUnloadBlockingDelegate beforeunload_pauser(web_contents());
      NavigateSubframeAndPauseAtBeforeUnload(beforeunload_pauser, sub_rfh.get(),
                                             subframe_navigate_url, iframe_id);

      // Subframe navigation is ongoing, so `NavigateToURL` cannot be used since
      // this function waits for all frames including subframe to finish
      // loading.
      ASSERT_TRUE(NavigateToURLFromRenderer(sub_rfh->GetMainFrame(),
                                            main_frame_navigate_url));

      // The subframe navigation hasn't reached the "pending commit" stage nor
      // sent a network request, so the page is eligible for BackForwardCache.
      EXPECT_TRUE(sub_rfh->GetMainFrame()->IsInBackForwardCache());
      EXPECT_TRUE(sub_rfh->IsInBackForwardCache());
    }
    web_contents()->SetDelegate(shell());

    // Wait until the subframe navigation is deferred.
    ASSERT_TRUE(
        subframe_navigation_manager.WaitForFirstYieldAfterDidStartNavigation());
    NavigationRequest* child_navigation = child_ftn->navigation_request();
    ASSERT_NE(child_navigation, nullptr);
    EXPECT_TRUE(child_navigation->IsDeferredForTesting());
  }
};

class BackForwardCacheWithSubframeNavigationWithParamBrowserTest
    : public BackForwardCacheWithSubframeNavigationBrowserTest,
      public ::testing::WithParamInterface<SubframeNavigationType> {
 public:
  // Provides meaningful param names instead of /0 and /1.
  static std::string DescribeParams(
      const ::testing::TestParamInfo<ParamType>& info) {
    switch (info.param) {
      case SubframeNavigationType::WithoutURLLoader:
        return "WithoutURLLoader";
      case SubframeNavigationType::WithURLLoader:
        return "WithURLLoader";
    }
  }
};

// Confirm that BackForwardCache is blocked when there is only 1 navigation and
// it's pending commit.
IN_PROC_BROWSER_TEST_P(
    BackForwardCacheWithSubframeNavigationWithParamBrowserTest,
    SubframeNavigationWithPendingCommitShouldPreventCache) {
  const GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  const GURL subframe_url = embedded_test_server()->GetURL(
      "b.com", "/cross_site_iframe_factory.html?b()");
  const GURL navigate_url(
      embedded_test_server()->GetURL("c.com", "/title1.html"));
  const GURL subframe_navigate_url =
      GetParam() == SubframeNavigationType::WithURLLoader
          ? embedded_test_server()->GetURL("b.com", "/title1.html")
          : GURL("about:blank");

  // Navigate to a page with a cross site iframe.
  ASSERT_TRUE(NavigateToURL(shell(), main_url));
  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));

  RenderFrameHostImplWrapper main_rfh(current_frame_host());
  FrameTreeNode* child_node = main_rfh.get()->child_at(0);
  RenderFrameHostImplWrapper sub_rfh(child_node->current_frame_host());

  // Pause subframe's navigation before `DidCommitNavigation`.
  NavigateSubframeAndPauseAtDidCommit(child_node, subframe_navigate_url);

  // Subframe navigation is ongoing, so `NavigateToURL` cannot be used since
  // this function waits for all frames including subframe to finish loading.
  ASSERT_TRUE(NavigateToURLFromRenderer(main_rfh.get(), navigate_url));

  // Subframe navigation has reached the "pending commit" stage, so the page is
  // not eligible for BackForwardCache.
  EXPECT_TRUE(main_rfh.WaitUntilRenderFrameDeleted());
  EXPECT_TRUE(sub_rfh.WaitUntilRenderFrameDeleted());

  // Navigate back.
  ASSERT_TRUE(HistoryGoBack(web_contents()));
  ExpectNotRestored({NotRestoredReason::kSubframeIsNavigating}, {}, {}, {}, {},
                    FROM_HERE);

  // Confirm that subframe's url didn't change.
  EXPECT_EQ(subframe_url, current_frame_host()->child_at(0)->current_url());
}

// Confirm that BackForwardCache is blocked when there are 2 navigations, 1 not
// pending commit yet, and 1 pending commit.
IN_PROC_BROWSER_TEST_F(
    BackForwardCacheWithSubframeNavigationBrowserTest,
    MultipleSubframeNavigationWithBeforeAndPendingCommitShouldPreventCache) {
  // This test relies on the main frame and the iframe to live in different
  // processes. This allows one renderer process to proceed a navigation while
  // the other renderer process is busy executing its beforeunload handler.
  if (!AreAllSitesIsolatedForTesting()) {
    GTEST_SKIP() << "Site isolation is not enabled!";
  }
  const GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b,c)"));
  const GURL subframe_b_url = embedded_test_server()->GetURL(
      "b.com", "/cross_site_iframe_factory.html?b()");
  const GURL subframe_c_url = embedded_test_server()->GetURL(
      "c.com", "/cross_site_iframe_factory.html?c()");
  const GURL navigate_url(
      embedded_test_server()->GetURL("d.com", "/title1.html"));
  const GURL subframe_navigate_url = GURL("about:blank");

  // Navigate to a page with two cross site iframes.
  ASSERT_TRUE(NavigateToURL(shell(), main_url));
  RenderFrameHostImplWrapper main_rfh(current_frame_host());
  RenderFrameHostImplWrapper sub_rfh_b(
      main_rfh.get()->child_at(0)->current_frame_host());
  RenderFrameHostImplWrapper sub_rfh_c(
      main_rfh.get()->child_at(1)->current_frame_host());

  {
    // The subframe_b itself does have a dialog-showing beforeunload handler.
    // Pause subframe_b's navigation when we get the confirmation dialog
    // triggered by beforeunload event.
    BeforeUnloadBlockingDelegate beforeunload_pauser(web_contents());
    NavigateSubframeAndPauseAtBeforeUnload(beforeunload_pauser, sub_rfh_b.get(),
                                           subframe_navigate_url,
                                           /*iframe_id=*/"child-0");

    // Pause subframe_c's navigation before `DidCommitNavigation`.
    NavigateSubframeAndPauseAtDidCommit(main_rfh.get()->child_at(1),
                                        subframe_navigate_url);

    // Subframe navigation is ongoing, so `NavigateToURL` cannot be used since
    // this function waits for all frames including subframe to finish loading.
    ASSERT_TRUE(NavigateToURLFromRenderer(main_rfh.get(), navigate_url));

    // The subframe_c's navigation already started committing, so the page is
    // not eligible for BackForwardCache.
    EXPECT_TRUE(main_rfh.WaitUntilRenderFrameDeleted());
    EXPECT_TRUE(sub_rfh_b.WaitUntilRenderFrameDeleted());
    EXPECT_TRUE(sub_rfh_c.WaitUntilRenderFrameDeleted());
  }
  web_contents()->SetDelegate(shell());

  // Navigate back.
  ASSERT_TRUE(HistoryGoBack(web_contents()));
  ExpectNotRestored({NotRestoredReason::kSubframeIsNavigating}, {}, {}, {}, {},
                    FROM_HERE);

  // Confirm that subframe's url didn't change.
  EXPECT_EQ(subframe_b_url, current_frame_host()->child_at(0)->current_url());
  EXPECT_EQ(subframe_c_url, current_frame_host()->child_at(1)->current_url());
}

// Confirm that BackForwardCache is blocked when there are 2 navigations, 1 has
// not sent a network request yet, and 1 has already sent request.
IN_PROC_BROWSER_TEST_F(
    BackForwardCacheWithSubframeNavigationBrowserTest,
    MultipleSubframeNavigationWithBeforeAndAfterSendingRequestShouldPreventCache) {
  // This test relies on the main frame and the iframe to live in different
  // processes. This allows one renderer process to proceed a navigation while
  // the other renderer process is busy executing its beforeunload handler.
  if (!AreAllSitesIsolatedForTesting()) {
    GTEST_SKIP() << "Site isolation is not enabled!";
  }
  const GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b,c)"));
  const GURL subframe_b_url = embedded_test_server()->GetURL(
      "b.com", "/cross_site_iframe_factory.html?b()");
  const GURL subframe_c_url = embedded_test_server()->GetURL(
      "c.com", "/cross_site_iframe_factory.html?c()");
  const GURL navigate_url(
      embedded_test_server()->GetURL("d.com", "/title1.html"));
  const GURL subframe_b_navigate_url(
      embedded_test_server()->GetURL("b.com", "/title1.html"));
  const GURL subframe_c_navigate_url(
      embedded_test_server()->GetURL("c.com", "/title1.html"));

  // Navigate to a page with two cross site iframes.
  ASSERT_TRUE(NavigateToURL(shell(), main_url));
  RenderFrameHostImplWrapper main_rfh(current_frame_host());
  RenderFrameHostImplWrapper sub_rfh_b(
      main_rfh.get()->child_at(0)->current_frame_host());
  RenderFrameHostImplWrapper sub_rfh_c(
      main_rfh.get()->child_at(1)->current_frame_host());

  // Pause a subframe_b navigation on `WillStartRequest` before sending a
  // network request.
  TestNavigationManager subframe_b_navigation_manager(web_contents(),
                                                      subframe_b_navigate_url);
  ASSERT_TRUE(
      BeginNavigateToURLFromRenderer(sub_rfh_b.get(), subframe_b_navigate_url));
  ASSERT_TRUE(subframe_b_navigation_manager.WaitForRequestStart());

  // Pause a subframe_c navigation on `WillProcessResponse` after sending a
  // network request.
  TestNavigationManager subframe_c_navigation_manager(web_contents(),
                                                      subframe_c_navigate_url);
  ASSERT_TRUE(
      BeginNavigateToURLFromRenderer(sub_rfh_c.get(), subframe_c_navigate_url));
  ASSERT_TRUE(subframe_c_navigation_manager.WaitForResponse());

  // Subframe navigation is ongoing, so `NavigateToURL` cannot be used since
  // this function waits for all frames including subframe to finish loading.
  ASSERT_TRUE(NavigateToURLFromRenderer(main_rfh.get(), navigate_url));

  // The subframe_c's navigation has already sent a network request, so the page
  // is not eligible for BackForwardCache.
  EXPECT_TRUE(main_rfh.WaitUntilRenderFrameDeleted());
  EXPECT_TRUE(sub_rfh_b.WaitUntilRenderFrameDeleted());
  EXPECT_TRUE(sub_rfh_c.WaitUntilRenderFrameDeleted());
  EXPECT_TRUE(subframe_b_navigation_manager.WaitForNavigationFinished());
  EXPECT_TRUE(subframe_c_navigation_manager.WaitForNavigationFinished());
  EXPECT_FALSE(subframe_b_navigation_manager.was_committed());
  EXPECT_FALSE(subframe_c_navigation_manager.was_committed());

  // Navigate back.
  ASSERT_TRUE(HistoryGoBack(web_contents()));
  ExpectNotRestored({NotRestoredReason::kSubframeIsNavigating}, {}, {}, {}, {},
                    FROM_HERE);

  // Confirm that subframe's url didn't change.
  EXPECT_EQ(subframe_b_url, current_frame_host()->child_at(0)->current_url());
  EXPECT_EQ(subframe_c_url, current_frame_host()->child_at(1)->current_url());
}

// Confirm that subframe navigation which needs url loader that has already sent
// a network request should block BackForwardCache.
IN_PROC_BROWSER_TEST_F(
    BackForwardCacheWithSubframeNavigationBrowserTest,
    SubframeNavigationWithUrlLoaderAfterSendingRequestShouldPreventCache) {
  const GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  const GURL subframe_url = embedded_test_server()->GetURL(
      "b.com", "/cross_site_iframe_factory.html?b()");
  const GURL navigate_url(
      embedded_test_server()->GetURL("c.com", "/title1.html"));
  const GURL subframe_navigate_url(
      embedded_test_server()->GetURL("b.com", "/title2.html"));

  // Navigate to a page with a cross site iframe.
  ASSERT_TRUE(NavigateToURL(shell(), main_url));
  RenderFrameHostImplWrapper main_rfh(current_frame_host());
  RenderFrameHostImplWrapper sub_rfh(
      main_rfh.get()->child_at(0)->current_frame_host());
  TestNavigationManager subframe_navigation_manager(web_contents(),
                                                    subframe_navigate_url);
  ASSERT_TRUE(
      BeginNavigateToURLFromRenderer(sub_rfh.get(), subframe_navigate_url));

  // Pause the subframe navigation on `WillProcessResponse`.
  ASSERT_TRUE(subframe_navigation_manager.WaitForResponse());

  // Subframe navigation is ongoing, so `NavigateToURL` cannot be used since
  // this function waits for all frames including subframe to finish loading.
  ASSERT_TRUE(NavigateToURLFromRenderer(main_rfh.get(), navigate_url));

  // Subframe navigation has already sent a network request, so the page is not
  // eligible for BackForwardCache.
  EXPECT_TRUE(main_rfh.WaitUntilRenderFrameDeleted());
  EXPECT_TRUE(sub_rfh.WaitUntilRenderFrameDeleted());
  EXPECT_FALSE(subframe_navigation_manager.was_committed());

  // Navigate back.
  ASSERT_TRUE(HistoryGoBack(web_contents()));
  ExpectNotRestored({NotRestoredReason::kSubframeIsNavigating}, {}, {}, {}, {},
                    FROM_HERE);

  // Confirm that subframe's url didn't change.
  EXPECT_EQ(subframe_url, current_frame_host()->child_at(0)->current_url());
}

// Confirm that subframe navigation which needs url loader that hasn't sent a
// network request should not block BackForwardCache.
IN_PROC_BROWSER_TEST_F(
    BackForwardCacheWithSubframeNavigationBrowserTest,
    SubframeNavigationWithUrlLoaderBeforeSendingRequestShouldNotPreventCache) {
  // This test relies on the main frame and the iframe to live in different
  // processes. This allows one renderer process to proceed a navigation while
  // the other renderer process is busy executing its beforeunload handler.
  if (!AreAllSitesIsolatedForTesting()) {
    GTEST_SKIP() << "Site isolation is not enabled!";
  }
  const GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  const GURL subframe_url = embedded_test_server()->GetURL(
      "b.com", "/cross_site_iframe_factory.html?b()");
  const GURL navigate_url(
      embedded_test_server()->GetURL("c.com", "/title1.html"));
  const GURL subframe_navigate_url(
      embedded_test_server()->GetURL("b.com", "/title1.html"));

  // Navigate to a page with a cross site iframe.
  ASSERT_TRUE(NavigateToURL(shell(), main_url));
  RenderFrameHostImplWrapper main_rfh(current_frame_host());
  RenderFrameHostImplWrapper sub_rfh(
      main_rfh.get()->child_at(0)->current_frame_host());

  // Put a page which has a subframe with a URLLoader navigation which hasn't
  // sent a network request into BackForwardCache. The iframe itself
  // does have a dialog-showing beforeunload handler.
  TestNavigationManager subframe_navigation_manager(web_contents(),
                                                    subframe_navigate_url);
  BFCachePageWithSubframeNavigationBeforeDidStartNavigation(
      navigate_url, subframe_navigate_url, sub_rfh, subframe_navigation_manager,
      /*iframe_id=*/"child-0");

  // Navigate back.
  TestNavigationObserver back_load_observer(shell()->web_contents());
  web_contents()->GetController().GoBack();
  back_load_observer.WaitForNavigationFinished();
  ASSERT_FALSE(main_rfh->IsInBackForwardCache());

  // Wait until the resumed subframe navigation finishes.
  EXPECT_TRUE(subframe_navigation_manager.WaitForNavigationFinished());
  EXPECT_TRUE(subframe_navigation_manager.was_successful());
  EXPECT_EQ(subframe_navigate_url,
            current_frame_host()->child_at(0)->current_url());
}

// Confirm that subframe no-url loader navigation (e.g., about:blank) in
// bfcached page is deferred and then resumed when the page is navigated back.
IN_PROC_BROWSER_TEST_F(
    BackForwardCacheWithSubframeNavigationBrowserTest,
    SubframeNavigationWithoutUrlLoaderBeforeCommitShouldNotPreventCache) {
  // This test relies on the main frame and the iframe to live in different
  // processes. This allows one renderer process to proceed a navigation while
  // the other renderer process is busy executing its beforeunload handler.
  if (!AreAllSitesIsolatedForTesting()) {
    GTEST_SKIP() << "Site isolation is not enabled!";
  }
  const GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  const GURL navigate_url(
      embedded_test_server()->GetURL("c.com", "/title1.html"));
  const GURL subframe_navigate_url = GURL("about:blank");

  // Navigate to a page with a cross site iframe.
  ASSERT_TRUE(NavigateToURL(shell(), main_url));
  RenderFrameHostImplWrapper main_rfh(current_frame_host());
  RenderFrameHostImplWrapper sub_rfh(
      main_rfh.get()->child_at(0)->current_frame_host());

  // Put a page which has a subframe with a no-URLLoader navigation which hasn't
  // reached the "pending commit" stage into BackForwardCache. The iframe itself
  // does have a dialog-showing beforeunload handler.
  TestNavigationManager subframe_navigation_manager(web_contents(),
                                                    subframe_navigate_url);
  BFCachePageWithSubframeNavigationBeforeDidStartNavigation(
      navigate_url, subframe_navigate_url, sub_rfh, subframe_navigation_manager,
      /*iframe_id=*/"child-0");

  // Navigate back.
  ASSERT_TRUE(HistoryGoBack(web_contents()));
  ASSERT_FALSE(main_rfh->IsInBackForwardCache());

  // Confirm the deferred navigation was resumed and subframe's url changed.
  EXPECT_TRUE(subframe_navigation_manager.WaitForNavigationFinished());
  EXPECT_TRUE(subframe_navigation_manager.was_successful());
  EXPECT_EQ(subframe_navigate_url,
            current_frame_host()->child_at(0)->current_url());
}

// Confirm that we don't resume a subframe navigation when an unrelated BFCached
// page gets restored.
IN_PROC_BROWSER_TEST_P(
    BackForwardCacheWithSubframeNavigationWithParamBrowserTest,
    SubframeNavigationShouldNotBeResumedWhenUnrelatedPageRestored) {
  // This test relies on the main frame and the iframe to live in different
  // processes. This allows one renderer process to proceed a navigation while
  // the other renderer process is busy executing its beforeunload handler.
  if (!AreAllSitesIsolatedForTesting()) {
    GTEST_SKIP() << "Site isolation is not enabled!";
  }
  const GURL main_url_a(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  const GURL navigate_url_c(
      embedded_test_server()->GetURL("c.com", "/title1.html"));
  const GURL navigate_url_d(
      embedded_test_server()->GetURL("d.com", "/title1.html"));
  const GURL subframe_navigate_url =
      GetParam() == SubframeNavigationType::WithURLLoader
          ? embedded_test_server()->GetURL("b.com", "/title1.html")
          : GURL("about:blank");

  // Navigate to a page with a cross site iframe.
  ASSERT_TRUE(NavigateToURL(shell(), main_url_a));
  RenderFrameHostImplWrapper main_rfh_a(current_frame_host());
  RenderFrameHostImplWrapper sub_rfh_b(
      main_rfh_a.get()->child_at(0)->current_frame_host());

  // Put a page which has a subframe with a navigation which hasn't reached the
  // "pending commit" stage or sent a network request into BackForwardCache.
  TestNavigationManager subframe_navigation_manager(web_contents(),
                                                    subframe_navigate_url);
  BFCachePageWithSubframeNavigationBeforeDidStartNavigation(
      navigate_url_c, subframe_navigate_url, sub_rfh_b,
      subframe_navigation_manager,
      /*iframe_id=*/"child-0");

  // Navigate away.
  // Currently, `main_rfh_a` is in BFCache and we are on `navigate_url_c`. Then,
  // we will navigate to `navigate_url_d` which will put `main_rfh_c` in
  // BFCache.
  RenderFrameHostImplWrapper main_rfh_c(current_frame_host());
  ASSERT_TRUE(NavigateToURL(shell(), navigate_url_d));
  ASSERT_TRUE(main_rfh_c->IsInBackForwardCache());

  // Navigate back to `main_rfh_c` and restore that from BFCache, while
  // `main_rfh_a` is still in BFCache.
  ASSERT_TRUE(HistoryGoBack(web_contents()));
  ASSERT_EQ(main_rfh_c.get(), current_frame_host());
  ASSERT_TRUE(main_rfh_a->IsInBackForwardCache());

  // Confirm the subframe's deferred navigation is not committed.
  EXPECT_FALSE(subframe_navigation_manager.was_committed());

  // Navigate back to `main_rfh_a`.
  TestNavigationObserver back_load_observer(shell()->web_contents());
  web_contents()->GetController().GoBack();
  back_load_observer.WaitForNavigationFinished();
  ASSERT_FALSE(main_rfh_a->IsInBackForwardCache());

  // Confirm the deferred navigation was resumed and subframe's url changed.
  EXPECT_TRUE(subframe_navigation_manager.WaitForNavigationFinished());
  EXPECT_TRUE(subframe_navigation_manager.was_successful());
  EXPECT_EQ(subframe_navigate_url,
            current_frame_host()->child_at(0)->current_url());
}

// Evict the bfcached page which has a subframe with a deferred navigation and
// confirm the subframe'url didn't change when the page is navigated back.
IN_PROC_BROWSER_TEST_P(
    BackForwardCacheWithSubframeNavigationWithParamBrowserTest,
    EvictBFCachedPageWithDeferredSubframeNavigationBeforeCommit) {
  // This test relies on the main frame and the iframe to live in different
  // processes. This allows one renderer process to proceed a navigation while
  // the other renderer process is busy executing its beforeunload handler.
  if (!AreAllSitesIsolatedForTesting()) {
    GTEST_SKIP() << "Site isolation is not enabled!";
  }
  const GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  const GURL subframe_url = embedded_test_server()->GetURL(
      "b.com", "/cross_site_iframe_factory.html?b()");
  const GURL navigate_url(
      embedded_test_server()->GetURL("c.com", "/title1.html"));
  const GURL subframe_navigate_url =
      GetParam() == SubframeNavigationType::WithURLLoader
          ? embedded_test_server()->GetURL("b.com", "/title1.html")
          : GURL("about:blank");

  // Navigate to a page with a cross site iframe.
  ASSERT_TRUE(NavigateToURL(shell(), main_url));
  RenderFrameHostImplWrapper main_rfh(current_frame_host());
  RenderFrameHostImplWrapper sub_rfh(
      main_rfh.get()->child_at(0)->current_frame_host());

  // Put a page which has a subframe with a navigation which hasn't reached the
  // "pending commit" stage or sent a network request into BackForwardCache. The
  // iframe itself does have a dialog-showing beforeunload handler.
  TestNavigationManager subframe_navigation_manager(web_contents(),
                                                    subframe_navigate_url);
  BFCachePageWithSubframeNavigationBeforeDidStartNavigation(
      navigate_url, subframe_navigate_url, sub_rfh, subframe_navigation_manager,
      /*iframe_id=*/"child-0");

  // Flush the cache and evict the previously BFCached page.
  web_contents()->GetController().GetBackForwardCache().Flush();
  ASSERT_TRUE(main_rfh.WaitUntilRenderFrameDeleted());
  ASSERT_TRUE(sub_rfh.WaitUntilRenderFrameDeleted());

  // Confirm the subframe's deferred navigation has finished and was not
  // committed.
  EXPECT_TRUE(subframe_navigation_manager.WaitForNavigationFinished());
  EXPECT_FALSE(subframe_navigation_manager.was_committed());

  // Navigate back.
  ASSERT_TRUE(HistoryGoBack(web_contents()));

  // Confirm that subframe's url didn't change.
  EXPECT_EQ(subframe_url, current_frame_host()->child_at(0)->current_url());
}

INSTANTIATE_TEST_SUITE_P(
    All,
    BackForwardCacheWithSubframeNavigationWithParamBrowserTest,
    ::testing::Values(SubframeNavigationType::WithoutURLLoader,
                      SubframeNavigationType::WithURLLoader),
    &BackForwardCacheWithSubframeNavigationWithParamBrowserTest::
        DescribeParams);

class BackForwardCacheFencedFrameBrowserTest
    : public BackForwardCacheBrowserTest {
 public:
  BackForwardCacheFencedFrameBrowserTest() = default;
  ~BackForwardCacheFencedFrameBrowserTest() override = default;
  BackForwardCacheFencedFrameBrowserTest(
      const BackForwardCacheFencedFrameBrowserTest&) = delete;

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

  void SetUpCommandLine(base::CommandLine* command_line) override {
    BackForwardCacheBrowserTest::SetUpCommandLine(command_line);
    fenced_frame_helper_ = std::make_unique<test::FencedFrameTestHelper>();
  }

  test::FencedFrameTestHelper& fenced_frame_test_helper() {
    return *fenced_frame_helper_;
  }

 private:
  std::unique_ptr<test::FencedFrameTestHelper> fenced_frame_helper_;
};

IN_PROC_BROWSER_TEST_F(BackForwardCacheFencedFrameBrowserTest,
                       FencedFramePageNotStoredInBackForwardCache) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
  GURL url_b(
      embedded_test_server()->GetURL("b.com", "/fenced_frames/title1.html"));
  GURL url_c(
      embedded_test_server()->GetURL("c.com", "/fenced_frames/title1.html"));

  // 1) Navigate to A.
  EXPECT_TRUE(NavigateToURL(shell(), url_a));

  // 2) Create a fenced frame.
  content::RenderFrameHostImpl* fenced_frame_host =
      static_cast<content::RenderFrameHostImpl*>(
          fenced_frame_test_helper().CreateFencedFrame(
              web_contents()->GetPrimaryMainFrame(), url_b));
  RenderFrameHostWrapper fenced_frame_host_wrapper(fenced_frame_host);

  // 3) Navigate to C on the fenced frame host.
  fenced_frame_test_helper().NavigateFrameInFencedFrameTree(fenced_frame_host,
                                                            url_c);
  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));

  if (!fenced_frame_host_wrapper.IsRenderFrameDeleted())
    EXPECT_FALSE(fenced_frame_host->IsInBackForwardCache());
}

IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
                       RendererInitiatedNavigateToSameUrl) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
  GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));

  // 1) Navigate to A.
  ASSERT_TRUE(NavigateToURL(shell(), url_a));
  RenderFrameHostImplWrapper rfh_a(current_frame_host());

  // 2) Navigate to B.
  ASSERT_TRUE(NavigateToURL(shell(), url_b));
  RenderFrameHostImplWrapper rfh_b(current_frame_host());

  // 3) Navigate to B again, renderer initiated.
  ASSERT_TRUE(NavigateToURLFromRenderer(rfh_b.get(), url_b));
  RenderFrameHostImplWrapper rfh_b2(current_frame_host());

  // This is treated as replacement, and the previous B page did not get into
  // back/forward cache.
  if (ShouldCreateNewHostForAllFrames()) {
    EXPECT_TRUE(rfh_b.WaitUntilRenderFrameDeleted());
  } else {
    EXPECT_FALSE(rfh_b->IsInBackForwardCache());
    EXPECT_EQ(rfh_b.get(), rfh_b2.get());
  }

  // 4) Go back. Make sure we go back to A instead of B and restore from
  // bfcache.
  ASSERT_TRUE(HistoryGoBack(shell()->web_contents()));
  EXPECT_EQ(current_frame_host(), rfh_a.get());
  EXPECT_TRUE(rfh_b2.get()->IsInBackForwardCache());
  ExpectRestored(FROM_HERE);

  // 5) Go forward and restore from bfcache.
  ASSERT_TRUE(HistoryGoForward(shell()->web_contents()));
  EXPECT_EQ(current_frame_host(), rfh_b2.get());
  ExpectRestored(FROM_HERE);
}

// BEFORE ADDING A NEW TEST HERE
// Read the note at the top about the other files you could add it to.
}  // namespace content
