chromium/content/browser/navigation_browsertest.cc

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

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/342213636): Remove this and spanify to fix the errors.
#pragma allow_unsafe_buffers
#endif

#include <stdint.h>

#include <memory>
#include <optional>
#include <variant>

#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/statistics_recorder.h"
#include "base/run_loop.h"
#include "base/strings/strcat.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_mock_time_task_runner.h"
#include "base/test/test_timeouts.h"
#include "base/threading/thread_restrictions.h"
#include "base/uuid.h"
#include "build/build_config.h"
#include "cc/test/pixel_test_utils.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/browser/browser_url_handler_impl.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/renderer_host/navigation_request.h"
#include "content/browser/renderer_host/navigation_state_keep_alive.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/spare_render_process_host_manager.h"
#include "content/browser/site_instance_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/content_navigation_policy.h"
#include "content/common/features.h"
#include "content/common/frame_messages.mojom.h"
#include "content/common/navigation_client.mojom-forward.h"
#include "content/common/navigation_client.mojom.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_message_filter.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/browser_url_handler.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/download_manager_delegate.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/network_service_util.h"
#include "content/public/browser/page_navigator.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/storage_partition_config.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/result_codes.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/back_forward_cache_util.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_content_browser_client.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/content_mock_cert_verifier.h"
#include "content/public/test/download_test_observer.h"
#include "content/public/test/hit_test_region_observer.h"
#include "content/public/test/navigation_handle_observer.h"
#include "content/public/test/no_renderer_crashes_assertion.h"
#include "content/public/test/slow_http_response.h"
#include "content/public/test/test_frame_navigation_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/url_loader_monitor.h"
#include "content/shell/browser/shell.h"
#include "content/shell/browser/shell_download_manager_delegate.h"
#include "content/test/content_browser_test_utils_internal.h"
#include "content/test/did_commit_navigation_interceptor.h"
#include "content/test/fake_network_url_loader_factory.h"
#include "content/test/render_document_feature.h"
#include "content/test/task_runner_deferring_throttle.h"
#include "content/test/test_render_frame_host_factory.h"
#include "ipc/ipc_security_test_util.h"
#include "mojo/public/cpp/bindings/pending_associated_remote.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "net/base/features.h"
#include "net/base/load_flags.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/http_response.h"
#include "net/test/url_request/url_request_failed_job.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/web_sandbox_flags.h"
#include "services/network/public/mojom/url_loader.mojom.h"
#include "third_party/blink/public/common/loader/url_loader_throttle.h"
#include "third_party/blink/public/mojom/frame/remote_frame.mojom-test-utils.h"
#include "third_party/blink/public/mojom/frame/sudden_termination_disabler_type.mojom-shared.h"
#include "third_party/blink/public/mojom/navigation/navigation_params.mojom-shared.h"
#include "ui/base/page_transition_types.h"
#include "url/gurl.h"
#include "url/url_constants.h"
#include "url/url_util.h"

namespace content {

namespace {
class InterceptAndCancelDidCommitProvisionalLoad
    : public DidCommitNavigationInterceptor {};

class RenderFrameHostImplForHistoryBackInterceptor
    : public RenderFrameHostImpl {};

class RenderFrameHostFactoryForHistoryBackInterceptor
    : public TestRenderFrameHostFactory {};

// Simulate embedders of content/ keeping track of the current visible URL using
// NavigateStateChanged() and GetVisibleURL() API.
class EmbedderVisibleUrlTracker : public WebContentsDelegate {};

// Helper class. Immediately run a callback when a navigation starts.
class DidStartNavigationCallback final : public WebContentsObserver {};

// Helper class. Immediately run a callback when a navigation finishes.
class DidFinishNavigationCallback final : public WebContentsObserver {};

const char* non_cacheable_html_response =;

// Insert a navigation throttle blocking every navigation in its
// WillProcessResponse handler.
std::unique_ptr<content::TestNavigationThrottleInserter>
BlockNavigationWillProcessResponse(WebContentsImpl* web_content) {}

void WaitForHistogramRecordedInChildProcess(std::string name) {}

}  // namespace

// Test about navigation.
// If you don't need a custom embedded test server, please use the next class
// below (NavigationBrowserTest), it will automatically start the
// default server.
class NavigationBaseBrowserTest : public ContentBrowserTest {};

class NavigationBrowserTest : public NavigationBaseBrowserTest {};

class NavigationGoToEntryAtOffsetBrowserTest : public NavigationBrowserTest {};

class NetworkIsolationNavigationBrowserTest : public ContentBrowserTest {};

class NavigationBrowserTestReferrerPolicy
    : public NavigationBrowserTest,
      public ::testing::WithParamInterface<network::mojom::ReferrerPolicy> {};

INSTANTIATE_TEST_SUITE_P();

// Ensure that browser initiated basic navigations work.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, BrowserInitiatedNavigations) {}

// Ensure that renderer initiated same-site navigations work.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       RendererInitiatedSameSiteNavigation) {}

// Ensure that renderer initiated cross-site navigations work.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       RendererInitiatedCrossSiteNavigation) {}

// Ensure navigation failures are handled.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, FailedNavigation) {}

// Ensure that browser initiated navigations to view-source URLs works.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       ViewSourceNavigation_BrowserInitiated) {}

// Ensure that content initiated navigations to view-sources URLs are blocked.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       ViewSourceNavigation_RendererInitiated) {}

// Ensure that content initiated navigations to googlechrome: URLs are blocked.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       GoogleChromeNavigation_RendererInitiated) {}

// Ensure that closing a page by running its beforeunload handler doesn't hang
// if there's an ongoing navigation.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, UnloadDuringNavigation) {}

// Ensure that the referrer of a navigation is properly sanitized.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, SanitizeReferrer) {}

// Ensure the correctness of a navigation request's referrer. This is a
// regression test for https://crbug.com/1004083.
IN_PROC_BROWSER_TEST_P(NavigationBrowserTestReferrerPolicy, ReferrerPolicy) {}

// Test to verify that an exploited renderer process trying to upload a file
// it hasn't been explicitly granted permissions to is correctly terminated.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, PostUploadIllegalFilePath) {}

// Test case to verify that redirects to data: URLs are properly disallowed,
// even when invoked through a reload.
// See https://crbug.com/723796.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       VerifyBlockedErrorPageURL_Reload) {}

// TODO(crbug.com/40924471): Test is flaky on Android, Linux.
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX)
#define MAYBE_BackFollowedByReload
#else
#define MAYBE_BackFollowedByReload
#endif
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, MAYBE_BackFollowedByReload) {}

// Test that a navigation response can be entirely fetched, even after the
// NavigationURLLoader has been deleted.
IN_PROC_BROWSER_TEST_F(NavigationBaseBrowserTest,
                       FetchResponseAfterNavigationURLLoaderDeleted) {}

