chromium/content/browser/renderer_host/render_frame_host_manager_browsertest.cc

// Copyright 2013 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/renderer_host/render_frame_host_manager_browsertest.h"

#include <stddef.h>
#include <stdint.h>

#include <functional>
#include <memory>
#include <set>

#include "base/cfi_buildflags.h"
#include "base/command_line.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/json/json_reader.h"
#include "base/location.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/lock.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/bind.h"
#include "base/thread_annotations.h"
#include "base/time/time.h"
#include "base/values.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/process_lock.h"
#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/browser/renderer_host/navigation_entry_restore_context_impl.h"
#include "content/browser/renderer_host/navigation_request.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_frame_proxy_host.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/site_info.h"
#include "content/browser/site_instance_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/browser/webui/web_ui_controller_factory_registry.h"
#include "content/browser/webui/web_ui_impl.h"
#include "content/common/content_constants_internal.h"
#include "content/common/content_navigation_policy.h"
#include "content/common/features.h"
#include "content/public/browser/browser_child_process_host.h"
#include "content/public/browser/child_process_launcher_utils.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/site_isolation_policy.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_ui_message_handler.h"
#include "content/public/common/bindings_policy.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/isolated_world_ids.h"
#include "content/public/common/url_constants.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.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/navigation_handle_observer.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_interceptor.h"
#include "content/shell/browser/shell.h"
#include "content/test/content_browser_test_utils_internal.h"
#include "content/test/render_document_feature.h"
#include "content/test/storage_partition_test_helpers.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/controllable_http_response.h"
#include "net/test/embedded_test_server/default_handlers.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/request_handler_util.h"
#include "net/test/url_request/url_request_failed_job.h"
#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "third_party/blink/public/common/chrome_debug_urls.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/web_preferences/web_preferences.h"

ASCIIToUTF16;

namespace content {

namespace {

// Helper function that return true in cases where the current process model
// will return the same SiteInstance for a cross-process navigation.
bool ExpectSameSiteInstance() {}

class TestWebUIMessageHandler : public WebUIMessageHandler {};

// This class implements waiting for RenderFrameHost destruction. It relies on
// the fact that RenderFrameDeleted event is fired when RenderFrameHost is
// destroyed.
// Note: RenderFrameDeleted is also fired when the process associated with the
// RenderFrameHost crashes, so this cannot be used in cases where process dying
// is expected.
class RenderFrameHostDestructionObserver : public WebContentsObserver {};

// A NavigationThrottle implementation that blocks all outgoing navigation
// requests for a specific WebContents. It is used to block navigations to
// WebUI URLs in tests.
class RequestBlockingNavigationThrottle : public NavigationThrottle {};

// Helper function for error page navigations that makes sure that the last
// committed origin on |node| is an opaque origin with a precursor that matches
// |url|'s origin.
// Returns true if the frame has an opaque origin with the expected precursor
// information. Otherwise returns false.
bool IsOriginOpaqueAndCompatibleWithURL(FrameTreeNode* node, const GURL& url) {}

bool IsMainFrameOriginOpaqueAndCompatibleWithURL(Shell* shell,
                                                 const GURL& url) {}

bool HasErrorPageSiteInfo(SiteInstance* site_instance) {}

bool HasErrorPageProcessLock(SiteInstance* site_instance) {}

}  // anonymous namespace

RenderFrameHostManagerTest::RenderFrameHostManagerTest() :{}

RenderFrameHostManagerTest::~RenderFrameHostManagerTest() = default;

void RenderFrameHostManagerTest::SetUpOnMainThread() {}

void RenderFrameHostManagerTest::DisableBackForwardCache(
    BackForwardCacheImpl::DisableForTestingReason reason) const {}

void RenderFrameHostManagerTest::StartServer() {}

void RenderFrameHostManagerTest::StartEmbeddedServer() {}

std::unique_ptr<content::URLLoaderInterceptor>
RenderFrameHostManagerTest::SetupRequestFailForURL(const GURL& url) {}

// Returns a URL on foo.com with the given path.
GURL RenderFrameHostManagerTest::GetCrossSiteURL(const std::string& path) {}

void RenderFrameHostManagerTest::NavigateToPageWithLinks(Shell* shell) {}

// Web pages should not have script access to the unloaded page.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest, NoScriptAccessAfterUnload) {}

// Test for crbug.com/24447.  Following a cross-site link with rel=noreferrer
// and target=_blank should create a new SiteInstance.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       SwapProcessWithRelNoreferrerAndTargetBlank) {}

// Same as above, but for 'noopener'
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       SwapProcessWithRelNoopenerAndTargetBlank) {}

