chromium/chrome/browser/extensions/service_worker_apitest.cc

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

#include "chrome/browser/extensions/service_worker_apitest.h"

#include <stdint.h>

#include <optional>
#include <utility>

#include "base/auto_reset.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/json/json_reader.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/scoped_observation.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/threading/thread_restrictions.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/extensions/api/permissions/permissions_api.h"
#include "chrome/browser/extensions/browsertest_util.h"
#include "chrome/browser/extensions/chrome_content_browser_client_extensions_part.h"
#include "chrome/browser/extensions/chrome_test_extension_loader.h"
#include "chrome/browser/extensions/crx_installer.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/unpacked_installer.h"
#include "chrome/browser/gcm/gcm_profile_service_factory.h"
#include "chrome/browser/notifications/notification_display_service_factory.h"
#include "chrome/browser/notifications/notification_display_service_tester.h"
#include "chrome/browser/notifications/notification_permission_context.h"
#include "chrome/browser/notifications/stub_notification_display_service.h"
#include "chrome/browser/push_messaging/push_messaging_app_identifier.h"
#include "chrome/browser/push_messaging/push_messaging_features.h"
#include "chrome/browser/push_messaging/push_messaging_service_factory.h"
#include "chrome/browser/push_messaging/push_messaging_service_impl.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/api/web_navigation.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "components/gcm_driver/fake_gcm_profile_service.h"
#include "components/gcm_driver/instance_id/fake_gcm_driver_for_instance_id.h"
#include "components/version_info/channel.h"
#include "components/version_info/version_info.h"
#include "content/public/browser/console_message.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/service_worker_context.h"
#include "content/public/browser/service_worker_context_observer.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/page_type.h"
#include "content/public/common/result_codes.h"
#include "content/public/test/background_sync_test_util.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/service_worker_test_helpers.h"
#include "extensions/browser/browsertest_util.h"
#include "extensions/browser/event_router.h"
#include "extensions/browser/extension_function_histogram_value.h"
#include "extensions/browser/extension_host.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/process_map.h"
#include "extensions/browser/service_worker/service_worker_task_queue.h"
#include "extensions/browser/service_worker/service_worker_test_utils.h"
#include "extensions/common/api/test.h"
#include "extensions/common/extensions_client.h"
#include "extensions/common/features/feature_channel.h"
#include "extensions/common/manifest_handlers/background_info.h"
#include "extensions/common/mojom/event_dispatcher.mojom.h"
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/common/verifier_formats.h"
#include "extensions/test/extension_background_page_waiter.h"
#include "extensions/test/extension_test_message_listener.h"
#include "extensions/test/result_catcher.h"
#include "extensions/test/test_extension_dir.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "services/network/public/cpp/is_potentially_trustworthy.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
#include "ui/message_center/public/cpp/notification.h"
#include "url/url_constants.h"