IN_PROC_BROWSER_TEST_F(NetworkIsolationNavigationBrowserTest,
                       BrowserNavigationNetworkIsolationKey) {}

IN_PROC_BROWSER_TEST_F(NetworkIsolationNavigationBrowserTest,
                       RenderNavigationIsolationInfo) {}

IN_PROC_BROWSER_TEST_F(NetworkIsolationNavigationBrowserTest,
                       SubframeIsolationInfo) {}

// Tests that the initiator is not set for a browser initiated top frame
// navigation.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, BrowserNavigationInitiator) {}

// Test that the initiator is set to the starting page when a renderer initiated
// navigation goes from the starting page to another page.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, RendererNavigationInitiator) {}

// Test that the initiator is set to the starting page when a sub frame is
// navigated by Javascript from some starting page to another page.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, SubFrameJsNavigationInitiator) {}

// Test that the initiator is set to the starting page when a sub frame,
// selected by Id, is navigated by Javascript from some starting page to another
// page.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       SubframeNavigationByTopFrameInitiator) {}

IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       RendererInitiatedCrossSiteNewWindowInitator) {}

// Ensure that renderer initiated navigations which have the opener suppressed
// work.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       RendererInitiatedNewWindowNoOpenerNavigation) {}

IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       RendererInitiatedWithSubframeInitator) {}

IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       InitiatorFrameStateConsistentAtDidStartNavigation) {}

IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       RendererInitiatedMiddleClickInitator) {}

// Data URLs can have a reference fragment like any other URLs. This test makes
// sure it is taken into account.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, DataURLWithReferenceFragment) {}

// Regression test for https://crbug.com/796561.
// 1) Start on a document with history.length == 1.
// 2) Create an iframe and call history.pushState at the same time.
// 3) history.back() must work.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       IframeAndPushStateSimultaneously) {}

// Regression test for https://crbug.com/260144
// Back/Forward navigation in an iframe must not stop ongoing XHR.
IN_PROC_BROWSER_TEST_F(NavigationBaseBrowserTest,
                       IframeNavigationsDoNotStopXHR) {}

// Regression test for https://crbug.com/856396.
// Note that original issue for the bug is not applicable anymore, because there
// is no provisional document loader which has not committed yet. We keep the
// modified version of this test to check removing iframe from the load event
// handler.
IN_PROC_BROWSER_TEST_F(NavigationBaseBrowserTest,
                       ReplacingDocumentLoaderFiresLoadEvent) {}

class NavigationDownloadBrowserTest : public NavigationBaseBrowserTest {};

// Regression test for https://crbug.com/855033
// 1) A page contains many scripts and DOM elements. It forces the parser to
//    yield CPU to other tasks. That way the response body's data are not fully
//    read when URLLoaderClient::OnComplete(..) is received.
// 2) A script makes the document navigates elsewhere while it is still loading.
//    It cancels the parser of the current document. Due to a bug, the document
//    loader was not marked to be 'loaded' at this step.
// 3) The request for the new navigation starts and it turns out it is a
//    download. The navigation is dropped.
// 4) There are no more possibilities for DidStopLoading() to be sent.
IN_PROC_BROWSER_TEST_F(NavigationDownloadBrowserTest,
                       StopLoadingAfterDroppedNavigation) {}

// Renderer initiated back/forward navigation in beforeunload should not prevent
// the user to navigate away from a website.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, HistoryBackInBeforeUnload) {}

// Same as 'HistoryBackInBeforeUnload', but wraps history.back() inside
// window.setTimeout(). Thus it is executed "outside" of its beforeunload
// handler and thus avoid basic navigation circumventions.
// Regression test for: https://crbug.com/879965.
IN_PROC_BROWSER_TEST_F(NavigationGoToEntryAtOffsetBrowserTest,
                       HistoryBackInBeforeUnloadAfterSetTimeout) {}

// Renderer initiated back/forward navigation can't cancel an ongoing browser
// initiated navigation if it is not user initiated.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       HistoryBackCancelPendingNavigationNoUserGesture) {}

// Renderer initiated back/forward navigation can cancel an ongoing browser
// initiated navigation if it is user initiated.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       HistoryBackCancelPendingNavigationUserGesture) {}

// Ensure the renderer process doesn't send too many IPC to the browser process
// when history.pushState() and history.back() are called in a loop.
// Failing to do so causes the browser to become unresponsive.
// See https://crbug.com/882238
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, IPCFlood_GoToEntryAtOffset) {}

// Ensure the renderer process doesn't send too many IPC to the browser process
// when doing a same-document navigation is requested in a loop.
// Failing to do so causes the browser to become unresponsive.
// TODO(arthursonzogni): Make the same test, but when the navigation is
// requested from a remote frame.
// See https://crbug.com/882238
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, IPCFlood_Navigation) {}

// TODO(http://crbug.com/632514): This test currently expects opener downloads
// go through, but when the linked bug is resolved the download should be
// disallowed.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, OpenerNavigation_DownloadPolicy) {}

// A variation of the OpenerNavigation_DownloadPolicy test above, but uses a
// cross-origin URL for the popup window.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       CrossOriginOpenerNavigation_DownloadPolicy) {}

// Regression test for https://crbug.com/872284.
// A NavigationThrottle cancels a download in WillProcessResponse.
// The navigation request must be canceled and it must also cancel the network
// request. Failing to do so resulted in the network socket being leaked.
IN_PROC_BROWSER_TEST_F(NavigationDownloadBrowserTest,
                       CancelDownloadOnResponseStarted) {}

// Add header on redirect.
IN_PROC_BROWSER_TEST_F(NavigationBaseBrowserTest, AddRequestHeaderOnRedirect) {}

// Add header on request start, modify it on redirect.
IN_PROC_BROWSER_TEST_F(NavigationBaseBrowserTest,
                       AddRequestHeaderModifyOnRedirect) {}

// Add header on request start, remove it on redirect.
IN_PROC_BROWSER_TEST_F(NavigationBaseBrowserTest,
                       AddRequestHeaderRemoveOnRedirect) {}

// Name of header used by CorsInjectingUrlLoader.
const std::string kCorsHeaderName =;

// URLLoaderThrottle that stores the last value of |kCorsHeaderName|.
class CorsInjectingUrlLoader : public blink::URLLoaderThrottle {};

// ContentBrowserClient responsible for creating CorsInjectingUrlLoader.
class CorsContentBrowserClient : public ContentBrowserTestContentBrowserClient {};

class NavigationCorsExemptBrowserTest : public NavigationBaseBrowserTest {};

// Verifies a header added by way of SetRequestHeader() makes it into
// |cors_exempt_headers|.
IN_PROC_BROWSER_TEST_F(NavigationCorsExemptBrowserTest,
                       SetCorsExemptRequestHeader) {}

// Test NavigationRequest::CheckAboutSrcDoc()
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, BlockedSrcDocBrowserInitiated) {}