// 'noopener' also works from 'window.open'
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       SwapProcessWithWindowOpenAndNoopener) {}

// As of crbug.com/69267, we create a new BrowsingInstance (and SiteInstance)
// for rel=noreferrer links in new windows, even to same site pages and named
// targets.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       SwapProcessWithSameSiteRelNoreferrer) {}

// Same as above, but for 'noopener'
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       SwapProcessWithSameSiteRelNoopener) {}

// Test for crbug.com/24447.  Following a cross-site link with just
// target=_blank should not create a new SiteInstance, unless we
// are running in --site-per-process mode.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       DontSwapProcessWithOnlyTargetBlank) {}

// Test for crbug.com/24447.  Following a cross-site link with rel=noreferrer
// and no target=_blank should not create a new SiteInstance.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       DontSwapProcessWithOnlyRelNoreferrer) {}

// Same as above, but for 'noopener'
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       DontSwapProcessWithOnlyRelNoOpener) {}

// Test for crbug.com/116192.  Targeted links should still work after the
// named target window has swapped processes.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       AllowTargetedNavigationsAfterSwap) {}

// Test that setting the opener to null in a window affects cross-process
// navigations, including those to existing entries.  http://crbug.com/156669.
// This test crashes under ThreadSanitizer, http://crbug.com/356758.
#if defined(THREAD_SANITIZER)
#define MAYBE_DisownOpener
#else
#define MAYBE_DisownOpener
#endif
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest, MAYBE_DisownOpener) {}

// Test that subframes can disown their openers.  http://crbug.com/225528.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest, DisownSubframeOpener) {}

// Check that window.name is preserved for top frames when they navigate
// cross-process.  See https://crbug.com/504164.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       PreserveTopFrameWindowNameOnCrossProcessNavigations) {}

// Test for crbug.com/99202.  PostMessage calls should still work after
// navigating the source and target windows to different sites.
// Specifically:
// 1) Create 3 windows (opener, "foo", and _blank) and send "foo" cross-process.
// 2) Fail to post a message from "foo" to opener with the wrong target origin.
// 3) Post a message from "foo" to opener, which replies back to "foo".
// 4) Post a message from _blank to "foo".
// 5) Post a message from "foo" to a subframe of opener, which replies back.
// 6) Post a message from _blank to a subframe of "foo".
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       SupportCrossProcessPostMessage) {}

// Test for crbug.com/278336. MessagePorts should work cross-process. Messages
// which contain Transferables that need to be forwarded between processes via
// RenderFrameProxy::willCheckAndDispatchMessageEvent should work.
// Specifically:
// 1) Create 2 windows (opener and "foo") and send "foo" cross-process.
// 2) Post a message containing a message port from opener to "foo".
// 3) Post a message from "foo" back to opener via the passed message port.
// The test will be enabled when the feature implementation lands.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       SupportCrossProcessPostMessageWithMessagePort) {}

// Test for crbug.com/116192.  Navigations to a window's opener should
// still work after a process swap.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       AllowTargetedNavigationsInOpenerAfterSwap) {}

// Test that subframes do not crash when sending a postMessage to the top frame
// from an unload handler while the top frame is being replaced as part of
// navigating cross-process.  https://crbug.com/475651.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       PostMessageFromSubframeUnloadHandler) {}

// Test that opening a new window in the same SiteInstance and then navigating
// both windows to a different SiteInstance allows the first process to exit.
// See http://crbug.com/126333.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       ProcessExitWithSwappedOutViews) {}

// Test for crbug.com/76666.  A cross-site navigation that fails with a 204
// error should not make us ignore future renderer-initiated navigations.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest, ClickLinkAfter204Error) {}

// A collection of tests to prevent URL spoofs when showing pending URLs above
// initial empty documents, ensuring that the URL reverts to about:blank if the
// document is accessed. See https://crbug.com/9682.
class RenderFrameHostManagerSpoofingTest : public RenderFrameHostManagerTest {};

// Helper to wait until a WebContent's NavigationController has a visible entry
// that is not the initial NavigationEntry.
class VisibleEntryWaiter : public WebContentsObserver {};

// Sanity test that a newly opened window shows the pending URL if the initial
// empty document is not modified. This is intentionally structured as similarly
// as possible to the subsequent ShowLoadingURLUntil*Spoof tests: it performs
// the same operations as the subsequent tests except DOM modification. This
// should help catch instances where the subsequent tests incorrectly pass due
// to a side effect of the test infrastructure.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerSpoofingTest,
                       ShowLoadingURLIfNotModified) {}