namespace extensions {

TestServiceWorkerTaskQueueObserver;

namespace {

HasSubstr;

class WebContentsLoadStopObserver : content::WebContentsObserver {};

// Extension ID for tests that use
// "worker_based_background/test_extension.pem" key.
constexpr char kTestExtensionId[] =;

}  // namespace

void ServiceWorkerTest::SetUpOnMainThread() {}

const Extension* ServiceWorkerTest::StartTestFromBackgroundPage(
    const char* script_name) {}

content::WebContents* ServiceWorkerTest::Navigate(const GURL& url) {}

content::PageType ServiceWorkerTest::NavigateAndGetPageType(const GURL& url) {}

std::string ServiceWorkerTest::ExtractInnerText(
    content::WebContents* contents) {}

std::string ServiceWorkerTest::NavigateAndExtractInnerText(const GURL& url) {}

size_t ServiceWorkerTest::GetWorkerRefCount(const blink::StorageKey& key) {}

void ServiceWorkerBasedBackgroundTest::SetUpOnMainThread() {}

// Returns the only running worker id for |extension_id|.
// Returns std::nullopt if there isn't any worker running or more than one
// worker is running for |extension_id|.
std::optional<WorkerId>
ServiceWorkerBasedBackgroundTest::GetUniqueRunningWorkerId(
    const ExtensionId& extension_id) {}

bool ServiceWorkerBasedBackgroundTest::ExtensionHasRenderProcessHost(
    const ExtensionId& extension_id) {}

class ServiceWorkerBasedBackgroundTestWithNotification
    : public ServiceWorkerBasedBackgroundTest {};

enum class ManifestVersion {};
class ServiceWorkerWithManifestVersionTest
    : public ServiceWorkerBasedBackgroundTest,
      public testing::WithParamInterface<ManifestVersion> {};

// Tests that Service Worker based background pages can be loaded and they can
// receive extension events.
// The extension is installed and loaded during this step and it registers
// an event listener for tabs.onCreated event. The step also verifies that tab
// creation correctly fires the listener.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, PRE_Basic) {}

// After browser restarts, this test step ensures that opening a tab fires
// tabs.onCreated event listener to the extension without explicitly loading the
// extension. This is because the extension registered a listener before browser
// restarted in PRE_Basic.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, Basic) {}

// Tests that an extension with a service worker script registered in non-root
// directory can successfully be registered.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, NonRootDirectory) {}

// Tests that a module service worker with static import can successfully be
// registered.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest,
                       ModuleServiceWorkerWithStaticImport) {}

// Tests that registering a module service worker with dynamic import fails.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest,
                       ModuleServiceWorkerWithDynamicImport) {}

// Tests a service worker registration that fails due to the worker script
// synchronously throwing a runtime error.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest,
                       ServiceWorkerWithRegistrationFailure) {}

// Tests that an error is generated if there is a syntax error in the service
// worker script.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, SyntaxError) {}

// Tests that an error is generated if there is an undefined variable in the
// service worker script.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, UndefinedVariable) {}

// Tests that an error is generated if console.error() is called from an
// extension's service worker.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, ConsoleError) {}

// Tests that an extension can fetch a file scheme URL from the service worker,
// if it has file access.
// TODO(crbug.com/40939961): Flaky on mac
#if BUILDFLAG(IS_MAC)
#define MAYBE_FetchFileSchemeURLWithFileAccess
#else
#define MAYBE_FetchFileSchemeURLWithFileAccess
#endif
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest,
                       MAYBE_FetchFileSchemeURLWithFileAccess) {}

// Tests that an extension can not fetch a file scheme URL from the service
// worker, if it does not have file access.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest,
                       FetchFileSchemeURLWithNoFileAccess) {}

// Tests chrome.runtime.onInstalled fires for extension service workers.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, OnInstalledEvent) {}

// Tests chrome.runtime.id and chrome.runtime.getURL().
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, RuntimeMisc) {}

// Tests chrome.app namespace is undefined for service worker-based extensions.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, ChromeAppUndefined) {}

// Tests chrome.storage APIs.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, StorageSetAndGet) {}

// Tests chrome.storage APIs are only enabled with permission.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, StorageNoPermissions) {}

// Tests chrome.tabs APIs.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, TabsBasic) {}

// Tests chrome.tabs events.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, TabsEvents) {}

// Tests chrome.tabs APIs.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, TabsExecuteScript) {}

// Tests chrome.windows APIs.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, WindowsBasic) {}

// Tests chrome.webRequest APIs.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, WebRequest) {}

// Tests more chrome.webRequest APIs. Any potentially flaky tests are isolated
// here.
// Flaky (crbug.com/1072715).
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, DISABLED_WebRequest2) {}

// Tests chrome.webRequest APIs in blocking mode.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, WebRequestBlocking) {}

// Tests chrome.webNavigation APIs.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, FilteredEvents) {}

// Listens for |message| from extension Service Worker early so that tests can
// wait for the message on startup (and not miss it).
template <const char message[]>
class ServiceWorkerWithEarlyMessageListenerTest
    : public ServiceWorkerBasedBackgroundTest {};

