chromium/chrome/browser/extensions/api/web_request/web_request_apitest.cc

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

#include <array>
#include <memory>
#include <optional>
#include <utility>
#include <vector>

#include "base/base64.h"
#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/json/json_reader.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/lock.h"
#include "base/task/sequenced_task_runner.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/run_until.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_future.h"
#include "base/time/time.h"
#include "base/time/time_override.h"
#include "base/values.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/devtools/protocol/devtools_protocol_test_support.h"
#include "chrome/browser/devtools/url_constants.h"
#include "chrome/browser/extensions/api/extension_action/test_extension_action_api_observer.h"
#include "chrome/browser/extensions/error_console/error_console.h"
#include "chrome/browser/extensions/error_console/error_console_test_observer.h"
#include "chrome/browser/extensions/extension_action_runner.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/extensions/extension_with_management_policy_apitest.h"
#include "chrome/browser/extensions/permissions/active_tab_permission_granter.h"
#include "chrome/browser/extensions/permissions/scripting_permissions_modifier.h"
#include "chrome/browser/extensions/tab_helper.h"
#include "chrome/browser/net/profile_network_context_service.h"
#include "chrome/browser/net/profile_network_context_service_factory.h"
#include "chrome/browser/net/system_network_context_manager.h"
#include "chrome/browser/new_tab_page/one_google_bar/one_google_bar_loader.h"
#include "chrome/browser/new_tab_page/one_google_bar/one_google_bar_service.h"
#include "chrome/browser/new_tab_page/one_google_bar/one_google_bar_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_destroyer.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/search/search.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_navigator_params.h"
#include "chrome/browser/ui/login/login_handler.h"
#include "chrome/browser/ui/search/ntp_test_utils.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/search_test_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/embedder_support/switches.h"
#include "components/google/core/common/google_switches.h"
#include "components/policy/core/common/mock_configuration_policy_provider.h"
#include "components/policy/policy_constants.h"
#include "components/prefs/pref_service.h"
#include "components/proxy_config/proxy_config_dictionary.h"
#include "components/proxy_config/proxy_config_pref_names.h"
#include "components/ukm/test_ukm_recorder.h"
#include "components/web_package/web_bundle_builder.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/webui_config_map.h"
#include "content/public/common/content_features.h"
#include "content/public/common/page_type.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/prerender_test_util.h"
#include "content/public/test/simple_url_loader_test_helper.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/url_loader_interceptor.h"
#include "content/public/test/url_loader_monitor.h"
#include "content/public/test/web_transport_simple_test_server.h"
#include "extensions/browser/api/web_request/extension_web_request_event_router.h"
#include "extensions/browser/api/web_request/web_request_api.h"
#include "extensions/browser/background_script_executor.h"
#include "extensions/browser/blocked_action_type.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/process_manager.h"
#include "extensions/browser/service_worker/service_worker_task_queue.h"
#include "extensions/browser/service_worker/service_worker_test_utils.h"
#include "extensions/common/extension_builder.h"
#include "extensions/common/extension_features.h"
#include "extensions/common/features/feature.h"
#include "extensions/test/extension_test_message_listener.h"
#include "extensions/test/result_catcher.h"
#include "extensions/test/test_extension_dir.h"
#include "google_apis/gaia/gaia_switches.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "net/base/network_isolation_key.h"
#include "net/cookies/site_for_cookies.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_util.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/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "net/test/embedded_test_server/request_handler_util.h"
#include "net/test/test_data_directory.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "services/metrics/public/cpp/metrics_utils.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "services/metrics/public/mojom/ukm_interface.mojom.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "services/network/public/cpp/url_loader_factory_builder.h"
#include "services/network/public/mojom/fetch_api.mojom.h"
#include "services/network/test/test_url_loader_client.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/input/web_input_event.h"
#include "ui/base/ui_base_features.h"
#include "ui/webui/untrusted_web_ui_browsertest_util.h"
#include "url/origin.h"

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "chrome/browser/ash/profiles/profile_helper.h"
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

WebContents;