// Test for crbug.com/9682.  We should show the URL for a pending renderer-
// initiated navigation in a new tab, until the content of the initial
// about:blank page is modified by another window.  At that point, we should
// revert to showing about:blank to prevent a URL spoof.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerSpoofingTest,
                       ShowLoadingURLUntilSpoof) {}

// Same as ShowLoadingURLUntilSpoof, but reloads the new popup before modifying
// it, to test https://crbug.com/847718.  The reload should not cause the
// visible entry to stick around after the modification, even though it is
// triggered in the browser process.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerSpoofingTest,
                       ShowLoadingURLUntilSpoofAfterReload) {}

// Similar but using document.open(): once a Document is opened, subsequent
// document.write() calls can insert arbitrary content into the target Document.
// Since this could result in URL spoofing, the pending URL should no longer be
// shown in the omnibox.
//
// Note: document.write() implicitly invokes document.open() if the Document has
// not already been opened, so there's no need to test document.write()
// separately.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerSpoofingTest,
                       ShowLoadingURLUntilDocumentOpenSpoof) {}

IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       WasDiscardedWhenNavigationInterruptsReload) {}

// Ensures that a pending navigation's URL  is no longer visible after the
// speculative RFH is discarded due to a concurrent renderer-initiated
// navigation.  See https://crbug.com/760342.
// TODO(crbug.com/41448629): Disabled due to flaky timeouts.
IN_PROC_BROWSER_TEST_P(
    RenderFrameHostManagerTest,
    DISABLED_ResetVisibleURLOnCrossProcessNavigationInterrupted) {}

// Ensures that deleting a speculative RenderFrameHost trying to commit a
// navigation to the pending NavigationEntry will not crash if it happens
// because a new navigation to the same pending NavigationEntry started. This is
// a regression test for crbug.com/796135.
IN_PROC_BROWSER_TEST_P(
    RenderFrameHostManagerTest,
    DeleteSpeculativeRFHPendingCommitOfPendingEntryOnInterrupted1) {}

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \
    BUILDFLAG(IS_MAC)
#define MAYBE_DeleteSpeculativeRFHPendingCommitOfPendingEntryOnInterrupted2
#else
#define MAYBE_DeleteSpeculativeRFHPendingCommitOfPendingEntryOnInterrupted2
#endif
// Ensures that deleting a speculative RenderFrameHost trying to commit a
// navigation to the pending NavigationEntry will not crash if it happens
// because a new navigation to the same pending NavigationEntry started.  This
// is a variant of the previous test, where we destroy the speculative
// RenderFrameHost to create another speculative RenderFrameHost. This is a
// regression test for crbug.com/796135.
IN_PROC_BROWSER_TEST_P(
    RenderFrameHostManagerTest,
    MAYBE_DeleteSpeculativeRFHPendingCommitOfPendingEntryOnInterrupted2) {}

// Test for crbug.com/9682.  We should not show the URL for a pending renderer-
// initiated navigation in a new tab if it is not the initial navigation.  In
// this case, the renderer will not notify us of a modification, so we cannot
// show the pending URL without allowing a spoof.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       DontShowLoadingURLIfNotInitialNav) {}

// Crashes under ThreadSanitizer, http://crbug.com/356758.
#if defined(THREAD_SANITIZER)
#define MAYBE_BackForwardNotStale
#else
#define MAYBE_BackForwardNotStale
#endif
// Test for http://crbug.com/93427.  Ensure that cross-site navigations
// do not cause back/forward navigations to be considered stale by the
// renderer.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest, MAYBE_BackForwardNotStale) {}

// This class ensures that all the given RenderViewHosts have properly been
// shutdown.
class RenderViewHostDestructionObserver : public WebContentsObserver {};

// Crashes under ThreadSanitizer, http://crbug.com/356758.
#if defined(THREAD_SANITIZER)
#define MAYBE_LeakingRenderViewHosts
#else
#define MAYBE_LeakingRenderViewHosts
#endif
// Test for crbug.com/90867. Make sure we don't leak render view hosts since
// they may cause crashes or memory corruptions when trying to call dead
// delegate_. This test also verifies crbug.com/117420 and crbug.com/143255 to
// ensure that a separate SiteInstance is created when navigating to view-source
// URLs, regardless of current URL.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       MAYBE_LeakingRenderViewHosts) {}