// Test NavigationRequest::CheckAboutSrcDoc().
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, BlockedSrcDocRendererInitiated) {}

// Ensure that about:srcdoc navigations get their origin and base URL from their
// parent frame (since that's where the content comes from) and not from the
// initiator of the navigation (like about:blank cases). See also the
// NavigateGrandchildToAboutBlank test. See https://crbug.com/1515381.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       GrandchildToAboutSrcdoc_BaseUrl_CrossOrigin) {}

IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       GrandchildToAboutSrcdoc_BaseUrl_SameOrigin) {}

// Ensure that about:blank navigations get their origin and base URL from the
// initiator of the navigation, and not from their parent frame (like
// about:srcdoc cases). See also the NavigateGrandchildToAboutSrcdoc test.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, GrandchildToAboutBlank_BaseUrl) {}

// Test renderer initiated navigations to about:srcdoc are routed through the
// browser process. It means RenderFrameHostImpl::BeginNavigation() is called.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, AboutSrcDocUsesBeginNavigation) {}

// Regression test for https://crbug.com/996044
//  1) Navigate an iframe to srcdoc (about:srcdoc);
//  2) Same-document navigation to about:srcdoc#1.
//  3) Same-document navigation to about:srcdoc#2.
//  4) history.back() to about:srcdoc#1.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       SrcDocWithFragmentHistoryNavigation) {}

// Regression test for https://crbug.com/996044.
//  1) Navigate an iframe to srcdoc (about:srcdoc).
//  2) Cross-document navigation to about:srcdoc?1.
//  3) Cross-document navigation to about:srcdoc?2.
//  4) history.back() to about:srcdoc?1.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       SrcDocWithQueryHistoryNavigation) {}

// Make sure embedders are notified about visible URL changes in this scenario:
// 1. Navigate to A.
// 2. Navigate to B.
// 3. Add a forward entry in the history for later (same-document).
// 4. Start navigation to C.
// 5. Start history cross-document navigation, cancelling 4.
// 6. Start history same-document navigation, cancelling 5.
//
// Regression test for https://crbug.com/998284.
IN_PROC_BROWSER_TEST_F(NavigationBaseBrowserTest,
                       BackForwardInOldDocumentCancelPendingNavigation) {}

// Regression test for https://crbug.com/999932.
IN_PROC_BROWSER_TEST_F(NavigationBaseBrowserTest, CanceledNavigationBug999932) {}

// Regression test for https://crbug.com/1001283
// 1) Load main document with CSP: script-src 'none'
// 2) Open an about:srcdoc iframe. It inherits the CSP.
// 3) The iframe navigates elsewhere.
// 4) The iframe navigates back to about:srcdoc.
// Check Javascript is never allowed.
IN_PROC_BROWSER_TEST_F(NavigationBaseBrowserTest,
                       SrcDocCSPInheritedAfterSameSiteHistoryNavigation) {}

IN_PROC_BROWSER_TEST_F(NavigationBaseBrowserTest,
                       SrcDocCSPInheritedAfterCrossSiteHistoryNavigation) {}

// Test that NavigationRequest::GetNextPageUkmSourceId returns the eventual
// value of RenderFrameHost::GetPageUkmSourceId() --- unremarkable top-level
// navigation case.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       NavigationRequest_GetNextPageUkmSourceId_Basic) {}

// Test that NavigationRequest::GetNextPageUkmSourceId returns the eventual
// value of RenderFrameHost::GetPageUkmSourceId() --- child frame case.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       NavigationRequest_GetNextPageUkmSourceId_ChildFrame) {}

// Test that NavigationRequest::GetNextPageUkmSourceId returns the eventual
// value of RenderFrameHost::GetPageUkmSourceId() --- same document navigation.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       NavigationRequest_GetNextPageUkmSourceId_SameDocument) {}

// Test that NavigationRequest::GetNextPageUkmSourceId returns the eventual
// value of RenderFrameHost::GetPageUkmSourceId() --- back navigation;
// this case matters because of back-forward cache.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       NavigationRequest_GetNextPageUkmSourceId_Back) {}

// Tests for cookies. Provides an HTTPS server.
class NavigationCookiesBrowserTest : public NavigationBaseBrowserTest {};

// Test how cookies are inherited in about:srcdoc iframes.
//
// Regression test: https://crbug.com/1003167.
// Test is flaky on all platforms: https://crbug.com/339033006
IN_PROC_BROWSER_TEST_F(NavigationCookiesBrowserTest,
                       DISABLED_CookiesInheritedSrcDoc) {}

// Test how cookies are inherited in about:blank iframes.
IN_PROC_BROWSER_TEST_F(NavigationCookiesBrowserTest,
                       CookiesInheritedAboutBlank) {}

// Test how cookies are inherited in about:blank iframes.
//
// This is a variation of
// NavigationCookiesBrowserTest.CookiesInheritedAboutBlank. Instead of
// requesting an history navigation, a new navigation is requested from the main
// frame. The navigation is cross-site instead of being same-site.
IN_PROC_BROWSER_TEST_F(NavigationCookiesBrowserTest,
                       CookiesInheritedAboutBlank2) {}

// Test how cookies are inherited in data-URL iframes.
IN_PROC_BROWSER_TEST_F(NavigationCookiesBrowserTest, CookiesInheritedDataUrl) {}

// Tests for validating URL rewriting behavior like chrome://newtab to
// chrome-native://newtab.
class NavigationUrlRewriteBrowserTest : public NavigationBaseBrowserTest {};

// Tests navigating to a URL that gets rewritten to a "no access" URL. This
// mimics the behavior of navigating to special URLs like chrome://newtab and
// chrome://history which get rewritten to "no access" chrome-native:// URLs.
IN_PROC_BROWSER_TEST_F(NavigationUrlRewriteBrowserTest, RewriteToNoAccess) {}

IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, SameDocumentNavigation) {}

// Some navigations are not allowed, such as when they fail the content security
// policy, or for trying to load about:srcdoc in the main frame. These result in
// us redirecting the navigation to an error page via
// RenderFrameHostImpl::FailedNavigation().
// Repeating the request with a different URL fragment results in attempting a
// same-document navigation, but error pages do not support such navigations. In
// this case treat each failed navigation request as a separate load, with the
// resulting navigation being performed as a cross-document navigation. This is
// regression test for https://crbug.com/1018385.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       SameDocumentNavigationOnBlockedPage) {}

// This navigation is allowed by the browser, but the network will not be able
// to connect to the site, so the NavigationRequest fails on the browser side
// and is redirected to an error page. Performing another navigation should
// make the full attempt again, in case the network request succeeds this time.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       SameDocumentNavigationOnBadServerErrorPage) {}