namespace extensions {

namespace {

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

// Observer that listens for messages from chrome.test.sendMessage to allow them
// to be used to trigger browser initiated naviagations from the javascript for
// testing purposes.
class NavigateTabMessageHandler {};

// Sends an XHR request to the provided host, port, and path, and responds when
// the request was sent.
const char kPerformXhrJs[] =;

// Header values set by the server and by the extension.
const char kHeaderValueFromExtension[] =;
const char kHeaderValueFromServer[] =;

constexpr char kCORSUrl[] =;
constexpr char kCORSProxyUser[] =;
constexpr char kCORSProxyPass[] =;
constexpr char kCustomPreflightHeader[] =;

// Performs an XHR in the given |frame|, replying when complete.
void PerformXhrInFrame(content::RenderFrameHost* frame,
                      const std::string& host,
                      int port,
                      const std::string& page) {}

base::Value ExecuteScriptAndReturnValue(const ExtensionId& extension_id,
                                        content::BrowserContext* context,
                                        const std::string& script) {}

std::optional<bool> ExecuteScriptAndReturnBool(const ExtensionId& extension_id,
                                               content::BrowserContext* context,
                                               const std::string& script) {}

std::optional<std::string> ExecuteScriptAndReturnString(
    const ExtensionId& extension_id,
    content::BrowserContext* context,
    const std::string& script) {}

// Returns the current count of a variable stored in the |extension| background
// script context (either background page or service worker). Returns -1 if
// something goes awry.
int GetCountFromBackgroundScript(const Extension* extension,
                                 content::BrowserContext* context,
                                 const std::string& variable_name) {}

// Returns the current count of webRequests received by the |extension| in
// the background script, either background page or service worker. Assumes the
// extension stores a value on the `self` object. Returns -1 if something goes
// awry.
int GetWebRequestCountFromBackgroundScript(const Extension* extension,
                                           content::BrowserContext* context) {}

// Returns true if the |extension|'s background script saw an event for a
// request with the given |hostname| (|hostname| should exclude port).
bool HasSeenWebRequestInBackgroundScript(const Extension* extension,
                                         content::BrowserContext* context,
                                         const std::string& hostname) {}

void WaitForExtraHeadersListener(base::WaitableEvent* event,
                                 content::BrowserContext* browser_context) {}

}  // namespace

class ExtensionWebRequestApiTest : public ExtensionApiTest {};

ContextType;

enum class BackgroundResourceFetchTestCase {};

class ExtensionWebRequestApiTestWithContextType
    : public ExtensionWebRequestApiTest,
      public testing::WithParamInterface<
          std::pair<ContextType, BackgroundResourceFetchTestCase>> {};

INSTANTIATE_TEST_SUITE_P();

// These tests use webRequestBlocking and/or declarativeWebRequest.
// See crbug.com/332512510.
INSTANTIATE_TEST_SUITE_P();

class DevToolsFrontendInWebRequestApiTest : public ExtensionApiTest {};

IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       WebRequestApi) {}

IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       WebRequestSimple) {}

// TODO(crbug.com/333791060): Parameterized test is flaky on multiple bots.
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       DISABLED_WebRequestComplex) {}

class ExtensionDevToolsProtocolTest
    : public ExtensionWebRequestApiTestWithContextType,
      public content::TestDevToolsProtocolClient {};

INSTANTIATE_TEST_SUITE_P();

// These tests use webRequestBlocking and/or declarativeWebRequest.
// See crbug.com/332512510.
INSTANTIATE_TEST_SUITE_P();

IN_PROC_BROWSER_TEST_P(ExtensionDevToolsProtocolTest,
                       HeaderOverriddenByExtension) {}

IN_PROC_BROWSER_TEST_P(ExtensionDevToolsProtocolTest,
                       HeaderOverrideViaProtocolAllowedByExtension) {}

// TODO(crbug.com/40168662) The test is flaky on multiple bots.
IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, DISABLED_WebRequestTypes) {}

// Test that a request to an OpenSearch description document (OSDD) generates
// an event with the expected details.
// Flaky on Windows and Mac: https://crbug.com/1218893
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
#define MAYBE_WebRequestTestOSDD
#else
#define MAYBE_WebRequestTestOSDD
#endif
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       MAYBE_WebRequestTestOSDD) {}

// Test that the webRequest events are dispatched with the expected details when
// a frame or tab is removed while a response is being received.
IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest,
                       WebRequestUnloadAfterRequest) {}

// Test that the webRequest events are dispatched with the expected details when
// a frame or tab is immediately removed after starting a request.
// Flaky on all platforms. See crbug.com/780369 for detail.
IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest,
                       DISABLED_WebRequestUnloadImmediately) {}