// Test for crbug.com/143155.  Frame tree updates during unload should not
// interrupt the intended navigation.
// Specifically:
// 1) Open 2 tabs in an HTTP SiteInstance, with a subframe in the opener.
// 2) Send the second tab to a different foo.com SiteInstance.
//    This created an opener proxy for the first tab in the foo process.
// 3) Navigate the first tab to the foo.com SiteInstance, and have the first
//    tab's unload handler remove its frame.
// In older versions of Chrome, this caused an update to the frame tree that
// resulted in showing an internal page rather than the real page.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       DontPreemptNavigationWithFrameTreeUpdate) {}

// Ensure that renderer-side debug URLs do not cause a process swap, since they
// are meant to run in the current page.  We had a bug where we expected a
// BrowsingInstance swap to occur on pages like view-source and extensions,
// which broke chrome://crash and javascript: URLs.
// See http://crbug.com/335503.
// The test fails on Mac OSX with ASAN.
// See http://crbug.com/699062.
#if BUILDFLAG(IS_MAC) && defined(THREAD_SANITIZER)
#define MAYBE_RendererDebugURLsDontSwap
#else
#define MAYBE_RendererDebugURLsDontSwap
#endif
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       MAYBE_RendererDebugURLsDontSwap) {}

// Ensure that renderer-side debug URLs don't take effect on crashed renderers.
// Otherwise, we might try to load an unprivileged about:blank page into a
// WebUI-enabled RenderProcessHost, failing a safety check in InitRenderView.
// See http://crbug.com/334214.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       IgnoreRendererDebugURLsWhenCrashed) {}

class RFHMProcessPerTabTest : public RenderFrameHostManagerTest {};

// Test that we still swap processes for BrowsingInstance changes even in
// --process-per-tab mode.  See http://crbug.com/343017.
// Disabled on Android: http://crbug.com/345873.
// Crashes under ThreadSanitizer, http://crbug.com/356758.
#if BUILDFLAG(IS_ANDROID) || defined(THREAD_SANITIZER)
#define MAYBE_BackFromWebUI
#else
#define MAYBE_BackFromWebUI
#endif
IN_PROC_BROWSER_TEST_P(RFHMProcessPerTabTest, MAYBE_BackFromWebUI) {}

// crbug.com/424526
// The test loads a WebUI page in process-per-tab mode, then navigates to a
// blank page and then to a regular page. The bug reproduces if blank page is
// visited in between WebUI and regular page.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       ForceSwapAfterWebUIBindings) {}

// crbug.com/615274
// This test ensures that after an RFH is unloaded, the associated WebUI
// instance is no longer allowed to send JavaScript messages. This is necessary
// because WebUI currently (and unusually) always sends JavaScript messages to
// the current main frame, rather than the RFH that owns the WebUI.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       WebUIJavascriptDisallowedAfterUnload) {}

// Test for http://crbug.com/703303.  Ensures that the renderer process does not
// try to select files whose paths cannot be converted to WebStrings.  This
// check is done in the renderer because it is hard to predict which paths will
// turn into empty WebStrings, and the behavior varies by platform.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest, DontSelectInvalidFiles) {}

// Test for http://crbug.com/262948.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       RestoreFileAccessForHistoryNavigation) {}

// Same as RenderFrameHostManagerTest.RestoreFileAccessForHistoryNavigation, but
// replace the cross-origin navigation by a crash, followed by a reload.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       RestoreFileAccessForHistoryNavigationAfterCrash) {}

// Test for http://crbug.com/441966.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       RestoreSubframeFileAccessForHistoryNavigation) {}

// Ensures that no RenderFrameHost/RenderViewHost objects are leaked when
// doing a simple cross-process navigation.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       CleanupOnCrossProcessNavigation) {}

// Ensure that the opener chain proxies and RVHs are properly reinitialized if
// a tab crashes and reloads.  See https://crbug.com/505090.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       ReinitializeOpenerChainAfterCrashAndReload) {}

// Test that when a frame's opener is updated via window.open, the browser
// process and the frame's proxies in other processes find out about the new
// opener.  Open two popups in different processes, set one popup's opener to
// the other popup, and ensure that the opener is updated in all processes.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest, UpdateOpener) {}

// Tests that when a popup is opened, which is then navigated cross-process and
// back, it can be still accessed through the original window reference in
// JavaScript. See https://crbug.com/537657
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       PopupKeepsWindowReferenceCrossProcesAndBack) {}

// Tests that going back to the same SiteInstance as a pending RenderFrameHost
// doesn't create a duplicate RenderFrameProxyHost. For example:
// 1. Navigate to a page on the opener site - a.com
// 2. Navigate to a page on site b.com
// 3. Start a navigation to another page on a.com, but commit is delayed.
// 4. Go back.
// See https://crbug.com/541619.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       PopupPendingAndBackToSameSiteInstance) {}

