// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/command_line.h" #include "base/feature_list.h" #include "base/memory/raw_ptr.h" #include "base/run_loop.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/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/test/test_timeouts.h" #include "build/build_config.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/devtools/protocol/devtools_protocol_test_support.h" #include "chrome/browser/extensions/chrome_test_extension_loader.h" #include "chrome/browser/login_detection/login_detection_util.h" #include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h" #include "chrome/browser/tab_contents/navigation_metrics_recorder.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/location_bar/location_bar.h" #include "chrome/browser/ui/sad_tab_helper.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/toolbar/back_forward_menu_model.h" #include "chrome/common/chrome_features.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "components/network_session_configurator/common/network_switches.h" #include "components/omnibox/browser/omnibox_view.h" #include "components/prefs/pref_service.h" #include "components/site_isolation/features.h" #include "components/site_isolation/pref_names.h" #include "components/ukm/test_ukm_recorder.h" #include "components/url_formatter/url_formatter.h" #include "components/variations/active_field_trials.h" #include "components/variations/hashing.h" #include "content/common/content_navigation_policy.h" #include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/context_menu_params.h" #include "content/public/browser/download_manager_delegate.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/reload_type.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/site_isolation_policy.h" #include "content/public/browser/storage_partition.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" #include "content/public/common/url_constants.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/download_test_observer.h" #include "content/public/test/navigation_handle_observer.h" #include "content/public/test/test_navigation_observer.h" #include "content/public/test/url_loader_interceptor.h" #include "extensions/test/extension_test_message_listener.h" #include "extensions/test/test_extension_dir.h" #include "google_apis/gaia/gaia_switches.h" #include "net/dns/mock_host_resolver.h" #include "pdf/buildflags.h" #include "services/metrics/public/cpp/ukm_builders.h" #include "services/network/public/cpp/features.h" #include "services/network/public/cpp/network_switches.h" #include "testing/gmock/include/gmock/gmock.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/page_state/page_state.h" #include "third_party/blink/public/mojom/context_menu/context_menu.mojom.h" #include "third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom-shared.h" IsEmpty; UnorderedElementsAre; class ChromeNavigationBrowserTest : public InProcessBrowserTest { … }; // Tests that viewing frame source on a local file:// page with an iframe // with a remote URL shows the correct tab title. IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, TestViewFrameSource) { … } // Base class for ctrl+click tests, which contains all the common functionality // independent from which process the navigation happens in. Each subclass // defines its own expectations depending on the conditions of the test. class CtrlClickProcessTest : public ChromeNavigationBrowserTest { … }; // Tests that verify that ctrl-click results 1) open up in a new renderer // process (https://crbug.com/23815) and 2) are in a new BrowsingInstance (e.g. // cannot find the opener's window by name - https://crbug.com/658386). class CtrlClickShouldEndUpInNewProcessTest : public CtrlClickProcessTest { … }; IN_PROC_BROWSER_TEST_F(CtrlClickShouldEndUpInNewProcessTest, NoTarget) { … } IN_PROC_BROWSER_TEST_F(CtrlClickShouldEndUpInNewProcessTest, BlankTarget) { … } IN_PROC_BROWSER_TEST_F(CtrlClickShouldEndUpInNewProcessTest, SubframeTarget) { … } // Similar to the tests above, but verifies that the new WebContents ends up in // the same process as the opener when it is exceeding the process limit. // See https://crbug.com/774723. class CtrlClickShouldEndUpInSameProcessTest : public CtrlClickProcessTest { … }; IN_PROC_BROWSER_TEST_F(CtrlClickShouldEndUpInSameProcessTest, NoTarget) { … } IN_PROC_BROWSER_TEST_F(CtrlClickShouldEndUpInSameProcessTest, BlankTarget) { … } IN_PROC_BROWSER_TEST_F(CtrlClickShouldEndUpInSameProcessTest, SubframeTarget) { … } // Test to verify that spoofing a URL via a redirect from a slightly malformed // URL doesn't work. See also https://crbug.com/657720. IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, ContextMenuNavigationToInvalidUrl) { … } // Ensure that URL transformations do not let a webpage populate the Omnibox // with a javascript: URL. See https://crbug.com/850824 and // https://crbug.com/1116280. IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, ClearInvalidPendingURLOnFail) { … } // A test performing two simultaneous navigations, to ensure code in chrome/, // such as tab helpers, can handle those cases. // This test starts a browser-initiated cross-process navigation, which is // delayed. At the same time, the renderer does a synchronous navigation // through pushState, which will create a separate navigation and associated // NavigationHandle. Afterwards, the original cross-process navigation is // resumed and confirmed to properly commit. IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, SlowCrossProcessNavigationWithPushState) { … } // Check that if a page has an iframe that loads an error page, that error page // does not inherit the Content Security Policy from the parent frame. See // https://crbug.com/703801. This test is in chrome/ because error page // behavior is only fully defined in chrome/. IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, ErrorPageDoesNotInheritCSP) { … } // Test that web pages can't navigate to an error page URL, either directly or // via a redirect, and that web pages can't embed error pages in iframes. IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, NavigationToErrorURLIsDisallowed) { … } // This test ensures that navigating to a page that returns an error code and // an empty document still shows Chrome's helpful error page instead of the // empty document. IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, EmptyDocumentWithErrorCode) { … } // Test for https://crbug.com/866549#c2. It verifies that about:blank does not // commit in the error page process when it is redirected to. IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, RedirectErrorPageReloadToAboutBlank) { … } // This test covers a navigation that: // 1. is initiated by a cross-site initiator, // 2. gets redirected via webRequest API to about:blank. // This is a regression test for https://crbug.com/1026738. IN_PROC_BROWSER_TEST_F( ChromeNavigationBrowserTest, NavigationInitiatedByCrossSiteSubframeRedirectedToAboutBlank) { … } // This test covers a navigation that: // 1. is initiated by a cross-site initiator, // 2. gets redirected via webRequest API to a data: URL // This covers a scenario similar to the one that led to crashes in // https://crbug.com/1026738. IN_PROC_BROWSER_TEST_F( ChromeNavigationBrowserTest, NavigationInitiatedByCrossSiteSubframeRedirectedToDataUrl) { … } // This test covers a navigation that: // 1. is initiated by a cross-site initiator, // 2. is a history navigation, // 3. gets redirected via webRequest API to a data: URL, but the original // navigation (that created the history entry) didn't get redirected. // This covers a scenario similar to the one that led to crashes in // https://crbug.com/40065692. IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, HistoryNavigationRedirectedToDataUrl) { … } // Same as above but the history navigation got redirected to about:blank // instead. // TODO(crbug.com/40266169): This is currently disabled because of // a bug where we will reuse the previous SiteInstance on the about:blank // navigation, even if the origins don't match, resulting in a CHECK failure // during the redirect on step 4. See also the TODO with the same bug number in // `SiteInstanceImpl::IsSameSite()`. IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, DISABLED_HistoryNavigationRedirectedToAboutBlank) { … } // Same as above but the history navigation is same-site with the previous page, // so the crash won't happen as the navigation is reusing the same SiteInstance. IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, HistoryNavigationRedirectedToAboutBlank_SameSite) { … } // Tests scenario where a blank iframe inside a blank popup (a popup with only // the initial navigation entry) does a same document navigation. This test was // added as a regression test for crbug.com/1237874. The main purpose of this // test is to ensure that WebContentsObservers and Chrome features don't crash. IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, SameDocumentNavigationInIframeInBlankDocument) { … } // Test scenario where we attempt a synchronous renderer-initiated same-document // navigation inside a blank popup (a popup with only the initial navigation // entry). Regression test for crbug.com/1254238. The main purpose of this test // is to ensure that WebContentsObservers and Chrome features don't crash. IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, SameDocumentNavigationInBlankPopup) { … } class SignInIsolationBrowserTest : public ChromeNavigationBrowserTest { … }; // This test ensures that the sign-in origin requires a dedicated process. It // only ensures that the sign-in origin is added as an isolated origin at // chrome/ layer; IsolatedOriginTest provides the main test coverage of origins // whitelisted for process isolation. See https://crbug.com/739418. IN_PROC_BROWSER_TEST_F(SignInIsolationBrowserTest, NavigateToSignInPage) { … } class WebstoreIsolationBrowserTest : public ChromeNavigationBrowserTest { … }; // Tests that Chrome Web Store URL used by the hosted app in production // (chrome.google.com/webstore/) is isolated from the rest of google.com and // other chrome.google.com pages not in the /webstore/ path. See // https://crbug.com/939108. IN_PROC_BROWSER_TEST_F(WebstoreIsolationBrowserTest, WebstorePopupIsIsolated) { … } // Make sure that the new Chrome Web Store URL used in production // (chromewebstore.google.com) is isolated from the rest of the google.com // domain. IN_PROC_BROWSER_TEST_F(WebstoreIsolationBrowserTest, NewWebstorePopupIsIsolated) { … } class WebstoreOverrideIsolationBrowserTest : public WebstoreIsolationBrowserTest { … }; // Make sure that Chrome Web Store origins are isolated from the rest of their // site when overriding the URL from the command line. See // https://crbug.com/939108. IN_PROC_BROWSER_TEST_F(WebstoreOverrideIsolationBrowserTest, WebstorePopupIsIsolated) { … } // Check that it's possible to navigate to a chrome scheme URL from a crashed // tab. See https://crbug.com/764641. IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, ChromeSchemeNavFromSadTab) { … } // Check that a browser-initiated navigation to a cross-site URL that then // redirects to a pdf hosted on another site works. IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, CrossSiteRedirectionToPDF) { … } ChromeNavigationBrowserTestWithMobileEmulation; // Tests the behavior of navigating to a PDF when mobile emulation is enabled. IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTestWithMobileEmulation, NavigateToPDFWithMobileEmulation) { … } // Tests the behavior of cross origin redirection to a PDF with mobile emulation // is enabled. IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTestWithMobileEmulation, CrossSiteRedirectionToPDFWithMobileEmulation) { … } // Check that clicking on a link doesn't carry the transient user activation // from the original page to the navigated page (crbug.com/865243). IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, WindowOpenBlockedAfterClickNavigation) { … } IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, OpenerNavigation_DownloadPolicy_Disallowed) { … } // Opener navigations from a same-origin popup should be allowed. IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, OpenerNavigation_DownloadPolicy_Allowed) { … } // Test which verifies that a noopener link/window.open() properly focus the // newly opened tab. See https://crbug.com/912348. IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, NoopenerCorrectlyFocusesNewTab) { … } // Tests the ukm entry logged when the navigation entry is marked as skippable // on back/forward button on doing a renderer initiated navigation without ever // getting a user activation. IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, NoUserActivationSetSkipOnBackForward) { … } // Same as above except the navigation is cross-site. IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, NoUserActivationSetSkipOnBackForwardCrossSite) { … } // Ensure that starting a navigation out of a sad tab hides the sad tab right // away, without waiting for the navigation to commit and restores it again // after cancelling. void ChromeNavigationBrowserTest:: ExpectHideAndRestoreSadTabWhenNavigationCancels(bool cross_site) { … } // Ensure that starting a navigation out of a sad tab hides the sad tab right // away, without waiting for the navigation to commit and restores it again // after cancelling. IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, RestoreSadTabWhenNavigationCancels_CrossSite) { … } // Same-site version of above. IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, RestoreSadTabWhenNavigationCancels_SameSite) { … } // Ensure that completing a navigation from a sad tab will clear the sad tab. void ChromeNavigationBrowserTest::ExpectHideSadTabWhenNavigationCompletes( bool cross_site) { … } // Flaky, see https://crbug.com/1223052 and https://crbug.com/1236500. // Ensure that completing a navigation from a sad tab will clear the sad tab. IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, DISABLED_ClearSadTabWhenNavigationCompletes_CrossSite) { … } // Same-site version of above. IN_PROC_BROWSER_TEST_F(ChromeNavigationBrowserTest, ClearSadTabWhenNavigationCompletes_SameSite) { … } // TODO(csharrison): These tests should become tentative WPT, once the feature // is enabled by default. NavigationConsumingTest; // The fullscreen API is spec'd to require a user activation (aka user gesture), // so use that API to test if navigation consumes the activation. // https://fullscreen.spec.whatwg.org/#allowed-to-request-fullscreen // https://crbug.com/1283289 Flaky on ChromeOS. #if BUILDFLAG(IS_CHROMEOS) #define MAYBE_NavigationConsumesUserGesture_Fullscreen … #else #define MAYBE_NavigationConsumesUserGesture_Fullscreen … #endif IN_PROC_BROWSER_TEST_F(NavigationConsumingTest, MAYBE_NavigationConsumesUserGesture_Fullscreen) { … } // Similar to the fullscreen test above, but checks that popups are successfully // blocked if spawned after a navigation. IN_PROC_BROWSER_TEST_F(NavigationConsumingTest, NavigationConsumesUserGesture_Popups) { … } // Regression test for https://crbug.com/856779, where a navigation to a // top-level, same process frame in another tab fails to focus that tab. IN_PROC_BROWSER_TEST_F(NavigationConsumingTest, TargetNavigationFocus) { … } HistoryManipulationInterventionBrowserTest; // Tests that chrome::GoBack does nothing if all the previous entries are marked // as skippable and the back button is disabled. IN_PROC_BROWSER_TEST_F(HistoryManipulationInterventionBrowserTest, AllEntriesSkippableBackButtonDisabled) { … } // Tests that chrome::GoBack is successful if there is at least one entry not // marked as skippable and the back button should be enabled. IN_PROC_BROWSER_TEST_F(HistoryManipulationInterventionBrowserTest, AllEntriesNotSkippableBackButtonEnabled) { … } #if BUILDFLAG(ENABLE_PDF) // Tests that a main frame hosting pdf does not get skipped because of history // manipulation intervention if there was a user gesture. // TODO(crbug.com/333829580): Flaky. IN_PROC_BROWSER_TEST_F(HistoryManipulationInterventionBrowserTest, DISABLED_PDFDoNotSkipOnBackForwardDueToUserGesture) { … } // Tests that a main frame hosting pdf gets skipped because of history // manipulation intervention if there was no user gesture. // TODO(crbug.com/333829580): Flaky. IN_PROC_BROWSER_TEST_F(HistoryManipulationInterventionBrowserTest, DISABLED_PDFSkipOnBackForwardNoUserGesture) { … } #endif // BUILDFLAG(ENABLE_PDF) // This test class turns on the mode where sites where the user enters a // password are dynamically added to the list of sites requiring a dedicated // process. It also disables strict site isolation so that the effects of // password isolation can be observed. class SiteIsolationForPasswordSitesBrowserTest : public ChromeNavigationBrowserTest { … }; // Verifies that a site gets process-isolated after a password is typed on a // page from that site. IN_PROC_BROWSER_TEST_F(SiteIsolationForPasswordSitesBrowserTest, SiteIsIsolatedAfterEnteringPassword) { … } // Verifies that persistent isolated sites survive restarts. Part 1. IN_PROC_BROWSER_TEST_F(SiteIsolationForPasswordSitesBrowserTest, PRE_IsolatedSitesPersistAcrossRestarts) { … } // Verifies that process-isolated sites persist across restarts. Part 2. // This runs after Part 1 above and in the same profile. Part 1 has already // added "saved.com" as a persisted isolated origin, so this part verifies that // it requires a dedicated process after restart. IN_PROC_BROWSER_TEST_F(SiteIsolationForPasswordSitesBrowserTest, IsolatedSitesPersistAcrossRestarts) { … } // Verify that trying to isolate a site multiple times will only save it to // disk once. IN_PROC_BROWSER_TEST_F(SiteIsolationForPasswordSitesBrowserTest, IsolatedSiteIsSavedOnlyOnce) { … } // Check that Incognito doesn't inherit saved isolated origins from its // original profile, and that any isolated origins added in Incognito don't // affect the original profile. IN_PROC_BROWSER_TEST_F(SiteIsolationForPasswordSitesBrowserTest, IncognitoWithIsolatedSites) { … } // Verify that serving a Clear-Site-Data header does not clear saved isolated // sites. Saved isolated sites should only be cleared by user-initiated // actions. (Note: Clear-Site-Data is only available on HTTPS URLs.) IN_PROC_BROWSER_TEST_F(SiteIsolationForPasswordSitesBrowserTest, ClearSiteDataDoesNotClearSavedIsolatedSites) { … } // This test class turns on the feature to dynamically isolate sites where the // user logs in via OAuth. This also requires enabling OAuth login detection // (which is used by other features as well) and disabling strict site // isolation (so that OAuth isolation can be observed on desktop platforms). class SiteIsolationForOAuthSitesBrowserTest : public ChromeNavigationBrowserTest { … }; // Simulate a popup-based OAuth login flow, where a client opens a popup to log // in via OAuth. Ensure that the client's site becomes isolated when the OAuth // login completes. IN_PROC_BROWSER_TEST_F(SiteIsolationForOAuthSitesBrowserTest, PopupFlow) { … } // Similar to previous test, but simulate a same-window OAuth login flow, where // a client navigates directly to the OAuth provider, which will // navigate/redirect back to the client when the login flow completes. // // Part 2 of this test also verifies that OAuth site isolation persists across // restarts. IN_PROC_BROWSER_TEST_F(SiteIsolationForOAuthSitesBrowserTest, PRE_RedirectFlow) { … } // See part 1 of the test above. This is part 2, which verifies that OAuth // site isolation persists across restarts. IN_PROC_BROWSER_TEST_F(SiteIsolationForOAuthSitesBrowserTest, RedirectFlow) { … } // This test class turns on the mode where sites served with // Cross-Origin-Opener-Policy headers are site-isolated. This complements // COOPIsolationTest in content_browsertests and focuses on persistence of COOP // sites in user prefs, which requires the //chrome layer. class SiteIsolationForCOOPBrowserTest : public ChromeNavigationBrowserTest { … }; // Verifies that sites isolated due to COOP headers are persisted across // restarts. Note that persistence requires both visiting the COOP site and // interacting with it via a user activation. Part 1/2. IN_PROC_BROWSER_TEST_F(SiteIsolationForCOOPBrowserTest, PRE_PersistAcrossRestarts) { … } // Verifies that sites isolated due to COOP headers with a user activation are // persisted across restarts. Part 2/2. IN_PROC_BROWSER_TEST_F(SiteIsolationForCOOPBrowserTest, PersistAcrossRestarts) { … } // Check that COOP sites are not persisted in Incognito; the isolation should // only persist for the duration of the Incognito session. IN_PROC_BROWSER_TEST_F(SiteIsolationForCOOPBrowserTest, Incognito) { … } // Verify that when a COOP-isolated site is visited again, the timestamp in its // stored pref entry is updated correctly and taken into consideration when // trimming the list of stored COOP sites to its maximum size. IN_PROC_BROWSER_TEST_F(SiteIsolationForCOOPBrowserTest, TimestampUpdateOnSecondVisit) { … }