enum class ProfileMode {};

struct ARTestParams {};

class ExtensionWebRequestApiAuthRequiredTest
    : public ExtensionWebRequestApiTest,
      public testing::WithParamInterface<ARTestParams> {};

IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiAuthRequiredTest,
                       WebRequestAuthRequired) {}

IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiAuthRequiredTest,
                       WebRequestAuthRequiredAsync) {}

// This is flaky on wide variety of platforms (beyond that tracked previously in
// https://crbug.com/998369). See https://crbug.com/1026001.
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiAuthRequiredTest,
                       DISABLED_WebRequestAuthRequiredParallel) {}

INSTANTIATE_TEST_SUITE_P();
INSTANTIATE_TEST_SUITE_P();

// These tests use webRequestBlocking and/or declarativeWebRequest.
// See crbug.com/332512510.
INSTANTIATE_TEST_SUITE_P();
INSTANTIATE_TEST_SUITE_P();

IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       WebRequestBlocking) {}

// This test times out regularly on win_rel trybots. See http://crbug.com/122178
// Also on Linux/ChromiumOS debug, ASAN and MSAN builds.
// https://crbug.com/670415
// Slower and flaky tests should be isolated in the "slow" group of tests in
// the JS file. This prevents losing test coverage for those tests that are
// not causing timeouts and flakes.
// TODO(crbug.com/40916455): Investigate the flakiness across all
// platforms and re-enable.
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       DISABLED_WebRequestBlockingSlow) {}

IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       WebRequestBlockingSetCookieHeader) {}

IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       WebRequestExtraHeaders) {}

// Flaky on all platforms: https://crbug.com/1003661
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       DISABLED_WebRequestExtraHeaders_Auth) {}

IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       WebRequestChangeCSPHeaders) {}

// TODO: crbug.com/1450976 - Re-enable tests on Mac and CrOS.
#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS)
#define MAYBE_WebRequestCORSWithExtraHeaders
#else
#define MAYBE_WebRequestCORSWithExtraHeaders
#endif
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       MAYBE_WebRequestCORSWithExtraHeaders) {}

#if defined(ADDRESS_SANITIZER)
#define MAYBE_WebRequestRedirects
#else
#define MAYBE_WebRequestRedirects
#endif
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       MAYBE_WebRequestRedirects) {}

IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       WebRequestRedirectsWithExtraHeaders) {}

// Tests that redirects from secure to insecure don't send the referrer header.
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       WebRequestRedirectsToInsecure) {}

// Tests redirects around workers. To test service workers, the HTTPS test
// server is used.
// TODO(crbug.com/40255652): test is flaky on linux-chromeos-rel.
// TODO(crbug.com/40259518): test is flaky on Mac10.14.
// TODO(crbug.com/40282182): test is flaky on linux tests.
#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
#define MAYBE_WebRequestRedirectsWorkers
#else
#define MAYBE_WebRequestRedirectsWorkers
#endif
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       MAYBE_WebRequestRedirectsWorkers) {}

// TODO(crbug.com/40916455): test is flaky on multiple platforms.
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       DISABLED_WebRequestSubresourceRedirects) {}

// TODO(crbug.com/40916455): test is flaky on multiple platforms.
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       DISABLED_WebRequestSubresourceRedirectsWithExtraHeaders) {}

IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       WebRequestNewTab) {}

IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       WebRequestDeclarative1) {}

// This test fixture runs all of the broken and flaky tests. It's disabled
// until these tests are fixed and moved to the set of tests that aren't
// broken or flaky. Should tests become flaky, they can be moved here.
// See https://crbug.com/846555.
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       DISABLED_WebRequestDeclarative1Broken) {}

IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       WebRequestDeclarative2) {}

void ExtensionWebRequestApiTest::RunPermissionTest(
    const char* extension_directory,
    bool load_extension_with_incognito_permission,
    bool wait_for_extension_loaded_in_incognito,
    const char* expected_content_regular_window,
    const char* exptected_content_incognito_window,
    ContextType context_type) {}

IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       WebRequestDeclarativePermissionSpanning1) {}

IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       WebRequestDeclarativePermissionSpanning2) {}

IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       WebRequestDeclarativePermissionSplit1) {}

IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       WebRequestDeclarativePermissionSplit2) {}