// Tests that navigating cross-process and reusing an existing RenderViewHost
// (whose process has been killed/crashed) recreates properly the
// `blink::WebView` and `blink::RemoteFrame` on the renderer side. See
// https://crbug.com/544271
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       RenderViewInitAfterProcessKill) {}

// Ensure that we don't crash the renderer in CreateRenderView if a proxy goes
// away between unload and the next navigation.  See https://crbug.com/581912.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       CreateRenderViewAfterProcessKillAndClosedProxy) {}

// Ensure that we don't crash in RenderViewImpl::Init if a proxy is created
// after unload and before navigation.  See https://crbug.com/544755.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       RenderViewInitAfterNewProxyAndProcessKill) {}

// Ensure that we use the same pending RenderFrameHost if a second navigation to
// its site occurs before it commits.  Otherwise the renderer process will have
// two competing pending RenderFrames that both try to swap with the same
// RenderFrameProxy.  See https://crbug.com/545900.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       ConsecutiveNavigationsToSite) {}

// Check that if a sandboxed subframe opens a cross-process popup such that the
// popup's opener won't be set, the popup still inherits the subframe's sandbox
// flags.  This matters for rel=noopener and rel=noreferrer links, as well as
// for some situations in non-site-per-process mode where the popup would
// normally maintain the opener, but loses it due to being placed in a new
// process and not creating subframe proxies.  The latter might happen when
// opening the default search provider site.  See https://crbug.com/576204.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       CrossProcessPopupInheritsSandboxFlagsWithNoOpener) {}

// When two frames are same-origin but cross-process, they should behave as if
// they are not same-origin and should not crash.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       SameOriginFramesInDifferentProcesses) {}

// Test coverage for attempts to open subframe links in new windows, to prevent
// incorrect invariant checks.  See https://crbug.com/605055.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest, CtrlClickSubframeLink) {}

// Ensure that we don't update the wrong NavigationEntry's title after an
// ignored commit during a cross-process navigation.
// See https://crbug.com/577449.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       UnloadPushStateOnCrossProcessNavigation) {}

// Ensure that document hosted on file: URL can successfully execute pushState
// with arbitrary origin, when universal access setting is enabled.
// TODO(nasko): The test is disabled on Mac, since universal access from file
// scheme behaves differently.  See also https://crbug.com/981018.
#if BUILDFLAG(IS_MAC)
#define MAYBE_EnsureUniversalAccessFromFileSchemeSucceeds
#else
#define MAYBE_EnsureUniversalAccessFromFileSchemeSucceeds
#endif
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       MAYBE_EnsureUniversalAccessFromFileSchemeSucceeds) {}

// Ensure that navigating back from a sad tab to an existing process works
// correctly. See https://crbug.com/591984.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       NavigateBackToExistingProcessFromSadTab) {}

// Verify that GetLastCommittedOrigin() is correct for the full lifetime of a
// RenderFrameHost, including when it's pending, current, and pending deletion.
// This is checked both for main frames and subframes.
// See https://crbug.com/590035.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest, LastCommittedOrigin) {}

// Ensure that loading a page with cross-site coreferencing iframes does not
// cause an infinite number of nested iframes to be created.
// See https://crbug.com/650332.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest, CoReferencingFrames) {}

// Ensures that nested subframes with the same URL but different fragments can
// only be nested once.  See https://crbug.com/650332.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       SelfReferencingFragmentFrames) {}

// Ensure that loading a page with a meta refresh iframe does not cause an
// infinite number of nested iframes to be created.  This test loads a page with
// an about:blank iframe where the page injects html containing a meta refresh
// into the iframe.  This test then checks that this does not cause infinite
// nested iframes to be created.  See https://crbug.com/527367.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       SelfReferencingMetaRefreshFrames) {}

// Ensure that navigating a subframe to the same URL as its parent twice in a
// row is not blocked by the self-reference check.
// See https://crbug.com/650332.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       SelfReferencingSameURLRenavigation) {}

// Ensures that POST requests bypass self-referential URL checks. See
// https://crbug.com/710008.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       SelfReferencingFramesWithPOST) {}

// Ensures that we don't reset a speculative RFH if a JavaScript URL is loaded
// while there's an ongoing cross-process navigation. See
// https://crbug.com/793432.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       JavaScriptLoadDoesntResetSpeculativeRFH) {}

// Test that unrelated browsing contexts cannot find each other's windows,
// even when they end up using the same renderer process (e.g. because of
// hitting a process limit).  See also https://crbug.com/718489.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       ProcessReuseVsBrowsingInstance) {}