// This navigation is allowed by the browser, and the request to the server is
// successful, but it returns 404 error headers, and (optionally) an error page.
// When another request is made for the same page but with a different fragment,
// the browser will attempt to perform a same-document navigation but that
// navigation is intended for the actual document not the error page that has
// been loaded instead. A same-document navigation in the renderer-loaded error
// page should be performed as a cross-document navigation in order to attempt
// to reload the page.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       SameDocumentNavigationOn404ErrorPage) {}

IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       SameDocumentNavigationFromCrossDocumentRedirect) {}

// 1. The browser navigates to a.html.
// 2. The renderer uses history.pushState() to change the URL of the current
//    document from a.html to b.html.
// 3. The browser tries to perform a same-document navigation to a.html#foo,
//    since it did not hear about the document's URL changing yet. When it gets
//    to the renderer, we discover a race has happened.
// 4. Meanwhile, the browser hears about the URL change to b.html and applies
//    it.
// Now - how do we resolve the race?
// 5. We will reorder the a.html#foo navigation to start over in the browser
//    after the b.html navigation.
// Technically, this is still a same-document navigation! The URL changed but
// the document did not. Currently, however, the browser only considers the URL
// when performing a non-history navigation to decide if it's a same-document
// navigation, so..
// 6. The browser will perform a cross-document navigation to a.html#foo.
//
// TODO(crbug.com/40799231): Test is flaky on various platforms.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       DISABLED_SameDocumentNavigationRacesPushStateURLChange) {}

class GetEffectiveUrlClient : public ContentBrowserTestContentBrowserClient {};

// While a document is open, state in the browser may change such that loading
// the document would choose a different SiteInstance. A cross-document
// navigation would pick up this different SiteInstance, but a same-document
// navigation should not. It should just navigate inside the currently loaded
// document instead of reloading the document.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       SameDocumentNavigationWhenSiteInstanceWouldChange) {}

// This tests the same ideas as the above test except in this case the same-
// document navigation is done through a history navigation, which exercises
// different codepaths in the NavigationControllerImpl.
IN_PROC_BROWSER_TEST_F(
    NavigationBrowserTest,
    SameDocumentHistoryNavigationWhenSiteInstanceWouldChange) {}

// Verify that actual renderer-initiated navigations to about:blank#blocked
// are respected, even though both the browser and renderer rewrite some illegal
// navigations to that URL as well. See https://crbug.com/40066983.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       SameDocumentHashNavigationToBlockedFragmentAllowed) {}

// Verify that same-document navigations from about:blank to an excessively long
// fragment do not crash the browser.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       SameDocumentAboutBlankLongURLHashNavigation) {}

IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       SameDocumentLongURLHashNavigation) {}

IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, SameDocumentLongURLPushState) {}

IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       SameDocumentLongURL204PopupHashNavigation) {}

IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       SameDocumentLongURL204PopupPushState) {}

// Ensure that no crash occurs when doing a same-document navigation within a
// site-less SiteInstance, such as for a browser-initiated about:blank.
// See https://crbug.com/359807735.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, SameDocumentSitelessNavigation) {}

IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       NonDeterministicUrlRewritesUseLastUrl) {}

// Create two windows. When the second is deleted, it initiates a navigation in
// the first. This is a situation where the navigation has an initiator frame
// token, but no corresponding RenderFrameHost.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       RendererInitiatedCrossWindowNavigationInPagehide) {}

// A document initiates a form submission in another frame, then deletes itself.
// Check the initiator frame token.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, FormSubmissionThenDeleteFrame) {}

// Same as the previous test, but for a remote frame navigation:
// A document initiates a form submission in a cross-origin frame, then deletes
// itself. Check the initiator frame token.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       FormSubmissionInRemoteFrameThenDeleteFrame) {}

// A class to intercept RemoteFrameHost IPCs, specifically OpenURL. When an
// OpenURL IPC is received, this interceptor closes the initiator's Shell,
// `shell_to_close`, and ensures the corresponding process exits before
// proceeding with the OpenURL call.
class InitiatorClosingOpenURLInterceptor
    : public blink::mojom::RemoteFrameHostInterceptorForTesting {};

// Test the case that once an OpenURL IPC is sent, it is received and the
// navigation occurs even if the sender is deleted while the IPC is in flight.
// This test opens a main frame, which opens a cross-site popup. The test then
// does a form submission to the popup and closes the main frame.
// Unlike FormSubmissionInRemoteFrameThenDeleteFrame, the initiator is the last
// (and only) frame of that SiteInstance. Deleting it usually causes proxies in
// the same SiteInstanceGroup to be deleted, meaning the OpenURL IPC may never
// be received.
//
// Fails on linux-bfcache-rel and android-bfcache-rel. See crbug.com/336671248.
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID)
#define MAYBE_FormSubmissionInRemoteFrameSenderDeletedBeforeReceivingOpenURL
#else
#define MAYBE_FormSubmissionInRemoteFrameSenderDeletedBeforeReceivingOpenURL
#endif
IN_PROC_BROWSER_TEST_F(
    NavigationBrowserTest,
    MAYBE_FormSubmissionInRemoteFrameSenderDeletedBeforeReceivingOpenURL) {}

MediaNavigationBrowserTest;

// Media navigations synchronously complete the time of the `CommitNavigation`
// IPC call. Ensure that the renderer does not crash if the media navigation
// results in an HTTP error with no body, since the renderer will reentrantly
// commit an error page while handling the `CommitNavigation` IPC.
IN_PROC_BROWSER_TEST_F(MediaNavigationBrowserTest, FailedNavigation) {}

DocumentPolicyBrowserTest;

// Test that scroll restoration can be disabled with
// Document-Policy: force-load-at-top
IN_PROC_BROWSER_TEST_F(DocumentPolicyBrowserTest,
                       ScrollRestorationDisabledByDocumentPolicy) {}

// Test that scroll restoration works as expected with
// Document-Policy: force-load-at-top=?0
IN_PROC_BROWSER_TEST_F(DocumentPolicyBrowserTest,
                       ScrollRestorationEnabledByDocumentPolicy) {}

// Test that element fragment anchor scrolling can be disabled with
// Document-Policy: force-load-at-top
IN_PROC_BROWSER_TEST_F(DocumentPolicyBrowserTest,
                       FragmentAnchorDisabledByDocumentPolicy) {}

// Test that element fragment anchor scrolling works as expected with
// Document-Policy: force-load-at-top=?0
IN_PROC_BROWSER_TEST_F(DocumentPolicyBrowserTest,
                       FragmentAnchorEnabledByDocumentPolicy) {}

IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, OriginToCommitBasic) {}

IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, OriginToCommit204) {}

IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       OriginToCommitSandboxFromResponse) {}

IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       OriginToCommitSandboxFromParentDocument) {}

// Regression test for https://crbug.com/1158306.
// Navigate to a response, which set Content-Security-Policy: sandbox AND block
// the response. The error page shouldn't set sandbox flags.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, ErrorPageFromCspSandboxResponse) {}

IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       ProcessShutdownDuringDeferredNavigationThrottle) {}

// Sandbox flags defined by the parent must not apply to Chrome's error page.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, ErrorPageFromInSandboxedIframe) {}

IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, OriginToCommitSandboxFromFrame) {}

IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       NavigateToAboutBlankWhileFirstNavigationPending) {}

class NetworkIsolationSplitCacheAppendIframeOrigin
    : public NavigationBaseBrowserTest {};

// Make a main document, have it request a cacheable subresources. Then make a
// same-site document in an iframe that serves the CSP:Sandbox header. Stop the
// test server, have the sandboxed document requests the same subresource. The
// request should fail. To make sure the request is actually in the cache, the
// main document should be able to request it again.
IN_PROC_BROWSER_TEST_F(NetworkIsolationSplitCacheAppendIframeOrigin,
                       SandboxedUsesDifferentCache) {}

// The Content Security Policy directive 'treat-as-public-address' is parsed
// into the parsed headers by services/network and applied there. That directive
// is ignored in report-only policies. Here we check that Blink reports a
// console message if 'treat-as-public-address' is delivered in a report-only
// policy. This serves also as a regression test for https://crbug.com/1150314
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       TreatAsPublicAddressInReportOnly) {}

// The Content Security Policy directive 'plugin-types' has been removed. Here
// we check that Blink reports a console message if 'plugin-type' is delivered
// in a policy.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       ContentSecurityPolicyErrorPluginTypes) {}

class SubresourceLoadingTest : public NavigationBrowserTest {};

// The test below verifies that an "about:blank" navigation commits with the
// right origin, even when the initiator of the navigation is not the parent or
// opener of the frame targeted by the navigation.  In the
// GrandchildToAboutBlank... testcases, the navigation is initiated by the
// grandparent of the target frame.
//
// In this test case there are no process swaps and the parent of the navigated
// frame is a local frame (even in presence of site-per-process).  See also
// GrandchildToAboutBlank_ABA_CrossSite and
// GrandchildToAboutBlank_ABB_CrossSite.
IN_PROC_BROWSER_TEST_F(SubresourceLoadingTest,
                       GrandchildToAboutBlank_ABA_SameSite) {}

// The test below verifies that an "about:blank" navigation commits with the
// right origin, even when the initiator of the navigation is not the parent or
// opener of the frame targeted by the navigation.  In the
// GrandchildToAboutBlank... testcases, the navigation is initiated by the
// grandparent of the target frame.
//
// In this test case there are no process swaps and the parent of the navigated
// frame is a remote frame (in presence of site-per-process).  See also
// GrandchildToAboutBlank_ABA_SameSite and GrandchildToAboutBlank_ABB_CrossSite.
IN_PROC_BROWSER_TEST_F(SubresourceLoadingTest,
                       GrandchildToAboutBlank_ABA_CrossSite) {}

// The test below verifies that an "about:blank" navigation commits with the
// right origin, even when the initiator of the navigation is not the parent or
// opener of the frame targeted by the navigation.  In the
// GrandchildToAboutBlank... testcases, the navigation is initiated by the
// grandparent of the target frame.
//
// In this test case the navigation forces a process swap of the target frame.
// See also GrandchildToAboutBlank_ABA_SameSite and
// GrandchildToAboutBlank_ABA_CrossSite.
IN_PROC_BROWSER_TEST_F(SubresourceLoadingTest,
                       GrandchildToAboutBlank_ABB_CrossSite) {}

// The test below verifies that an "about:blank" navigation commits with the
// right origin, even when the initiator of the navigation is not the parent or
// opener of the frame targeted by the navigation.  In the
// TopToAboutBlank_CrossSite testcase, the top-level navigation is initiated by
// a cross-site subframe.
IN_PROC_BROWSER_TEST_F(SubresourceLoadingTest, TopToAboutBlank_CrossSite) {}

// The test below verifies that an "about:blank" navigation commits with the
// right origin, even when the initiator of the navigation is not the parent or
// opener of the frame targeted by the navigation.  In the
// SameSiteSiblingToAboutBlank_CrossSiteTop testcase, the navigation is
// initiated by a same-origin sibling (notably, not by one of target frame's
// ancestors) and both siblings are subframes of a cross-site main frame.
IN_PROC_BROWSER_TEST_F(SubresourceLoadingTest,
                       SameSiteSiblingToAboutBlank_CrossSiteTop) {}

// The test below verifies that an initial empty document has a functional
// URLLoaderFactory.  Note that some aspects of the current behavior (e.g. the
// synchronous re-navigation) are not spec-compliant - see
// https://crbug.com/778318 and https://github.com/whatwg/html/issues/3267.
// Note that the same behavior is expected in the ...NewFrameWithoutSrc and
// in the ...NewFrameWithAboutBlank testcases.
IN_PROC_BROWSER_TEST_F(SubresourceLoadingTest,
                       URLLoaderFactoryInInitialEmptyDoc_NewFrameWithoutSrc) {}

// See the doc comment for the
// URLLoaderFactoryInInitialEmptyDoc_NewFrameWithoutSrc test case.
IN_PROC_BROWSER_TEST_F(
    SubresourceLoadingTest,
    URLLoaderFactoryInInitialEmptyDoc_NewFrameWithAboutBlank) {}

IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       SameOriginFlagOfSameOriginAboutBlankNavigation) {}

IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       SameOriginFlagOfCrossOriginAboutBlankNavigation) {}

IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       SameOriginFlagOfSrcdocNavigation) {}

IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       SameOriginFlagOfAboutBlankToAboutBlankNavigation) {}

IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, SameOriginOfSandboxedIframe) {}

// The test below verifies that an initial empty document has a functional
// URLLoaderFactory.
IN_PROC_BROWSER_TEST_F(SubresourceLoadingTest,
                       URLLoaderFactoryInInitialEmptyDoc_NewPopupToEmptyUrl) {}

// See the doc comment for the
// URLLoaderFactoryInInitialEmptyDoc_NewPopupToEmptyUrl test case.
IN_PROC_BROWSER_TEST_F(SubresourceLoadingTest,
                       URLLoaderFactoryInInitialEmptyDoc_NewPopupToAboutBlank) {}

// The test below verifies that error pages have a functional URLLoaderFactory.
IN_PROC_BROWSER_TEST_F(SubresourceLoadingTest, URLLoaderFactoryInErrorPage) {}

// The test below verifies that an initial empty document has a functional
// URLLoaderFactory.
IN_PROC_BROWSER_TEST_F(
    SubresourceLoadingTest,
    URLLoaderFactoryInInitialEmptyDoc_HungNavigationInSubframe) {}