// TODO(crbug.com/41010858): Cure these flaky tests.
// TODO(crbug.com/40734863): Bulk-disabled as part of mac arm64 bot greening
// TODO(crbug.com/40773828): Further disabled due to ongoing flakiness.
IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, DISABLED_PostData1) {}

IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, DISABLED_PostData2) {}

IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       DeclarativeSendMessage) {}

// Check that reloading an extension that runs in incognito split mode and
// has two active background pages with registered events does not crash the
// browser. Regression test for http://crbug.com/224094
// Flaky on linux-lacros and Linux. See http://crbug.com/1423252
#if BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(IS_LINUX)
#define MAYBE_IncognitoSplitModeReload
#else
#define MAYBE_IncognitoSplitModeReload
#endif
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       MAYBE_IncognitoSplitModeReload) {}

IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       ExtensionRequests) {}

IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, HostedAppRequest) {}

// Tests that WebRequest works with runtime host permissions.
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       WebRequestWithWithheldPermissions) {}

// Test that extensions with granted runtime host permissions to a tab can
// intercept cross-origin requests from that tab.
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       WebRequestWithheldPermissionsCrossOriginRequests) {}

// Tests behavior when an extension has withheld access to a request's URL, but
// not the initiator's (tab's) URL. Regression test for
// https://crbug.com/891586.
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       WithheldHostPermissionsForCrossOriginWithoutInitiator) {}

// Verify that requests to clientsX.google.com are protected properly.
// First test requests from a standard renderer and then a request from the
// browser process.
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       WebRequestClientsGoogleComProtection) {}

// Verify that requests for PAC scripts are protected properly.
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       WebRequestPacRequestProtection) {}

// Checks that the Dice response header is protected for Gaia URLs, but not
// other URLs.
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       WebRequestDiceHeaderProtection) {}

// Test that the webRequest events are dispatched for the WebSocket handshake
// requests.
// TODO(crbug.com/40715657): Test is flaky on multiple platforms.
IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, DISABLED_WebSocketRequest) {}

// Test that the webRequest events are dispatched for the WebSocket handshake
// requests when authenrication is requested by server.
// TODO(crbug.com/40168662) Re-enable test
IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest,
                       DISABLED_WebSocketRequestAuthRequired) {}

// Test that the webRequest events are dispatched for the WebSocket handshake
// requests.
IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, WebSocketRequestOnWorker) {}

// Tests that a clean close from the server is not reported as an error when
// there is a race between OnDropChannel and SendFrame.
// Regression test for https://crbug.com/937790.
//
// TODO(b:332825952): Flaky on linux-chromeos-dbg
#if BUILDFLAG(IS_CHROMEOS)
#define MAYBE_WebSocketCleanClose
#else
#define MAYBE_WebSocketCleanClose
#endif
IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, MAYBE_WebSocketCleanClose) {}

class ExtensionWebRequestApiWebTransportTest
    : public ExtensionWebRequestApiTest {};

// Test that the webRequest events are dispatched for the WebTransport
// handshake.
// TODO(crbug.com/326122304): Re-enable this test
IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiWebTransportTest, DISABLED_Main) {}

// Test that the webRequest events are dispatched for the WebTransport
// handshake in a dedicated worker.
IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiWebTransportTest,
                       DedicaterWorker) {}

// Test that the webRequest events are dispatched for the WebTransport
// handshake in a shared worker.
IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiWebTransportTest, SharedWorker) {}

// Test that the webRequest events are dispatched for the WebTransport
// handshake in a service worker.
IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiWebTransportTest, ServiceWorker) {}

// Test behavior when intercepting requests from a browser-initiated url fetch.
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       WebRequestURLLoaderInterception) {}

// Test that extensions need host permissions to both the request url and
// initiator to intercept a request.
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       InitiatorAccessRequired) {}

IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest,
                       WebRequestApiClearsBindingOnFirstListener) {}

// Regression test for http://crbug.com/878366.
IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest,
                       WebRequestApiDoesNotCrashOnErrorAfterProfileDestroyed) {}

// Tests that webRequest API can inspect window.open() requests initiated from
// chrome-untrusted:// pages to Web origins, but not other WebUI origins.
IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest,
                       OpenNewTabFromChromeUntrusted) {}

// Tests that webRequest API can inspect a chrome-untrusted:// main frame
// navigating itself to Web origins.
IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest,
                       NavigateMainFrameToWebOriginFromChromeUntrusted) {}