// Verify that cross-site main frame navigations will swap BrowsingInstances
// for certain browser-initiated navigations, such as user typing the URL into
// the address bar.  This helps avoid unneeded process sharing and should
// happen even if the current frame has an opener.  See
// https://crbug.com/803367.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       BrowserInitiatedNavigationsSwapBrowsingInstance) {}

// Verifies that a renderer-initiated navigation from a site in the default
// StoragePartition to one that ContentBrowserClient places in a non-default
// StoragePartition will swap to a new BrowsingInstance.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       NavigationToDifferentPartitionSwapsBrowsingInstance) {}

// Verifies that iframes inherit their StoragePartition, even if
// ContentBrowserClient would normally place the iframe's URL in a dedicated
// StoragePartition.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       SubframeInheritsStoragePartition) {}

// Ensure that these two browser-initiated navigations:
//   foo.com -> about:blank -> foo.com
// stay in the same SiteInstance.  This isn't technically required for
// correctness, but some tests (e.g., testEnsureHotFromScratch from
// telemetry_unittests) currently depend on this behavior.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       NavigateToAndFromAboutBlank) {}

// Check that with the following sequence of navigations:
//   foo.com -(1)-> bar.com -(2)-> about:blank -(3)-> foo.com
// where (1) is renderer-initiated and (2)+(3) are browser-initiated, the last
// navigation goes back to the first SiteInstance without --site-per-process,
// and to a new SiteInstance and BrowsingInstance with --site-per-process.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       NavigateToFooThenBarThenAboutBlankThenFoo) {}

// Test to verify that navigations in the main frame, which result in an error
// page, properly commit the error page in its own dedicated process.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       ErrorPageNavigationInMainFrame) {}

// Test to verify that navigations in subframes, which result in an error
// page, commit the error page in the same process and not in the dedicated
// error page process.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       ErrorPageNavigationInChildFrame) {}

// Test to verify that navigations in new window, which result in an error
// page, commit the error page in the dedicated error page process and not in
// the one for the destination site.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       ErrorPageNavigationInNewWindow) {}

// Test to verify that windows that are not part of the same
// BrowsingInstance end up using the same error page process, even though
// their SiteInstances are not related.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       ErrorPageNavigationInUnrelatedWindows) {}

// Test to verify that reloading an error page once the error condition has
// cleared up is successful and does not create a new navigation entry.
// See https://crbug.com/840485.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest, ErrorPageNavigationReload) {}

// Version of ErrorPageNavigationReload test that targets a subframe (because
// subframes are currently [~2019Q1] not subject to error page isolation).
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       ErrorPageNavigationReload_InSubframe_NetworkError) {}

// Version of ErrorPageNavigationReload test that targets a subframe (because
// subframes are currently [~2019Q1] not subject to error page isolation).
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       ErrorPageNavigationReload_InSubframe_BlockedByClient) {}

// Make sure that reload works properly if it redirects to a different site than
// the initial navigation.  The initial purpose of this test was to make sure
// the corresponding unit test matches the actual product code behavior
// (e.g. see NavigationControllerTest.Reload_GeneratesNewPage).
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       ReloadRedirectsToDifferentCrossSitePage) {}

// Test to verify that navigating away from an error page results in correct
// change in SiteInstance.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       ErrorPageNavigationAfterError) {}

// Test to verify that when an error page is hit and its process is terminated,
// a successful reload correctly commits in a different process.
// See https://crbug.com/866549.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       ErrorPageNavigationReloadWithTerminatedProcess) {}

// Test to verify that navigation to existing history entry, which results in
// an error page, is correctly placed in the error page SiteInstance.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       ErrorPageNavigationHistoryNavigationFailure) {}

// Test to verify that a successful navigation to existing history entry,
// which initially resulted in an error page, is correctly placed in a
// SiteInstance different than the error page one.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       ErrorPageNavigationHistoryNavigationSuccess) {}

// Test to verify that navigations to WebUI URL which results in an error
// commits properly in the error page process and does not give it WebUI
// bindings.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       ErrorPageNavigationToWebUIResourceWithError) {}

// If a WebUI page leads to an error page and is then reloaded successfully from
// its NavigationEntry, ensure that WebUI bindings are granted and that we don't
// crash. See https://crbug.com/1046159.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       ReloadWebUIErrorPageToValidWebUI) {}
// A custom ContentBrowserClient that simulates GetEffectiveURL() translation
// for all URLs that are in the same page (including URL with refs).
class PageEffectiveURLContentBrowserClient
    : public ContentBrowserTestContentBrowserClient {};