// The test below verifies that an initial empty document has a functional
// URLLoaderFactory.
IN_PROC_BROWSER_TEST_F(
    SubresourceLoadingTest,
    URLLoaderFactoryInInitialEmptyDoc_HungNavigationInPopup) {}

// The test below verifies that an initial empty document has a functional
// URLLoaderFactory.  The ...WithClearedOpener testcase is a regression test for
// https://crbug.com/1191203.
IN_PROC_BROWSER_TEST_F(
    SubresourceLoadingTest,
    URLLoaderFactoryInInitialEmptyDoc_HungNavigationInPopupWithClearedOpener) {}

// The test below verifies that an initial empty document has a functional
// URLLoaderFactory.
IN_PROC_BROWSER_TEST_F(SubresourceLoadingTest,
                       URLLoaderFactoryInInitialEmptyDoc_204NoOpenerPopup) {}

// The test below verifies that an initial empty document has a functional
// URLLoaderFactory.
IN_PROC_BROWSER_TEST_F(
    SubresourceLoadingTest,
    URLLoaderFactoryInInitialEmptyDoc_HungNavigationInNewWindow) {}

namespace {

struct Result {};

class NavigationLogger : public WebContentsObserver {};

}  // namespace

class UndoCommitNavigationBrowserTest : public NavigationBrowserTest {};

// A helper that invokes `functor` on the next `DidStartNavigation()`.
template <typename F>
void OnNextDidStartNavigation(WebContents* web_contents, F&& functor) {}

IN_PROC_BROWSER_TEST_F(UndoCommitNavigationBrowserTest,
                       PerformanceManagerFrameTreeConsistency) {}

class ResumeCommitClosureSetWaiter {};

class NavigationQueueingBrowserTest : public NavigationBrowserTest {};

IN_PROC_BROWSER_TEST_F(NavigationQueueingBrowserTest, Regular) {}

class CommitNavigationRaceBrowserTest
    : public NavigationBrowserTest,
      public ::testing::WithParamInterface<bool> {};

// Test for https://crbug.com/40187807 and https://crbug.com/332746903.
//
// Ensure that racing a navigation commit in a speculative/provisional child
// frame in render process B with a detach IPC from render process A (i.e. the
// child frame's parent is in render process A and has removed the frame owner
// element—e.g. <iframe>—from the DOM) does not result in the detach IPC being
// discarded and never received by render process B.
IN_PROC_BROWSER_TEST_P(CommitNavigationRaceBrowserTest,
                       DetachAfterCommitNavigationInSubFrame) {}

IN_PROC_BROWSER_TEST_P(CommitNavigationRaceBrowserTest,
                       BeginNewNavigationDuringCommitNavigationInMainFrame) {}

IN_PROC_BROWSER_TEST_P(CommitNavigationRaceBrowserTest,
                       BeginNewNavigationDuringCommitNavigationInSubFrame) {}

// Test the behavior of a navigation that gets suspended in the pending commit
// state followed by another navigation that results in a failed navigation. A
// failed navigation is not a navigation that results in an HTTP error page; it
// is a situation where the network request itself fails, e.g. DNS resolution
// failed, and Chrome commits an error page instead.
IN_PROC_BROWSER_TEST_P(
    CommitNavigationRaceBrowserTest,
    BeginNewNavigationDuringCommitFailedNavigationInMainFrame) {}

IN_PROC_BROWSER_TEST_P(
    CommitNavigationRaceBrowserTest,
    BeginNewNavigationDuringCommitFailedNavigationInSubFrame) {}

// about:blank navigations do not require a URL loader and go through a
// different path to commit the navigation in the renderer.
IN_PROC_BROWSER_TEST_P(
    CommitNavigationRaceBrowserTest,
    BeginNewNavigationWithNoUrlLoaderDuringCommitNavigationInMainFrame) {}

IN_PROC_BROWSER_TEST_P(
    CommitNavigationRaceBrowserTest,
    BeginNewNavigationWithNoUrlLoaderDuringCommitNavigationInSubFrame) {}

// Tests when a navigation is pending commit, two new navigations start one
// after another in the same frame.
IN_PROC_BROWSER_TEST_P(CommitNavigationRaceBrowserTest,
                       BeginTwoNavigationsDuringCommitNavigation) {}

// Verify that a speculative RFH in the pending commit state is still cleaned up
// if the renderer crashes.
IN_PROC_BROWSER_TEST_P(CommitNavigationRaceBrowserTest,
                       CrashedInPendingCommit) {}

// Tests when a back navigation is pending commit, then another back navigation
// starts.
IN_PROC_BROWSER_TEST_P(CommitNavigationRaceBrowserTest,
                       MultipleBackNavigation) {}

INSTANTIATE_TEST_SUITE_P();

// Validate browser-side state when a pending commit RFH sends a bad
// CommitNavigation() IPC. Immediately after the bad message is reported, the
// speculative RFH should remain in the kPendingCommit state, but with no
// pending commit for a cross-document navigation. This somewhat odd state comes
// about because processing the commit navigation ack consumes the
// NavigationRequest early on, before the bad message is reported. Reporting the
// bad message cancels any further processing of the commit navigation ack, but
// does not directly clear any other navigation-related state.
//
// Instead, the pending commit speculative RFH will be asynchronously torn down
// later, when the browser process observes the renderer process going away,
// which then implicitly ends the navigation.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       CommitBadNavigationInPendingCommitRFHCleanup) {}

// The following test checks what happens if a WebContentsDelegate navigates
// away in response to the NavigationStateChanged event. Previously
// (https://crbug.com/1210234), this was triggering a crash when creating the
// new NavigationRequest, because it was trying to access the current
// RenderFrameHost's PolicyContainerHost, which had not been set up yet by
// RenderFrameHostImpl::DidNavigate.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, Bug1210234) {}

class NavigationBrowserTestCredentiallessIframe : public NavigationBrowserTest {};

IN_PROC_BROWSER_TEST_F(NavigationBrowserTestCredentiallessIframe,
                       CredentiallessAttributeIsHonoredByNavigation) {}

// Ensures that OpenURLParams::FromNavigationHandle translates navigation params
// correctly when used to initiate a navigation in another WebContents.
IN_PROC_BROWSER_TEST_F(
    NavigationBrowserTest,
    FromNavigationHandleTranslatesNavigationParamsCorrectly) {}

// Regression test for https://crbug.com/1392653.  Ensure that loading a URL
// that doesn't go through the network stack but does assign a site for its
// SiteInstance in an unassigned SiteInstance does not fail.  An example of
// such a URL is about:srcdoc. This ensures that the SiteInstance's site is set
// even on the WillCommitWithoutUrlLoader() path in NavigationRequest.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       AboutSrcdocInjectedOnAboutBlankPage) {}

class NavigationBrowserTestWarnSandboxIneffective
    : public NavigationBrowserTest {};

IN_PROC_BROWSER_TEST_F(NavigationBrowserTestWarnSandboxIneffective,
                       WarnEscapableSandboxSameOrigin) {}