constexpr char kMsgOnStartup[] =;
ServiceWorkerOnStartupEventTest;

// Tests "runtime.onStartup" for extension SW.
IN_PROC_BROWSER_TEST_F(ServiceWorkerOnStartupEventTest, PRE_Event) {}

IN_PROC_BROWSER_TEST_F(ServiceWorkerOnStartupEventTest, Event) {}

constexpr char kMsgWorkerRunning[] =;
class ServiceWorkerRegistrationAtStartupTest
    : public ServiceWorkerWithEarlyMessageListenerTest<kMsgWorkerRunning> {};

// Disabled on Win due an unrelated bug: https://crbug.com/41491822.
#if BUILDFLAG(IS_WIN)
#define MAYBE_PRE_ExtensionActivationDoesNotReregister
#define MAYBE_ExtensionActivationDoesNotReregister
#else
#define MAYBE_PRE_ExtensionActivationDoesNotReregister
#define MAYBE_ExtensionActivationDoesNotReregister
#endif
// Tests that Service Worker registration for existing extension isn't issued
// upon browser restart.
// Regression test for https://crbug.com/889687.
IN_PROC_BROWSER_TEST_F(ServiceWorkerRegistrationAtStartupTest,
                       MAYBE_PRE_ExtensionActivationDoesNotReregister) {}

IN_PROC_BROWSER_TEST_F(ServiceWorkerRegistrationAtStartupTest,
                       MAYBE_ExtensionActivationDoesNotReregister) {}

// Class that dispatches an event to |extension_id| right after a
// non-lazy listener to the event is added from the extension's Service Worker.
class EarlyWorkerMessageSender : public EventRouter::Observer {};

// Tests that extension event dispatch works correctly right after extension
// installation registers its Service Worker.
// Regression test for: https://crbug.com/850792.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, EarlyEventDispatch) {}

// Tests that filtered events dispatches correctly right after a non-lazy
// listener is registered for that event (and before the corresponding lazy
// listener is registered).
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest,
                       EarlyFilteredEventDispatch) {}

class ServiceWorkerBackgroundSyncTest : public ServiceWorkerTest {};

class ServiceWorkerPushMessagingTest : public ServiceWorkerTest {};

class ServiceWorkerLazyBackgroundTest : public ServiceWorkerTest {};

IN_PROC_BROWSER_TEST_F(ServiceWorkerTest, RegisterSucceeds) {}

IN_PROC_BROWSER_TEST_F(ServiceWorkerTest, UpdateRefreshesServiceWorker) {}

IN_PROC_BROWSER_TEST_F(ServiceWorkerTest, UpdateWithoutSkipWaiting) {}

IN_PROC_BROWSER_TEST_F(ServiceWorkerTest, UpdateToMV3RefreshesServiceWorker) {}

IN_PROC_BROWSER_TEST_F(ServiceWorkerTest, FetchArbitraryPaths) {}

IN_PROC_BROWSER_TEST_F(ServiceWorkerTest,
                       FetchExtensionResourceFromServiceWorker) {}

// Tests that fetch() from service worker and network fallback
// go through webRequest.onBeforeRequest API.
IN_PROC_BROWSER_TEST_F(ServiceWorkerTest, OnBeforeRequest) {}

IN_PROC_BROWSER_TEST_F(ServiceWorkerTest, SWServedBackgroundPageReceivesEvent) {}

IN_PROC_BROWSER_TEST_F(ServiceWorkerTest, SWServedBackgroundPage) {}

IN_PROC_BROWSER_TEST_F(ServiceWorkerTest,
                       ServiceWorkerPostsMessageToBackgroundClient) {}

IN_PROC_BROWSER_TEST_F(ServiceWorkerTest,
                       BackgroundPagePostsMessageToServiceWorker) {}

IN_PROC_BROWSER_TEST_F(ServiceWorkerTest,
                       ServiceWorkerSuspensionOnExtensionUnload) {}