// Ensure that same-document navigations for URLs with effective URLs don't
// incorrectly swap BrowsingInstance. See crbug.com/1073540.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       NavigationToSameDocumentWithEffectiveURL) {}

// A test ContentBrowserClient implementation which enforces
// BrowsingInstance swap on every navigation. It is used to verify that
// reloading of an error page to an URL that requires BrowsingInstance swap
// works correctly.
class BrowsingInstanceSwapContentBrowserClient
    : public ContentBrowserTestContentBrowserClient {};

// Test to verify that reloading of an error page which resulted from a
// navigation to an URL which requires a BrowsingInstance swap, correcly
// reloads in the same SiteInstance for the error page.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       ErrorPageNavigationReloadBrowsingInstanceSwap) {}

// Helper class to simplify testing of unload handlers.  It allows waiting for
// particular HTTP requests to be made to the embedded_test_server(); the tests
// use this to wait for termination pings (e.g., navigator.sendBeacon()) made
// from unload handlers.
class RenderFrameHostManagerUnloadBrowserTest
    : public RenderFrameHostManagerTest {};

// Ensure that after a main frame with a cross-site iframe is itself navigated
// cross-site, the unload event handlers (for unload, pagehide, or
// visibilitychange events) in the iframe can use navigator.sendBeacon() to do a
// termination ping.  See https://crbug.com/852204, where this was broken with
// site isolation if the iframe was in its own process.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerUnloadBrowserTest,
                       SubframeTerminationPing_SendBeacon) {}

// Ensure that after a main frame with a cross-site iframe is itself navigated
// cross-site, the pagehide handler in the iframe can use an image load to do a
// termination ping. See https://crbug.com/852204, where this was broken with
// site isolation if the iframe was in its own process.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerUnloadBrowserTest,
                       SubframeTerminationPing_Image) {}

// Ensure that when closing a window containing a page with a cross-site
// iframe, the iframe still runs its pagehide handler and can do a sendBeacon
// termination ping.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerUnloadBrowserTest,
                       SubframeTerminationPingWhenWindowCloses) {}

// Ensure that after a main frame with a cross-site iframe is navigated
// cross-site, and the iframe had a pagehide handler which never finishes,
// the iframe's process eventually exits.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerUnloadBrowserTest,
                       SubframeProcessGoesAwayAfterUnloadTimeout) {}

// Verify that when an OOPIF with a pagehide handler navigates cross-process,
// its pagehide handler is able to send a postMessage to the parent frame.
// See https://crbug.com/857274.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerUnloadBrowserTest,
                       PostMessageToParentWhenSubframeNavigates) {}

// Ensure that when a pending delete RenderFrameHost's process dies, the
// current RenderFrameHost does not lose its child frames.  See
// https://crbug.com/867274.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerUnloadBrowserTest,
                       PendingDeleteRFHProcessShutdownDoesNotRemoveSubframes) {}

// RenderFrameHost should have correct sudden termination disabler
// state after the event listeners are registered and removed.
// Regression test for crbug.com/1341417.
IN_PROC_BROWSER_TEST_P(
    RenderFrameHostManagerUnloadBrowserTest,
    AddAndRemoveEventListenersAffectingSuddenTerminationDisablerState) {}

namespace {

// A helper to post a recurring check that a renderer process is foregrounded.
// The recurring check uses WeakPtr semantic and will die when this class goes
// out of scope.
class AssertForegroundHelper {};

}  // namespace

// This is a regression test for https://crbug.com/560446. It ensures the
// newly launched process for cross-process navigation in the foreground
// WebContents isn't backgrounded prior to the navigation committing and a
// "visible" widget being added to the process. This test discards the spare
// RenderProcessHost if present, to ensure that it is not used in the
// cross-process navigation.
// TODO(crbug.com/40760155): Flaky on Mac.
#if BUILDFLAG(IS_APPLE)
#define MAYBE_ForegroundNavigationIsNeverBackgroundedWithoutSpareProcess
#else
#define MAYBE_ForegroundNavigationIsNeverBackgroundedWithoutSpareProcess
#endif
IN_PROC_BROWSER_TEST_P(
    RenderFrameHostManagerTest,
    MAYBE_ForegroundNavigationIsNeverBackgroundedWithoutSpareProcess) {}

// Similar to the test above, but verifies the spare RenderProcessHost uses the
// right priority.
IN_PROC_BROWSER_TEST_P(
    RenderFrameHostManagerTest,
    ForegroundNavigationIsNeverBackgroundedWithSpareProcess) {}