IN_PROC_BROWSER_TEST_F(NavigationBrowserTestWarnSandboxIneffective,
                       WarnEscapableSandboxCrossOrigin) {}

IN_PROC_BROWSER_TEST_F(NavigationBrowserTestWarnSandboxIneffective,
                       WarnEscapableSandboxSameOriginGrandChild) {}

// We may have an unload handler in the main frame or a subframe or nowhere.
enum class UnloadFrameType {};

static std::string ToString(UnloadFrameType v) {}

// We may navigate the main frame, the subframe that may have an unload handler
// or another subframe that will never have an unload handler.
enum class NavigateFrameType {};

static std::string ToString(NavigateFrameType v) {}

void AddUnloadHandler(RenderFrameHostImpl* rfh) {}

class NavigationSuddenTerminationDisablerTypeBrowserTest
    : public NavigationBrowserTest {};

class NavigationSuddenTerminationDisablerTypeWithFrameTypeBrowserTest
    : public NavigationSuddenTerminationDisablerTypeBrowserTest,
      public ::testing::WithParamInterface<
          std::tuple<UnloadFrameType, NavigateFrameType>> {};

INSTANTIATE_TEST_SUITE_P();

// Set up a page with 2 subframes. The main frame or one of the subframes may
// have an unload handler. Then navigate one of the frames and verify that we
// correctly record which type of frame navigates combined with whether it
// involved an unload handler.
IN_PROC_BROWSER_TEST_P(
    NavigationSuddenTerminationDisablerTypeWithFrameTypeBrowserTest,
    RecordUma) {}

// Test that "SameOrigin" only considers frames that have an unbroken path of
// same-origin frames from the frame that navigates.
IN_PROC_BROWSER_TEST_F(
    NavigationSuddenTerminationDisablerTypeBrowserTest,
    NavigationSuddenTerminationDisablerTypeRecordUmaSameOrigin) {}

// Test that we record when the navigation involves restoring from BFCache.
// This is tested because the code path for a navigation involving activation
// is different from one involving a pageload.
IN_PROC_BROWSER_TEST_F(
    NavigationSuddenTerminationDisablerTypeBrowserTest,
    NavigationSuddenTerminationDisablerTypeRecordUmaActivation) {}

// Ensure that the first navigation of a subframe away from the initial empty
// document is recorded correctly. This does not test all possibilities of
// histogram value, just that the scenario is counted under the correct
// histogram.
IN_PROC_BROWSER_TEST_F(
    NavigationSuddenTerminationDisablerTypeBrowserTest,
    NavigationSuddenTerminationDisablerTypeRecordUmaInitialEmptyDocument) {}

// Ensure that navigations from non-HTTP(S) pages are recorded correctly.
IN_PROC_BROWSER_TEST_F(
    NavigationSuddenTerminationDisablerTypeBrowserTest,
    NavigationSuddenTerminationDisablerTypeRecordUmaNotHttp) {}

// This is a regression test against https://crbug.com/1145717 - navigating to
// invalid/weird URLs (e.g. `about:mumble` or `about://mumble`) shouldn't crash.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, AboutMumble) {}

// Ensure that the browser process doesn't see a javascript: URL when opening a
// new window to a javascript: URL. These URLs are typically handled on the
// renderer side, and the renderer should not send the javascript: URL to the
// browser in a navigation request. Previously, this was not correctly handled
// for initial navigations to javascript: URLs. See https://crbug.com/1357515.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, FilterURL_JavascriptURLs) {}

// Ensure that opening popups to empty URLs does not fail FilterURL. The
// renderer process treats empty URLs as about:blank, but the browser process
// does not consider them valid and may treat them as attempts to go to the NTP
// in some cases. As a result, the renderer should map empty URLs to about:blank
// before making navigation requests. See https://crbug.com/1357515.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, FilterURL_EmptyURL) {}

// Check that an about:blank popup opened from a WebUI page is not allowed to
// execute Javascript URLs. chrome:// pages don't allow executing javascript:
// URLs, so an about:blank popup opened by one should not be allowed to either,
// despite its URL not having the chrome: scheme.  See
// https://crbug.com/1471305.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       JavascriptURLBlockedInAboutBlankWebUiPopup) {}

// Same test as above, but with a sandboxed about:blank WebUI popup, which
// should still not be allowed to execute Javascript URLs.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       JavascriptURLBlockedInSandboxedWebUiPopup) {}

// Test navigation with site instances whose storage partitions are fixed.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, FixedStoragePartition) {}

// Exercises the restored session history traversal code path which uses
// RESTORE navigation types, rather than HISTORY_{SAME|DIFFERENT}_DOCUMENT,
// which code might erroneously expect. See https://crbug.com/40068335.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       TraversingToRestoredEntryUsesRestoreType) {}

class NavigationBrowserTestDeprecateUnloadOptOut
    : public NavigationBrowserTest,
      public ::testing::WithParamInterface<bool> {};

INSTANTIATE_TEST_SUITE_P();

// Test that enabled/disabled kDeprecateUnloadOptOut has the desired effect.
IN_PROC_BROWSER_TEST_P(NavigationBrowserTestDeprecateUnloadOptOut,
                       DeprecateUnloadOptOutFlagRespected) {}

IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, FCPMetrics) {}

// Tests that if the main frame has focus before a same-site navigation, it's
// kept after navigation.
// Regression test for crbug.com/360705823.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       FocusPreservedOnNavigation_MainFrame) {}

// Same as the above test, but the focus is on the iframe.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       FocusPreservedOnNavigation_Subframe) {}

// When the navigation is cross-site, focus is not preserved.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
                       FocusNotPreservedOnNavigation_SubframeCrossSite) {}

class NavigationWithPageSwapBrowserTest : public NavigationBrowserTest {};

IN_PROC_BROWSER_TEST_F(NavigationWithPageSwapBrowserTest,
                       PageSwapForInitialEntry) {}

IN_PROC_BROWSER_TEST_F(NavigationWithPageSwapBrowserTest,
                       PageSwapWhenTraversingToRestoredEntry) {}

class NavigationBrowserTestPaintHoldingSubframe
    : public NavigationBrowserTest,
      public ::testing::WithParamInterface<bool> {};

IN_PROC_BROWSER_TEST_P(NavigationBrowserTestPaintHoldingSubframe, Basic) {}

IN_PROC_BROWSER_TEST_P(NavigationBrowserTestPaintHoldingSubframe,
                       BasicInProcessIframe) {}

IN_PROC_BROWSER_TEST_P(NavigationBrowserTestPaintHoldingSubframe, CrossOrigin) {}

IN_PROC_BROWSER_TEST_P(NavigationBrowserTestPaintHoldingSubframe,
                       CrashSubframe) {}

INSTANTIATE_TEST_SUITE_P();

