chromium/chrome/browser/extensions/back_forward_cache_browsertest.cc

// Copyright 2021 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/public/browser/back_forward_cache.h"

#include <string>
#include <string_view>

#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "chrome/browser/extensions/extension_action_runner.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/extensions/tab_helper.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/back_forward_cache/back_forward_cache_disable.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_features.h"
#include "content/public/test/back_forward_cache_util.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/prerender_test_util.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/api/messaging/message_service.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest_constants.h"
#include "net/dns/mock_host_resolver.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h"
#include "third_party/blink/public/mojom/navigation/renderer_eviction_reason.mojom-shared.h"

namespace extensions {

ContextType;

struct TestParams {};

class ExtensionBackForwardCacheBrowserTest
    : public ExtensionBrowserTest,
      public ::testing::WithParamInterface<TestParams> {};

// These tests use chrome.tabs.executeScript, so the SW versions of the tests
// must still be run with MV2. See crbug.com/332328868.
INSTANTIATE_TEST_SUITE_P();
INSTANTIATE_TEST_SUITE_P();
INSTANTIATE_TEST_SUITE_P();
INSTANTIATE_TEST_SUITE_P();

IN_PROC_BROWSER_TEST_P(ExtensionBackForwardCacheBrowserTest, ScriptAllowed) {}

IN_PROC_BROWSER_TEST_P(ExtensionBackForwardCacheBrowserTest, CSSAllowed) {}

IN_PROC_BROWSER_TEST_P(ExtensionBackForwardCacheBrowserTest,
                       UnloadExtensionFlushCache) {}

IN_PROC_BROWSER_TEST_P(ExtensionBackForwardCacheBrowserTest,
                       LoadExtensionFlushCache) {}

// Test if the chrome.runtime.connect API is called, the page is prevented from
// entering bfcache.
IN_PROC_BROWSER_TEST_P(ExtensionBackForwardCacheBrowserTest,
                       ChromeRuntimeConnectUsage) {}

// Test that we correctly clear the bfcache disable reasons on a same-origin
// cross document navigation for a document with an active channel, allowing
// the frame to be bfcached subsequently.
IN_PROC_BROWSER_TEST_P(ExtensionBackForwardCacheBrowserTest,
                       ChromeRuntimeConnectUsageInIframeWithIframeNavigation) {}

// Test that the page can enter BFCache with an active channel created from the
// iframe.
IN_PROC_BROWSER_TEST_P(
    ExtensionBackForwardCacheBrowserTest,
    ChromeRuntimeConnectUsageInIframeWithoutIframeNavigation) {}

// Test that the page can enter BFCache with an active channel that's created
// from the extension background with two receivers from different frames.
IN_PROC_BROWSER_TEST_P(ExtensionBackForwardCacheBrowserTest,
                       ChromeTabsConnectWithMultipleReceivers) {}

// Test if the chrome.runtime.sendMessage API is called, the page is allowed
// to enter the bfcache.
IN_PROC_BROWSER_TEST_P(ExtensionBackForwardCacheBrowserTest,
                       ChromeRuntimeSendMessageUsage) {}

// Test if the chrome.runtime.connect is called then disconnected, the page is
// allowed to enter the bfcache.
IN_PROC_BROWSER_TEST_P(ExtensionBackForwardCacheBrowserTest,
                       ChromeRuntimeConnectDisconnect) {}

// Test if the chrome.tabs.connect is called and then the page is navigated,
// the page is allowed to enter the bfcache, but if the extension tries to send
// it a message the page will be evicted.
IN_PROC_BROWSER_TEST_P(ExtensionBackForwardCacheBrowserTest,
                       ChromeTabsConnect) {}

// Test that after caching and restoring a page, long-lived ports still work.
IN_PROC_BROWSER_TEST_P(ExtensionBackForwardCacheBrowserTest,
                       ChromeTabsConnectChannelWorksAfterRestore) {}

// Test if the chrome.tabs.connect is called then disconnected, the page is
// allowed to enter the bfcache.
IN_PROC_BROWSER_TEST_P(ExtensionBackForwardCacheBrowserTest,
                       ChromeTabsConnectDisconnect) {}

// Test that the extension background receives `disconnect` event if the
// channel is closed after the page enters BFCache when
// `DisconnectExtensionMessagePortWhenPageEntersBFCache` is enabled.
IN_PROC_BROWSER_TEST_P(ExtensionBackForwardCacheBrowserTest,
                       ExtensionBackgroundOnDisconnectEvent) {}

// Tests sending a message to all frames does not send it to back-forward
// cached frames.
IN_PROC_BROWSER_TEST_P(ExtensionBackForwardCacheBrowserTest,
                       MessageSentToAllFramesDoesNotSendToBackForwardCache) {}

// Tests sending a message to specific frame that is in the back forward cache
// fails.
IN_PROC_BROWSER_TEST_P(ExtensionBackForwardCacheBrowserTest,
                       MessageSentToCachedIdFails) {}

// Test that running extensions message dispatching via a ScriptContext::ForEach
// for back forward cached pages causes eviction of that RenderFrameHost.
IN_PROC_BROWSER_TEST_P(ExtensionBackForwardCacheBrowserTest,
                       StorageCallbackEvicts) {}

// Test that ensures the origin restriction declared on the extension
// manifest.json is properly respected even when BFCache is involved.
IN_PROC_BROWSER_TEST_P(ExtensionBackForwardCacheBrowserTest, TabsOrigin) {}

// Test that ensures the content scripts only execute once on a back/forward
// cached page.
IN_PROC_BROWSER_TEST_P(ExtensionBackForwardCacheBrowserTest,
                       ContentScriptsRunOnlyOnce) {}

// Test that an activeTab permission temporarily granted to an extension for a
// page does not revive when the BFCache entry is restored.
IN_PROC_BROWSER_TEST_P(ExtensionBackForwardCacheBrowserTest,
                       ActiveTabPermissionRevoked) {}

// This subclass adds some necessary setup for testing the BFCache metrics
// reported by the extensions.
class ExtensionBackForwardCacheMetricsBrowserTest
    : public ExtensionBackForwardCacheBrowserTest {};

INSTANTIATE_TEST_SUITE_P();
INSTANTIATE_TEST_SUITE_P();
INSTANTIATE_TEST_SUITE_P();
INSTANTIATE_TEST_SUITE_P();

namespace {

// Convert the given source and reason into metric value that is used for metric
// testing. This follows the implementation of
// `content::BackForwardCacheMetrics::MetricValue`.
// See the comments from `content::BackForwardCache::DisabledSource` also.
constexpr int ToBackForwardCacheDisabledReasonMetricValue(
    content::BackForwardCache::DisabledSource source,
    back_forward_cache::DisabledReasonId reason) {}

}  // namespace

// Test when `DisconnectExtensionMessagePortWhenPageEntersBFCache` is disabled,
// if the extension sends message to a cached document, the document is not
// allowed to enter the back/forward cache, and the
// `BackForwardCacheDisabledForRenderFrameHostReason` metric will be recorded
// for the document URL and the extension URL.
// It also tests the case when the same extension triggers the disabling twice
// in different navigations, the metrics should be recorded under different
// source ids.
IN_PROC_BROWSER_TEST_P(
    ExtensionBackForwardCacheMetricsBrowserTest,
    BFCacheMetricsRecordedIfExtensionSendsMessageToCachedFrame) {}

class ExtensionBackForwardCacheWithPrerenderBrowserTest
    : public ExtensionBackForwardCacheBrowserTest {};

INSTANTIATE_TEST_SUITE_P();
INSTANTIATE_TEST_SUITE_P();
INSTANTIATE_TEST_SUITE_P();
INSTANTIATE_TEST_SUITE_P();

// Test the extension message port created during prerendering won't be closed
// after the prerendered page is activated.
IN_PROC_BROWSER_TEST_P(ExtensionBackForwardCacheWithPrerenderBrowserTest,
                       PortIsStillOpenAfterPrerenderAndActivate) {}

}  // namespace extensions