IN_PROC_BROWSER_TEST_F(ServiceWorkerTest, NotificationAPI) {}

IN_PROC_BROWSER_TEST_F(ServiceWorkerTest, WebAccessibleResourcesFetch) {}

// Tests that updating a packed extension with modified scripts works
// properly -- we expect that the new script will execute, rather than the
// previous one.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest,
                       UpdatePackedExtension) {}

// Tests that updating an unpacked extension with modified scripts works
// properly -- we expect that the new script will execute, rather than the
// previous one.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest,
                       UpdateUnpackedExtension) {}

// This test loads a web page that has an iframe pointing to a
// chrome-extension:// URL. The URL is listed in the extension's
// web_accessible_resources. Initially the iframe is served from the extension's
// resource file. After verifying that, we register a Service Worker that
// controls the extension. Further requests to the same resource as before
// should now be served by the Service Worker.
// This test also verifies that if the requested resource exists in the manifest
// but is not present in the extension directory, the Service Worker can still
// serve the resource file.
IN_PROC_BROWSER_TEST_F(ServiceWorkerTest, WebAccessibleResourcesIframeSrc) {}

// Verifies that service workers that aren't specified as the background script
// for the extension do not have extension API bindings.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, VerifyNoApiBindings) {}

IN_PROC_BROWSER_TEST_F(ServiceWorkerBackgroundSyncTest, Sync) {}

IN_PROC_BROWSER_TEST_F(ServiceWorkerTest,
                       FetchFromContentScriptShouldNotGoToServiceWorkerOfPage) {}

IN_PROC_BROWSER_TEST_F(ServiceWorkerPushMessagingTest, OnPush) {}

IN_PROC_BROWSER_TEST_F(ServiceWorkerTest, MimeHandlerView) {}

IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest,
                       EventsToStoppedWorker) {}

namespace {

constexpr char kIncognitoManifest[] =;

constexpr char kQueryWorkerScript[] =;

constexpr char kTabsOnUpdatedSplitScript[] =;

constexpr char kTabsOnUpdatedSpanningScript[] =;

}  // anonymous namespace

IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, TabsQuerySplit) {}

// Tests already-loaded extension activation in incognito profile.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest,
                       AlreadyLoadedSplitExtensionActivationInIncognito) {}

IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, TabsQuerySpanning) {}

IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, TabsOnUpdatedSplit) {}

// Test extension with OnInstalled listener can be successfully updated when,
// 1) Was allowed in incognito.
// 2) An incognito window was open.
// 3) Toggle the allow in incognito switch to off
// Regression test for crbug.com/1394588
// TODO(crbug.com/40282331): Disabled on ASAN due to leak caused by renderer gin
// objects which are intended to be leaked.
#if defined(ADDRESS_SANITIZER)
#define MAYBE_DisallowIncognitoWithOnInstalledListener
#else
#define MAYBE_DisallowIncognitoWithOnInstalledListener
#endif
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest,
                       MAYBE_DisallowIncognitoWithOnInstalledListener) {}

IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest,
                       TabsOnUpdatedSpanning) {}

// Tests the restriction on registering service worker scripts at root scope.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest,
                       ServiceWorkerScriptRootScope) {}

// Tests that a worker that failed to start due to 'install' error, clears its
// PendingTasks correctly. Also tests that subsequent tasks are properly
// cleared.
// Regression test for https://crbug.com/1019161.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest,
                       WorkerStartFailureClearsPendingTasks) {}

IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest,
                       ProcessManagerRegistrationOnShutdown) {}

IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest,
                       ProcessManagerRegistrationOnTerminate) {}

// Tests that worker ref count increments while extension API function is
// active.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, WorkerRefCount) {}

IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest,
                       PRE_EventsAfterRestart) {}

// After browser restarts, this test step ensures that opening a tab fires
// tabs.onCreated event listener to the extension without explicitly loading the
// extension. This is because the extension registered a listener for
// tabs.onMoved before browser restarted in PRE_EventsAfterRestart.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, EventsAfterRestart) {}