// Tests that webRequest API can't inspect a chrome-untrusted:// main frame
// navigating itself to another WebUI origin.
IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest,
                       NavigateMainFrameToWebUIOriginFromChromeUntrusted) {}

// Tests that webRequest API can't inspect a subframe inside chrome-untrusted://
// navigating to a Web origin.
IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest,
                       SubframeNavigationsInChromeUntrustedPage) {}

// Test fixture which sets a custom NTP Page.
class NTPInterceptionWebRequestAPITest
    : public ExtensionApiTest,
      public testing::WithParamInterface<ContextType> {};

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

// Ensures that requests made by the NTP Instant renderer are hidden from the
// Web Request API. Regression test for crbug.com/797461.
IN_PROC_BROWSER_TEST_P(NTPInterceptionWebRequestAPITest,
                       NTPRendererRequestsHidden) {}

// Test fixture testing that requests made for the OneGoogleBar on behalf of
// the WebUI NTP can't be intercepted by extensions.
class WebUiNtpInterceptionWebRequestAPITest
    : public ExtensionApiTest,
      public OneGoogleBarServiceObserver,
      public testing::WithParamInterface<ContextType> {};

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

IN_PROC_BROWSER_TEST_P(WebUiNtpInterceptionWebRequestAPITest,
                       OneGoogleBarRequestsHidden) {}

// Ensure that devtools frontend requests are hidden from the webRequest API.
IN_PROC_BROWSER_TEST_F(DevToolsFrontendInWebRequestApiTest, HiddenRequests) {}

class WebRequestApiTestWithManagementPolicy
    : public ExtensionApiTestWithManagementPolicy,
      public testing::WithParamInterface<ContextType> {};

INSTANTIATE_TEST_SUITE_P();
INSTANTIATE_TEST_SUITE_P();

// Tests that the webRequest events aren't dispatched when the request initiator
// is protected by policy.
IN_PROC_BROWSER_TEST_P(WebRequestApiTestWithManagementPolicy,
                       InitiatorProtectedByPolicy) {}

// Tests that the webRequest events aren't dispatched when the URL of the
// request is protected by policy.
IN_PROC_BROWSER_TEST_P(WebRequestApiTestWithManagementPolicy,
                       UrlProtectedByPolicy) {}

// Test that no webRequest events are seen for a protected host during normal
// navigation. This replicates most of the tests from
// WebRequestWithWithheldPermissions with a protected host. Granting a tab
// specific permission shouldn't bypass our policy.
IN_PROC_BROWSER_TEST_P(WebRequestApiTestWithManagementPolicy,
                       WebRequestProtectedByPolicy) {}

// A test fixture which mocks the Time::Now() function to ensure that the
// default clock returns monotonically increasing time.
class ExtensionWebRequestMockedClockTest
    : public ExtensionWebRequestApiTestWithContextType {};

INSTANTIATE_TEST_SUITE_P();

// These tests use webRequestBlocking and/or declarativeWebRequest.
// See crbug.com/332512510.
INSTANTIATE_TEST_SUITE_P();

// Tests that we correctly dispatch the OnActionIgnored event on an extension
// if the extension's proposed redirect is ignored.
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestMockedClockTest,
                       OnActionIgnored_Redirect) {}

// Regression test for http://crbug.com/1074282.
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       StaleHeadersAfterRedirect) {}

IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       ChangeHeaderUMAs) {}

IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       RemoveHeaderUMAs) {}

struct SWTestParams {};

class ServiceWorkerWebRequestApiTest
    : public testing::WithParamInterface<SWTestParams>,
      public ExtensionApiTest {};

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

// These tests use webRequestBlocking and/or declarativeWebRequest.
// See crbug.com/332512510.
INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

IN_PROC_BROWSER_TEST_P(ServiceWorkerWebRequestApiTest, ServiceWorkerFetch) {}

IN_PROC_BROWSER_TEST_P(ServiceWorkerWebRequestApiTest, ServiceWorkerFallback) {}

IN_PROC_BROWSER_TEST_P(ServiceWorkerWebRequestApiTest,
                       ServiceWorkerNoFetchHandler) {}

IN_PROC_BROWSER_TEST_P(ServiceWorkerWebRequestApiTest,
                       ServiceWorkerFallbackAfterRedirect) {}