RenderFrameHostImpl* GetMainFrameSpeculativeRFH(WebContentsImpl* web_contents) {}

void VerifyDeferSpeculativeRFHActionUMA(const base::HistogramTester& tester,
                                        DeferSpeculativeRFHAction action) {}

class DeferSpeculativeRFHCreationTest : public NavigationBrowserTest {};

class DeferSpeculativeRFHCreationRenderProcessTest
    : public NavigationBrowserTest,
      public ::testing::WithParamInterface<bool> {};

// Verify the common flow for with DeferSpeculativeRFHCreation feature.
// The creation of the speculative RFH will be deferred until the network
// request is sent.
IN_PROC_BROWSER_TEST_P(DeferSpeculativeRFHCreationRenderProcessTest,
                       SpeculativeRFHCreationDeferred) {}

INSTANTIATE_TEST_SUITE_P();

// Verify that navigating from a crashed page will create a speculative
// RFH at once.
IN_PROC_BROWSER_TEST_F(DeferSpeculativeRFHCreationTest,
                       NavigationFromCrashedFrameNotDeferred) {}

// Verify that the creation of the speculative RFH is not deferred for the
// web pages.
IN_PROC_BROWSER_TEST_F(DeferSpeculativeRFHCreationTest,
                       CreationNotDeferredForWebUI) {}

// Verify that the creation of the speculative RFH is not deferred for the
// pages without a URL loader.
IN_PROC_BROWSER_TEST_F(DeferSpeculativeRFHCreationTest,
                       CreationNotDeferredWithoutURLLoader) {}

// Verify that the created speculative RFH after the network request will
// be correctly replaced if the redirection points to a different site.
IN_PROC_BROWSER_TEST_F(DeferSpeculativeRFHCreationTest,
                       SpeculativeRFHWithRedirect) {}

// Test that if there is a navigation pending for commit, the deferred
// speculative RFH will not be created event after the request is sent. The new
// navigation will be queued until the pending navigation commits.
IN_PROC_BROWSER_TEST_F(DeferSpeculativeRFHCreationTest,
                       NavigateWithPendingCommit) {}

class DeferSpeculativeRFHCreationReuseRFHTest : public NavigationBrowserTest {};

// Verify that navigating with the same RFH will reuse the RFH at once.
IN_PROC_BROWSER_TEST_F(DeferSpeculativeRFHCreationReuseRFHTest,
                       ReuseSameRFHNotDeferred) {}

class VisualPropertiesSynchronization : public NavigationBrowserTest {};

// Regression test for https://crbug.com/352093463.
// Verify that when a cross-origin subframe initiates a top-level navigation to
// a same-origin (with respect to itself) URL, that the visual properties
// are invalidated correctly.
// TODO(https://crbug.com/361299696): Flaky on Fuchsia and ChromeOS Ash.
#if BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_CHROMEOS_ASH)
#define MAYBE_RemoteToLocalTransition
#else
#define MAYBE_RemoteToLocalTransition
#endif
IN_PROC_BROWSER_TEST_F(VisualPropertiesSynchronization,
                       MAYBE_RemoteToLocalTransition) {}

#if BUILDFLAG(IS_ANDROID)
class AndroidPrewarmSpareRendererTest
    : public NavigationBrowserTest,
      public ::testing::WithParamInterface<std::tuple<std::string, bool>> {
 public:
  AndroidPrewarmSpareRendererTest() {
    std::map<std::string, std::string> parameters = {
        {"spare_renderer_creation_timing", std::get<0>(GetParam())},
        {"spare_renderer_timeout_seconds",
         std::get<1>(GetParam()) ? "10" : "-1"},
    };
    feature_list_.InitWithFeaturesAndParameters(
        /*enabled_features=*/{{features::kAndroidWarmUpSpareRendererWithTimeout,
                               parameters}},
        /*disabled_features=*/{{features::kSpareRendererForSitePerProcess}});
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    // Enable site per process so that the navigation will take
    // the spare process.
    command_line->AppendSwitch(switches::kSitePerProcess);
  }

  bool SpareRendererHasTimeout() { return std::get<1>(GetParam()); }

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

INSTANTIATE_TEST_SUITE_P(
    All,
    AndroidPrewarmSpareRendererTest,
    testing::Combine(
        testing::Values(
            features::kAndroidSpareRendererCreationAfterLoading,
            features::kAndroidSpareRendererCreationAfterFirstPaint,
            features::kAndroidSpareRendererCreationDelayedDuringLoading),
        testing::Bool()));

IN_PROC_BROWSER_TEST_P(AndroidPrewarmSpareRendererTest, ReuseSpareRenderer) {
  SpareRenderProcessHostManager::GetInstance().CleanupSpareRenderProcessHost();
  SpareRenderProcessObserver render_process_observer;
  ASSERT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL("a.com", "/title1.html")));
  render_process_observer.WaitForSpareRenderProcessCreation();
  RenderProcessHost* created_process =
      render_process_observer.spare_render_process_host();
  ASSERT_TRUE(!!created_process);
  ASSERT_EQ(
      SpareRenderProcessHostManager::GetInstance().spare_render_process_host(),
      created_process);
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());
  ASSERT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL("b.com", "/title1.html")));
  ASSERT_EQ(web_contents->GetSiteInstance()->GetProcess(), created_process);
}

IN_PROC_BROWSER_TEST_P(AndroidPrewarmSpareRendererTest, RendererTimeout) {
  scoped_refptr<base::TestMockTimeTaskRunner> task_runner =
      new base::TestMockTimeTaskRunner();
  SpareRenderProcessHostManager& manager =
      SpareRenderProcessHostManager::GetInstance();
  manager.SetDeferTimerTaskRunnerForTesting(task_runner);
  const base::TimeDelta kTimeout = base::Seconds(10);

  SpareRenderProcessHostManager::GetInstance().CleanupSpareRenderProcessHost();
  SpareRenderProcessObserver render_process_observer;
  ASSERT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL("a.com", "/title1.html")));
  render_process_observer.WaitForSpareRenderProcessCreation();
  RenderProcessHost* created_process =
      render_process_observer.spare_render_process_host();
  ASSERT_TRUE(!!created_process);
  ASSERT_EQ(manager.spare_render_process_host(), created_process);

  if (!SpareRendererHasTimeout()) {
    // Warming up a spare renderer with a timeout shall not override
    // a spare renderer without a timeout.
    manager.WarmupSpareRenderProcessHost(
        shell()->web_contents()->GetBrowserContext(), kTimeout);
  }
  task_runner->FastForwardBy(kTimeout);
  base::RunLoop().RunUntilIdle();
  if (SpareRendererHasTimeout()) {
    ASSERT_FALSE(!!manager.spare_render_process_host());
  } else {
    ASSERT_EQ(created_process, manager.spare_render_process_host());
  }
}
#endif

}  // namespace content