constexpr char kListenerAdded[] =;
ServiceWorkerWebRequestEarlyListenerTest;

IN_PROC_BROWSER_TEST_F(ServiceWorkerWebRequestEarlyListenerTest,
                       PRE_WebRequestAfterRestart) {}

// After browser restarts, this test step ensures that navigating a tab fires
// the webRequest listener.
IN_PROC_BROWSER_TEST_F(ServiceWorkerWebRequestEarlyListenerTest,
                       WebRequestAfterRestart) {}

// Disabled on win due to flakiness: https://crbug.com/1127126.
#if BUILDFLAG(IS_WIN)
#define MAYBE_PRE_FilteredEventsAfterRestart
#define MAYBE_FilteredEventsAfterRestart
#else
#define MAYBE_PRE_FilteredEventsAfterRestart
#define MAYBE_FilteredEventsAfterRestart
#endif
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest,
                       MAYBE_PRE_FilteredEventsAfterRestart) {}

// After browser restarts, this test step ensures that opening a tab fires
// tabs.onCreated event listener to the extension without explicitly loading the
// extension. This is because the extension registered a listener for
// tabs.onMoved before browser restarted in PRE_EventsAfterRestart.
//
// Disabled on win due to flakiness: https://crbug.com/1127126.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest,
                       MAYBE_FilteredEventsAfterRestart) {}

// Tests that chrome.browserAction.onClicked sees user gesture.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest,
                       BrowserActionUserGesture) {}

// Tests that Service Worker notification handlers can call extension APIs that
// require user gesture to be present.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTestWithNotification,
                       ServiceWorkerNotificationClick) {}

// Tests chrome.permissions.request API.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, PermissionsAPI) {}

// Tests that loading a component MV3 extension succeeds.
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, Component) {}

// Tests that two extensions with the same ServiceWorkerContext* can be
// disabled successfully. This test ensures that the DCHECK in
// ServiceWorkerTaskQueue::StopObserving does not fail in such a scenario.

// Regression test for https://crbug.com/1223476
IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest,
                       ObserveServiceWorkerContext) {}

constexpr char kReady[] =;
class ServiceWorkerTestWithEarlyReadyMesssage
    : public ServiceWorkerWithEarlyMessageListenerTest<kReady> {};

// Tests that missing SW registration is re-registered upon extension
// activation.
//
// In PRE_ test, extension is loaded and then its SW is unregistered. After
// browser restart, the tests verifies that the extension still runs after
// browser restart.
//
// Regression test for crbug.com/1271154.
IN_PROC_BROWSER_TEST_F(ServiceWorkerTestWithEarlyReadyMesssage,
                       PRE_MissingRegistrationMitigated) {}

IN_PROC_BROWSER_TEST_F(ServiceWorkerTestWithEarlyReadyMesssage,
                       MissingRegistrationMitigated) {}

// Tests that an extension's service worker can't be used to relax the extension
// CSP.
IN_PROC_BROWSER_TEST_P(ServiceWorkerWithManifestVersionTest,
                       ExtensionCSPModification) {}

INSTANTIATE_TEST_SUITE_P();

// Tests that console messages logged by extension service workers, both via
// the typical console.* methods and via our custom bindings console, are
// passed through the normal ServiceWorker console messaging and are
// observable.
IN_PROC_BROWSER_TEST_F(ServiceWorkerLazyBackgroundTest, ConsoleLogging) {}

class ServiceWorkerCheckBindingsTest
    : public ServiceWorkerTest,
      public testing::WithParamInterface<version_info::Channel> {};

// Load an extension in each allowed channel and check that the expected
// bindings are available.
IN_PROC_BROWSER_TEST_P(ServiceWorkerCheckBindingsTest, BindingsAvailability) {}

INSTANTIATE_TEST_SUITE_P();

}  // namespace extensions