// An extension should be able to modify the request header for service worker
// script by using WebRequest API.
IN_PROC_BROWSER_TEST_P(ServiceWorkerWebRequestApiTest, ServiceWorkerScript) {}

// An extension should be able to modify the request header for module service
// worker script by using WebRequest API.
IN_PROC_BROWSER_TEST_P(ServiceWorkerWebRequestApiTest,
                       ModuleServiceWorkerScript) {}

// An extension should be able to modify the request header for module service
// worker script with static import by using WebRequest API.
IN_PROC_BROWSER_TEST_P(ServiceWorkerWebRequestApiTest,
                       ModuleServiceWorkerScriptWithStaticImport) {}

// Ensure that extensions can intercept service worker navigation preload
// requests.
IN_PROC_BROWSER_TEST_P(ServiceWorkerWebRequestApiTest,
                       ServiceWorkerNavigationPreload) {}

// Ensure we don't strip off initiator incorrectly in web request events when
// both the normal and incognito contexts are active. Regression test for
// crbug.com/934398.
// TODO(crbug.com/41493389): enable this flaky test
#if BUILDFLAG(IS_LINUX) && defined(ADDRESS_SANITIZER) && defined(LEAK_SANITIZER)
#define MAYBE_Initiator_SpanningIncognito
#else
#define MAYBE_Initiator_SpanningIncognito
#endif
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       MAYBE_Initiator_SpanningIncognito) {}

// Ensure we don't strip off initiator incorrectly in web request events when
// both the normal and incognito contexts are active. Regression test for
// crbug.com/934398.
// Flaky on Linux. See http://crbug.com/1423252
#if BUILDFLAG(IS_LINUX)
#define MAYBE_Initiator_SplitIncognito
#else
#define MAYBE_Initiator_SplitIncognito
#endif
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       MAYBE_Initiator_SplitIncognito) {}

// A request handler that sets the Access-Control-Allow-Origin header.
std::unique_ptr<net::test_server::HttpResponse> HandleXHRRequest(
    const net::test_server::HttpRequest& request) {}

// Regression test for http://crbug.com/971206. The responseHeaders should still
// be present in onBeforeRedirect even for HSTS upgrade.
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       ExtraHeadersWithHSTSUpgrade) {}

// Ensure that when an extension blocks a main-frame request, the resultant
// error page attributes this to an extension.
IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest,
                       ErrorPageForBlockedMainFrameNavigation) {}

// Regression test for https://crbug.com/1019614.
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       HSTSUpgradeAfterRedirect) {}

// Regression test for https://crbug.com/40864513. This test passes if it
// doesn't crash.
// This is a copy of HSTSUpgradeAfterRedirect, but the redirect contains a CSP
// header.
// TODO(https://crbug.com/40864513) Enable this test.
IN_PROC_BROWSER_TEST_P(ExtensionWebRequestApiTestWithContextType,
                       DISABLED_HSTSUpgradeAfterRedirectWithCSP) {}

// Tests registering webRequest events in multiple contexts in the same
// extension (which will thus be in the same process). Regression test for
// https://crbug.com/1297276.
IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest,
                       ListenersInMultipleContexts) {}

struct SWBTestParams {};

class SubresourceWebBundlesWebRequestApiTest
    : public testing::WithParamInterface<SWBTestParams>,
      public ExtensionApiTest {};

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

// These tests use webRequestBlocking and/or declarativeWebRequest.
// See crbug.com/332512510.
INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

// Ensure web request listeners can intercept requests for a web bundle and its
// subresources.
// TODO(crbug.com/40801096): Fix flane and re-enable test.
IN_PROC_BROWSER_TEST_P(SubresourceWebBundlesWebRequestApiTest,
                       DISABLED_RequestIntercepted) {}

// Ensure web request API can block the requests for the subresources inside the
// web bundle.
IN_PROC_BROWSER_TEST_P(SubresourceWebBundlesWebRequestApiTest,
                       RequestCanceled) {}

// Ensure web request API can change the headers of the subresources inside the
// web bundle.
IN_PROC_BROWSER_TEST_P(SubresourceWebBundlesWebRequestApiTest, ChangeHeader) {}