// When ProactivelySwapBrowsingInstance is enabled, the browser switch to a new
// BrowsingInstance on cross-site HTTP(S) main frame navigations, when there are
// no other windows in the BrowsingInstance.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       ProactivelySwapBrowsingInstance) {}

// Tests specific to the "default process" mode (which creates strict
// SiteInstances that can share a default process per BrowsingInstance).
class RenderFrameHostManagerDefaultProcessTest
    : public RenderFrameHostManagerTest {};

// Ensure that the default process can be used for URLs that don't assign a site
// to the SiteInstance, when Site Isolation is not enabled.
// 1. Visit foo.com.
// 2. Start to navigate to a siteless URL.
// 3. When the commit is pending, start a navigation to bar.com in a popup.
// (Using a popup avoids a crash when replacting the speculative RFH, per
// https://crbug.com/838348.)
// All navigations should use the default process, and we should not crash.
// See https://crbug.com/977956.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerDefaultProcessTest,
                       NavigationRacesWithSitelessCommitInDefaultProcess) {}

// 1. Navigate to A1(B2, B3(B4), C5)
// 2. Crash process B
// 3. Reload B2, creating RFH B6.
//
// Along the way, check the RenderFrameProxies.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       CrashFrameReloadAndCheckProxy) {}

// With just the right initial navigations using RendererDebugURLs, creating a
// new RenderFrameHost can fail. https://crbug.com/1006814
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       NavigateFromRevivedRendererDebugURL) {}

// Helper class to run tests without site isolation.
class RenderFrameHostManagerNoSiteIsolationTest
    : public RenderFrameHostManagerTest {};

// Ensure that when a process that allows any site gets reused by new
// BrowsingInstances, ChildProcessSecurityPolicy gets notified about those new
// BrowsingInstances.  Failure to do so will lead to a crash at commit time due
// to mismatched process locks.  See https://crbug.com/1141877.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerNoSiteIsolationTest,
                       IncludeIsolationContextInProcessThatAllowsAnySite) {}

// With RenderDocument for subframes, removing a frame while it is executing
// its own unload handler caused a crash. https://crbug.com/1148793
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       RemoveSubframeInPageHide_SameSite) {}

// See RemoveSubframeInUnload_SameSite
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       RemoveSubframeInPageHide_CrossSite) {}

// This test demonstrates a similar issue to the previous two tests, but
// triggers it in a slightly different way. The previous two tests navigate a
// subframe and rely on some variant of RenderDocument being enabled to trigger
// the crash. If the navigation commits in a new RenderFrameHostImpl, the
// renderer does not correctly handle the case where running the unload handler
// while swapping in the new frame detaches the navigated frame.
//
// However, this bug actually precedes RenderDocument, as detaching a document
// for navigation at swap time must also detach the subtree. Given a frame tree
// A1(B(A2)) and a navigation from B->A3, committing A3 will unload B. However,
// unloading B will also detach A2, and A2's unload handler can detach B since
// it can script A1 and remove the frame owner element synchronously.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerUnloadBrowserTest, NestedUnload) {}

// See RemoveSubframeInPageHide_SameSite
void RenderFrameHostManagerTest::AssertCanRemoveSubframeInPageHide(
    bool same_site) {}

// From https://crbug.com/1169844. Verify that crashing a cross-site subframe
// and navigating it to a new site does not cause the browser to crash.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerTest,
                       NavigateCrossSiteSubframeAfterCrash) {}

// From https://crbug.com/1503038.
// The RuntimeFeatureStateDocumentData should be re-created when the main frame
// recovers from a crash.
IN_PROC_BROWSER_TEST_P(
    RenderFrameHostManagerTest,
    RuntimeFeatureStateDocumentDataShouldBeRecreatedAfterCrash) {}

// Tests that enable clearing window.name on cross-site
// cross-BrowsingInstance navigations.
class RenderFrameHostManagerClearWindowNameTest
    : public RenderFrameHostManagerTest {};

// Verify that cross-site main frame navigation that swaps BrowsingInstances
// clears window.name.
IN_PROC_BROWSER_TEST_P(RenderFrameHostManagerClearWindowNameTest,
                       ClearWindowNameCrossSite) {}

INSTANTIATE_TEST_SUITE_P();
INSTANTIATE_TEST_SUITE_P();
INSTANTIATE_TEST_SUITE_P();
INSTANTIATE_TEST_SUITE_P();
INSTANTIATE_TEST_SUITE_P();
INSTANTIATE_TEST_SUITE_P();
INSTANTIATE_TEST_SUITE_P();
}  // namespace content