// Ensure web request API can change the response headers of uuid-in-package:
// URL subresources inside the web bundle.
// Note: Currently we can't directly check the response headers of
// uuid-in-package: URL resources, because CORS requests are not allowed for
// such URLs. So we change the content-type header of a JavaScript file and
// monitor the error handler. Subresources in web bundles should be treated as
// if an artificial `X-Content-Type-Options: nosniff` header field is set. So
// when the content-type is not suitable for script execution, the script
// should fail to load.
IN_PROC_BROWSER_TEST_P(SubresourceWebBundlesWebRequestApiTest,
                       ChangeHeaderUuidInPackageUrlResource) {}

// Ensure web request API can redirect the requests for the subresources inside
// the web bundle.
IN_PROC_BROWSER_TEST_P(SubresourceWebBundlesWebRequestApiTest,
                       RequestRedirected) {}

// Ensure that request to Subresource WebBundle fails if it is redirected by web
// request API.
IN_PROC_BROWSER_TEST_P(SubresourceWebBundlesWebRequestApiTest,
                       WebBundleRequestRedirected) {}

// Ensure web request listener can intercept requests for web bundles with the
// resource type "webbundle".
IN_PROC_BROWSER_TEST_P(SubresourceWebBundlesWebRequestApiTest,
                       WebBundleRequestCanceledWithResourceType) {}

// TODO(crbug.com/40130781) When we implement variant matching of subresource
// web bundles, we should add test for request header modification.

enum class RedirectType {};

struct RITestParams {};

class RedirectInfoWebRequestApiTest
    : public testing::WithParamInterface<RITestParams>,
      public ExtensionApiTest {};

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

// These tests use webRequestBlocking and/or declarativeWebRequest.
// See crbug.com/332512510.
INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

// Test that a main frame request redirected by an extension has the correct
// site_for_cookies and network_isolation_key parameters.
IN_PROC_BROWSER_TEST_P(RedirectInfoWebRequestApiTest,
                       VerifyRedirectInfoMainFrame) {}

// Test that a sub frame request redirected by an extension has the correct
// site_for_cookies and network_isolation_key parameters.
IN_PROC_BROWSER_TEST_P(RedirectInfoWebRequestApiTest,
                       VerifyBeforeRequestRedirectInfoSubFrame) {}

// Regression test for crbug.com/1510422 to validate that redirection to an
// invalid URL by extension does not crash the browser.
IN_PROC_BROWSER_TEST_P(RedirectInfoWebRequestApiTest,
                       VerifyInvalidUrlRedirection) {}

class ProxyCORSWebRequestApiTest
    : public ExtensionApiTest,
      public testing::WithParamInterface<ContextType> {};

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

// Regression test for crbug.com/1212625
// Test that CORS preflight request which requires proxy auth completes
// successfully instead of being cancelled after proxy auth required response.
IN_PROC_BROWSER_TEST_P(ProxyCORSWebRequestApiTest,
                       PreflightCompletesSuccessfully) {}

class ExtensionWebRequestApiFencedFrameTest
    : public ExtensionWebRequestApiTest {};

IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiFencedFrameTest, Load) {}

IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiFencedFrameTest,
                       DeclarativeSendMessage) {}

class ExtensionWebRequestApiPrerenderingTest
    : public ExtensionWebRequestApiTest {};

IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiPrerenderingTest, Load) {}

IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiPrerenderingTest, LoadIntoNewTab) {}

// A clunky test suite class to allow for waiting for a message to be sent from
// the extension's background context when it starts up. We need this because
// we don't currently have a good way of waiting for a service worker context to
// be fully initialized.
class WebRequestPersistentListenersTest
    : public ExtensionWebRequestApiTestWithContextType {};

namespace {

constexpr char kGetNumRequests[] =;

}  // namespace

// Tests that webRequest listeners are persistent across browser restarts.
IN_PROC_BROWSER_TEST_P(WebRequestPersistentListenersTest,
                       PRE_TestListenersArePersistent) {}

IN_PROC_BROWSER_TEST_P(WebRequestPersistentListenersTest,
                       TestListenersArePersistent) {}

INSTANTIATE_TEST_SUITE_P();
INSTANTIATE_TEST_SUITE_P();

class ManifestV3WebRequestApiTest : public ExtensionWebRequestApiTest {};

// Tests a service worker-based extension intercepting requests with
// webRequestBlocking.
IN_PROC_BROWSER_TEST_F(ManifestV3WebRequestApiTest, WebRequestBlocking) {}

// Tests a service worker-based extension registering multiple webRequest events
// in multiple contexts. This ensures the subevent name logic for service worker
// extensions doesn't result in any collisions of listener IDs, similar to the
// issue found in https://crbug.com/1297276.
IN_PROC_BROWSER_TEST_F(ManifestV3WebRequestApiTest,
                       MultipleListenersAndContexts) {}

// Tests that a service worker-based extension with webRequestBlocking can
// intercept requests after the service worker stops.
IN_PROC_BROWSER_TEST_F(ManifestV3WebRequestApiTest,
                       WebRequestBlocking_AfterWorkerShutdown) {}

// Tests a service worker-based extension using webRequest for observational
// purposes receives events after the worker stops.
IN_PROC_BROWSER_TEST_F(ManifestV3WebRequestApiTest,
                       WebRequestObservation_AfterWorkerShutdown) {}

// Tests unloading an extension with lazy listeners while the worker is
// inactive. The listeners should be properly cleaned up.
IN_PROC_BROWSER_TEST_F(
    ManifestV3WebRequestApiTest,
    ServiceWorkerWithWebRequest_UnloadExtensionWhileWorkerInactive) {}

// Tests a service worker adding and then removing a listener.
IN_PROC_BROWSER_TEST_F(ManifestV3WebRequestApiTest,
                       ServiceWorkerWithWebRequest_ManuallyRemoveListener) {}

// Tests listeners in multiple contexts with lazy event disptaching.
IN_PROC_BROWSER_TEST_F(ManifestV3WebRequestApiTest,
                       ListenersInMultipleContextsWithLazyDispatch) {}

// Tests that an MV3 extension can use the `webRequestAuthProvider` permission
// to intercept and handle `onAuthRequired` events coming from a tab.
IN_PROC_BROWSER_TEST_F(ManifestV3WebRequestApiTest, TestOnAuthRequiredTab) {}

class OnAuthRequiredApiTest : public ExtensionApiTest {};

// Tests that an MV3 extension can use the `webRequestAuthProvider` permission
// to intercept and handle `onAuthRequired` events coming from an extension
// service worker. This test does the following:
//   (1) This loads an extension with a service-worker background.js.
//   (2) The extension adds a listener to chrome.webRequest.onAuthRequired.
//   (3) The extension attempts to fetch a resource that requires http auth.
//   (4) This triggers the listener in (3), which supplies credentials
//   (5) Checks that the fetch succeeded.
IN_PROC_BROWSER_TEST_F(OnAuthRequiredApiTest,
                       TestOnAuthRequiredExtensionServiceWorker) {}

// This test is similar to TestOnAuthRequiredExtensionServiceWorker but the
// service worker is hosted by a website instead of the extension istelf.
IN_PROC_BROWSER_TEST_F(OnAuthRequiredApiTest,
                       TestOnAuthRequiredWebsiteServiceWorker) {}

// Tests the behavior of an extension that registers an event listener
// asynchronously.
// Regression test for https://crbug.com/1397879 and https://crbug.com/1434212.
IN_PROC_BROWSER_TEST_F(ManifestV3WebRequestApiTest, AsyncListenerRegistration) {}

// Tests behavior when a service worker is stopped while processing an event.
IN_PROC_BROWSER_TEST_F(ManifestV3WebRequestApiTest,
                       ServiceWorkerGoesAwayWhileHandlingRequest) {}

// Tests that a MV3 extension that doesn't have the `webRequestAuthProvider`
// permission cannot use blocking listeners for `onAuthRequired`.
IN_PROC_BROWSER_TEST_F(ManifestV3WebRequestApiTest,
                       TestOnAuthRequired_NoPermission) {}

// Tests that an extension that doesn't have the `webView` permission cannot
// manually create and add a WebRequestEvent that specifies a webViewInstanceId.
// TODO(tjudkins): It would be good to also stop this on the JS layer by not
// allowing extensions to manually create and add WebRequestEvents.
// Regression test for crbug.com/1472830
IN_PROC_BROWSER_TEST_F(ManifestV3WebRequestApiTest,
                       TestWebviewIdSpecifiedOnEvent_NoPermission) {}

IN_PROC_BROWSER_TEST_F(ManifestV3WebRequestApiTest, RecordUkmOnNavigation) {}

}  // namespace extensions