chromium/chrome/browser/dips/dips_bounce_detector_browsertest.cc

// Copyright 2022 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/dips/dips_bounce_detector.h"

#include <iterator>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <string_view>
#include <vector>

#include "base/base64.h"
#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/functional/bind.h"
#include "base/location.h"
#include "base/memory/raw_ptr.h"
#include "base/path_service.h"
#include "base/ranges/algorithm.h"
#include "base/run_loop.h"
#include "base/strings/escape.h"
#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/bind.h"
#include "base/test/gmock_expected_support.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_clock.h"
#include "base/test/test_future.h"
#include "base/test/test_timeouts.h"
#include "base/time/time.h"
#include "base/types/expected.h"
#include "chrome/browser/content_settings/cookie_settings_factory.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/dips/dips_redirect_info.h"
#include "chrome/browser/dips/dips_service.h"
#include "chrome/browser/dips/dips_storage.h"
#include "chrome/browser/dips/dips_test_utils.h"
#include "chrome/browser/dips/dips_utils.h"
#include "chrome/browser/privacy_sandbox/privacy_sandbox_settings_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/subresource_filter/subresource_filter_browser_test_harness.h"
#include "chrome/browser/tpcd/heuristics/opener_heuristic_tab_helper.h"
#include "chrome/browser/tpcd/heuristics/redirect_heuristic_tab_helper.h"
#include "chrome/common/chrome_features.h"
#include "chrome/test/base/chrome_test_utils.h"
#include "chrome/test/base/platform_browser_test.h"
#include "components/content_settings/common/content_settings_manager.mojom.h"
#include "components/content_settings/core/browser/cookie_settings.h"
#include "components/content_settings/core/common/features.h"
#include "components/content_settings/core/common/pref_names.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "components/prefs/pref_service.h"
#include "components/privacy_sandbox/privacy_sandbox_attestations/privacy_sandbox_attestations.h"
#include "components/privacy_sandbox/tracking_protection_prefs.h"
#include "components/subresource_filter/core/common/test_ruleset_utils.h"
#include "content/public/browser/attribution_data_model.h"
#include "content/public/browser/back_forward_cache.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/cookie_access_details.h"
#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/interest_group_manager.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/back_forward_cache_util.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/fenced_frame_test_util.h"
#include "content/public/test/prerender_test_util.h"
#include "content/public/test/test_devtools_protocol_client.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_status_code.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 "services/metrics/public/cpp/ukm_builders.h"
#include "services/network/public/cpp/features.h"
#include "services/network/test/trust_token_request_handler.h"
#include "services/network/test/trust_token_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/blink/public/common/switches.h"
#include "third_party/blink/public/mojom/frame/frame.mojom-shared.h"
#include "third_party/metrics_proto/ukm/source.pb.h"
#include "url/gurl.h"
#include "url/origin.h"

#if !BUILDFLAG(IS_ANDROID)
#include "chrome/browser/ssl/cert_verifier_browser_test.h"
#include "chrome/browser/ui/browser.h"
#include "content/public/browser/scoped_authenticator_environment_for_testing.h"
#include "device/fido/virtual_fido_device_factory.h"
#endif  // !BUILDFLAG(IS_ANDROID)

Bucket;
CookieAccessDetails;
NavigationHandle;
WebContents;
Contains;
ElementsAre;
Eq;
Gt;
IsEmpty;
Pair;
DIPS_Redirect;
AttributionData;

namespace {

StorageTypeAccessed;

// Returns a simplified URL representation for ease of comparison in tests.
// Just host+path.
std::string FormatURL(const GURL& url) {}

void AppendRedirect(std::vector<std::string>* redirects,
                    const DIPSRedirectInfo& redirect,
                    const DIPSRedirectChainInfo& chain,
                    size_t redirect_index) {}

void AppendRedirects(std::vector<std::string>* vec,
                     std::vector<DIPSRedirectInfoPtr> redirects,
                     DIPSRedirectChainInfoPtr chain) {}

void AppendSitesInReport(std::vector<std::string>* reports,
                         const std::set<std::string>& sites) {}

std::vector<url::Origin> GetOrigins(const AttributionData& data) {}

}  // namespace

// Keeps a log of DidStartNavigation, OnCookiesAccessed, and DidFinishNavigation
// executions.
class WCOCallbackLogger
    : public content::WebContentsObserver,
      public content::WebContentsUserData<WCOCallbackLogger>,
      public content::SharedWorkerService::Observer,
      public content::DedicatedWorkerService::Observer {};

WCOCallbackLogger::WCOCallbackLogger(content::WebContents* web_contents)
    :{}

void WCOCallbackLogger::DidStartNavigation(
    NavigationHandle* navigation_handle) {}

void WCOCallbackLogger::OnCookiesAccessed(
    content::RenderFrameHost* render_frame_host,
    const content::CookieAccessDetails& details) {}

void WCOCallbackLogger::OnCookiesAccessed(
    NavigationHandle* navigation_handle,
    const content::CookieAccessDetails& details) {}

void WCOCallbackLogger::OnServiceWorkerAccessed(
    content::RenderFrameHost* render_frame_host,
    const GURL& scope,
    content::AllowServiceWorkerResult allowed) {}

void WCOCallbackLogger::OnServiceWorkerAccessed(
    content::NavigationHandle* navigation_handle,
    const GURL& scope,
    content::AllowServiceWorkerResult allowed) {}

void WCOCallbackLogger::OnClientAdded(
    const blink::SharedWorkerToken& token,
    content::GlobalRenderFrameHostId render_frame_host_id) {}

void WCOCallbackLogger::OnWorkerCreated(
    const blink::DedicatedWorkerToken& worker_token,
    int worker_process_id,
    const url::Origin& security_origin,
    content::DedicatedWorkerCreator creator) {}

void WCOCallbackLogger::DidFinishNavigation(
    NavigationHandle* navigation_handle) {}

void WCOCallbackLogger::WebAuthnAssertionRequestSucceeded(
    content::RenderFrameHost* render_frame_host) {}

void WCOCallbackLogger::NotifyStorageAccessed(
    content::RenderFrameHost* render_frame_host,
    StorageTypeAccessed storage_type,
    bool blocked) {}

WEB_CONTENTS_USER_DATA_KEY_IMPL(WCOCallbackLogger);

class DIPSBounceDetectorBrowserTest
    : public subresource_filter::SubresourceFilterBrowserTest {};

IN_PROC_BROWSER_TEST_F(
    DIPSBounceDetectorBrowserTest,
    // TODO(crbug.com/40924446): Re-enable this test
    DISABLED_AttributeSameSiteIframesCookieClientAccessTo1P) {}

// TODO(crbug.com/40276415): Flaky on Mac.
#if BUILDFLAG(IS_MAC)
#define MAYBE_AttributeSameSiteIframesCookieServerAccessTo1P
#else
#define MAYBE_AttributeSameSiteIframesCookieServerAccessTo1P
#endif
IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
                       MAYBE_AttributeSameSiteIframesCookieServerAccessTo1P) {}

IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
                       Attribute3PIframesCHIPSClientAccessTo1P) {}

IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
                       // TODO(crbug.com/40287072): Re-enable this test
                       DISABLED_Attribute3PIframesCHIPSServerAccessTo1P) {}

IN_PROC_BROWSER_TEST_F(
    DIPSBounceDetectorBrowserTest,
    // TODO(crbug.com/40287072): Re-enable this test
    DISABLED_AttributeSameSiteNestedIframesCookieClientAccessTo1P) {}

IN_PROC_BROWSER_TEST_F(
    DIPSBounceDetectorBrowserTest,
    // TODO(crbug.com/40287072): Re-enable this test
    DISABLED_AttributeSameSiteNestedIframesCookieServerAccessTo1P) {}

IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
                       Attribute3PNestedIframesCHIPSClientAccessTo1P) {}

IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
                       Attribute3PNestedIframesCHIPSServerAccessTo1P) {}

IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
                       Attribute3PSubResourceCHIPSClientAccessTo1P) {}

IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
                       DiscardFencedFrameCookieClientAccess) {}

IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
                       DiscardFencedFrameCookieServerAccess) {}

// TODO(crbug.com/40917101): Flaky on Mac.
#if BUILDFLAG(IS_MAC)
#define MAYBE_DiscardPrerenderedPageCookieClientAccess
#else
#define MAYBE_DiscardPrerenderedPageCookieClientAccess
#endif
IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
                       MAYBE_DiscardPrerenderedPageCookieClientAccess) {}

// TODO(crrev/1448453): flaky test.
IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
                       DISABLED_DiscardPrerenderedPageCookieServerAccess) {}

IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
                       DetectStatefulBounce_ClientRedirect_SiteDataAccess) {}

// The timing of WCO::OnCookiesAccessed() execution is unpredictable for
// redirects. Sometimes it's called before WCO::DidRedirectNavigation(), and
// sometimes after. Therefore DIPSBounceDetector needs to know when it's safe to
// judge an HTTP redirect as stateful (accessing cookies) or not. This test
// tries to verify that OnCookiesAccessed() is always called before
// DidFinishNavigation(), so that DIPSBounceDetector can safely perform that
// judgement in DidFinishNavigation().
//
// This test also verifies that OnCookiesAccessed() is called for URLs in the
// same order that they're visited (and that for redirects that both read and
// write cookies, OnCookiesAccessed() is called with kRead before it's called
// with kChange, although DIPSBounceDetector doesn't depend on that anymore.)
//
// If either assumption is incorrect, this test will be flaky. On 2022-04-27 I
// (rtarpine) ran this test 1000 times in 40 parallel jobs with no failures, so
// it seems robust.
IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
                       AllCookieCallbacksBeforeNavigationFinished) {}

// An EmbeddedTestServer request handler for
// /cross-site-with-samesite-none-cookie URLs. Like /cross-site-with-cookie, but
// the cookie has additional Secure and SameSite=None attributes.
std::unique_ptr<net::test_server::HttpResponse>
HandleCrossSiteSameSiteNoneCookieRedirect(
    net::EmbeddedTestServer* server,
    const net::test_server::HttpRequest& request) {}

// Ignore iframes because their state will be partitioned under the top-level
// site anyway.
IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
                       IgnoreServerRedirectsInIframes) {}

// This test verifies that sites in a redirect chain with previous user
// interaction are not reported in the resulting issue when a navigation
// finishes.
IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
                       ReportRedirectorsInChain_OmitSitesWithInteraction) {}

// This test verifies that a third-party cookie access doesn't cause a client
// bounce to be considered stateful.
IN_PROC_BROWSER_TEST_F(
    DIPSBounceDetectorBrowserTest,
    DetectStatefulRedirect_Client_IgnoreThirdPartySubresource) {}

// This test verifies that a same-site cookie access DOES cause a client
// bounce to be considered stateful.
IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
                       DetectStatefulRedirect_Client_FirstPartySubresource) {}

// This test verifies that consecutive redirect chains are combined into one.
IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
                       DetectStatefulRedirect_ServerClientClientServer) {}

IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
                       DetectStatefulRedirect_ClosingTabEndsChain) {}

// Verifies server redirects that occur while opening a link in a new tab are
// properly detected.
// TODO(crbug.com/40936579): Flaky on Chrome OS and Linux.
#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
#define MAYBE_OpenServerRedirectURLInNewTab
#else
#define MAYBE_OpenServerRedirectURLInNewTab
#endif
IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
                       MAYBE_OpenServerRedirectURLInNewTab) {}

// Verifies client redirects that occur while opening a link in a new tab are
// properly detected.
IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
                       OpenClientRedirectURLInNewTab) {}

// Verifies the start URL of a redirect chain started by opening a link in a new
// tab is handled correctly, when that start page has an opaque origin.
IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
                       OpenRedirectURLInNewTab_OpaqueOriginInitiator) {}

class RedirectHeuristicBrowserTest : public PlatformBrowserTest {};

// Tests the conditions for recording RedirectHeuristic_CookieAccess2 and
// RedirectHeuristic_CookieAccessThirdParty2 UKM events.
IN_PROC_BROWSER_TEST_F(RedirectHeuristicBrowserTest,
                       RecordsRedirectHeuristicCookieAccessEvent) {}

// Tests setting different metrics for the RedirectHeuristic_CookieAccess2 UKM
// event.
// TODO(crbug.com/40934961): Flaky on multiple platforms.
IN_PROC_BROWSER_TEST_F(RedirectHeuristicBrowserTest,
                       DISABLED_RedirectHeuristicCookieAccessEvent_AllMetrics) {}

struct RedirectHeuristicFlags {};

// chrome/browser/ui/browser.h (for changing profile prefs) is not available on
// Android.
#if !BUILDFLAG(IS_ANDROID)
class RedirectHeuristicGrantTest
    : public RedirectHeuristicBrowserTest,
      public testing::WithParamInterface<RedirectHeuristicFlags> {};

IN_PROC_BROWSER_TEST_P(RedirectHeuristicGrantTest,
                       CreatesRedirectHeuristicGrantsWithSatisfyingURL) {}

IN_PROC_BROWSER_TEST_P(
    RedirectHeuristicGrantTest,
    CreatesRedirectHeuristicGrantsWithPartiallySatisfyingURL) {}

const RedirectHeuristicFlags kRedirectHeuristicTestCases[] =;

INSTANTIATE_TEST_SUITE_P();
#endif  // !BUILDFLAG(IS_ANDROID)

class DIPSBounceTrackingDevToolsIssueTest
    : public content::TestDevToolsProtocolClient,
      public DIPSBounceDetectorBrowserTest {};

IN_PROC_BROWSER_TEST_F(DIPSBounceTrackingDevToolsIssueTest,
                       BounceTrackingDevToolsIssue) {}

class DIPSSiteDataAccessDetectorTest
    : public DIPSBounceDetectorBrowserTest,
      public testing::WithParamInterface<StorageTypeAccessed> {};

IN_PROC_BROWSER_TEST_P(DIPSSiteDataAccessDetectorTest,
                       DetectSiteDataAccess_Storages) {}

IN_PROC_BROWSER_TEST_P(DIPSSiteDataAccessDetectorTest,
                       AttributeSameSiteIframesSiteDataAccessTo1P) {}

IN_PROC_BROWSER_TEST_P(DIPSSiteDataAccessDetectorTest,
                       AttributeSameSiteNestedIframesSiteDataAccessTo1P) {}

IN_PROC_BROWSER_TEST_P(DIPSSiteDataAccessDetectorTest,
                       DiscardFencedFrameCookieClientAccess) {}

IN_PROC_BROWSER_TEST_P(DIPSSiteDataAccessDetectorTest,
                       DiscardPrerenderedPageCookieClientAccess) {}

// WeLocks accesses aren't monitored by the `PageSpecificContentSettings` as
// they are not persistent.
// TODO(crbug.com/40269763): Remove `StorageTypeAccessed::kFileSystem` once
// deprecation is complete.
INSTANTIATE_TEST_SUITE_P();

// WebAuthn tests do not work on Android because there is no current way to
// install a virtual authenticator.
// NOTE: Manual testing was performed to ensure this implementation works as
// expected on Android platform.
// TODO(crbug.com/40269763): Implement automated testing once the infrastructure
// permits it (Requires mocking the Android Platform Authenticator i.e. GMS
// Core).
#if !BUILDFLAG(IS_ANDROID)
// Some refs for this test fixture:
// clang-format off
// - https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/webauthn/chrome_webauthn_browsertest.cc;drc=c4061a03f240338b42a5b84c98b1a11b62a97a9a
// - https://source.chromium.org/chromium/chromium/src/+/main:content/browser/webauth/webauth_browsertest.cc;drc=e8e4ad9096841fae7c55cea1b7d278c58f6160ff
// - https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/payments/secure_payment_confirmation_authenticator_browsertest.cc;drc=edea5c45c08d151afe67276f08a2ee13814563e1
// clang-format on
class DIPSWebAuthnBrowserTest : public CertVerifierBrowserTest {};

IN_PROC_BROWSER_TEST_F(DIPSWebAuthnBrowserTest,
                       WebAuthnAssertion_ConfirmWCOCallback) {}

// This test verifies that sites in a redirect chain with previous web authn
// assertions are not reported in the resulting issue when a navigation
// finishes.
IN_PROC_BROWSER_TEST_F(
    DIPSWebAuthnBrowserTest,
    ReportRedirectorsInChain_OmitSitesWithWebAuthnAssertions) {}
#endif  // !BUILDFLAG(IS_ANDROID)

// Verifies that a successfully registered service worker is tracked as a
// storage access.
IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
                       ServiceWorkerAccess_Storages) {}

// TODO(crbug.com/40290702): Shared workers are not available on Android.
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_SharedWorkerAccess_Storages
#else
#define MAYBE_SharedWorkerAccess_Storages
#endif
// Verifies that adding a shared worker to a frame is tracked as a storage
// access.
IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
                       MAYBE_SharedWorkerAccess_Storages) {}

// Verifies that adding a dedicated worker to a frame is tracked as a storage
// access.
IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
                       DedicatedWorkerAccess_Storages) {}

// Tests that currently only work consistently when the trigger is (any) bounce.
// TODO(crbug.com/336161248) Make these tests use stateful bounces.
class DIPSBounceTriggerBrowserTest : public DIPSBounceDetectorBrowserTest {};

// Verifies that a HTTP 204 (No Content) response is treated like a bounce.
IN_PROC_BROWSER_TEST_F(DIPSBounceTriggerBrowserTest, NoContent) {}

class DIPSThrottlingBrowserTest : public DIPSBounceDetectorBrowserTest {};

IN_PROC_BROWSER_TEST_F(DIPSThrottlingBrowserTest,
                       InteractionRecording_Throttled) {}

IN_PROC_BROWSER_TEST_F(DIPSThrottlingBrowserTest,
                       InteractionRecording_NotThrottled_AfterRefresh) {}

// TODO(b/325196134): Re-enable the test.
IN_PROC_BROWSER_TEST_F(DIPSThrottlingBrowserTest,
                       DISABLED_StorageRecording_Throttled) {}

// TODO(b/325196134): Re-enable the test.
IN_PROC_BROWSER_TEST_F(DIPSThrottlingBrowserTest,
                       DISABLED_StorageRecording_NotThrottled_AfterRefresh) {}

class AllSitesFollowingFirstPartyTest : public PlatformBrowserTest {};

IN_PROC_BROWSER_TEST_F(AllSitesFollowingFirstPartyTest,
                       SiteFollowingFirstPartyIncluded) {}

IN_PROC_BROWSER_TEST_F(AllSitesFollowingFirstPartyTest,
                       SiteNotFollowingFirstPartyNotIncluded) {}

IN_PROC_BROWSER_TEST_F(AllSitesFollowingFirstPartyTest, MultipleSitesIncluded) {}

IN_PROC_BROWSER_TEST_F(AllSitesFollowingFirstPartyTest,
                       NoFirstParty_NothingIncluded) {}

IN_PROC_BROWSER_TEST_F(AllSitesFollowingFirstPartyTest,
                       NothingAfterFirstParty_NothingIncluded) {}

class DIPSPrivacySandboxApiInteractionTest : public PlatformBrowserTest {};

// Verify that accessing storage via the PAT Protected Audience API doesn't
// trigger DIPS deletion for the accessing site.
IN_PROC_BROWSER_TEST_F(DIPSPrivacySandboxApiInteractionTest,
                       DontTriggerDeletionOnProtectedAudienceApiStorageAccess) {}

// Verify that accessing storage via the PAT Attribution Reporting API doesn't
// trigger DIPS deletion for the accessing site.
IN_PROC_BROWSER_TEST_F(
    DIPSPrivacySandboxApiInteractionTest,
    DontTriggerDeletionOnAttributionReportingApiStorageAccess) {}

// Verify that accessing storage via the PAT Private State Tokens API doesn't
// trigger DIPS deletion for the accessing site.
IN_PROC_BROWSER_TEST_F(
    DIPSPrivacySandboxApiInteractionTest,
    DontTriggerDeletionOnPrivateStateTokensApiStorageAccess) {}

// Verify that accessing storage via the PAT Topics API doesn't trigger DIPS
// deletion for the accessing site.
IN_PROC_BROWSER_TEST_F(DIPSPrivacySandboxApiInteractionTest,
                       DontTriggerDeletionOnTopicsApiStorageAccess) {}

class DIPSPrivacySandboxDataPreservationTest
    : public DIPSPrivacySandboxApiInteractionTest,
      public testing::WithParamInterface<bool> {};

IN_PROC_BROWSER_TEST_P(DIPSPrivacySandboxDataPreservationTest,
                       DontClearAttributionReportingApiData) {}

INSTANTIATE_TEST_SUITE_P();

namespace {

class SiteStorage {};

class CookieStorage : public SiteStorage {};

class LocalStorage : public SiteStorage {};

void PrintTo(const SiteStorage* storage, std::ostream* os) {}

static constexpr CookieStorage kCookieStorage;
static constexpr LocalStorage kLocalStorage;
}  // namespace

class DIPSDataDeletionBrowserTest
    : public DIPSBounceDetectorBrowserTest,
      public testing::WithParamInterface<const SiteStorage*> {};

IN_PROC_BROWSER_TEST_P(DIPSDataDeletionBrowserTest, DeleteDomain) {}

IN_PROC_BROWSER_TEST_P(DIPSDataDeletionBrowserTest, DontDeleteOtherDomains) {}

IN_PROC_BROWSER_TEST_P(DIPSDataDeletionBrowserTest,
                       DontDeleteDomainWhenPartitioned) {}

IN_PROC_BROWSER_TEST_P(DIPSDataDeletionBrowserTest, DeleteSubdomains) {}

IN_PROC_BROWSER_TEST_P(DIPSDataDeletionBrowserTest, DeleteEmbedded3Ps) {}

IN_PROC_BROWSER_TEST_P(DIPSDataDeletionBrowserTest,
                       DeleteEmbedded3Ps_Subdomain) {}

INSTANTIATE_TEST_SUITE_P();

class DIPSBounceDetectorBFCacheTest : public DIPSBounceDetectorBrowserTest,
                                      public testing::WithParamInterface<bool> {};

// Confirm that DIPS records a bounce that writes a cookie as stateful, even if
// the user immediately navigates away.
IN_PROC_BROWSER_TEST_P(DIPSBounceDetectorBFCacheTest, LateCookieAccessTest) {}

// Confirm that DIPS records a bounce that writes a cookie as stateful, even if
// the chain ends immediately afterwards.
IN_PROC_BROWSER_TEST_P(DIPSBounceDetectorBFCacheTest, QuickEndChainTest) {}

// Confirm that WCO::OnCookiesAccessed() is always called even if the user
// immediately navigates away.
IN_PROC_BROWSER_TEST_P(DIPSBounceDetectorBFCacheTest, CookieAccessReported) {}

// Confirm that DIPS records an interaction, even if the user immediately
// navigates away.
IN_PROC_BROWSER_TEST_P(DIPSBounceDetectorBFCacheTest, LateInteractionTest) {}

IN_PROC_BROWSER_TEST_P(DIPSBounceDetectorBFCacheTest, IsOrWasInPrimaryPage) {}

// For waiting until prerendering starts.
class PrerenderingObserver : public content::WebContentsObserver {};

void PrerenderingObserver::RenderFrameCreated(
    content::RenderFrameHost* render_frame_host) {}

// Confirm that IsOrWasInPrimaryPage() returns false for prerendered pages that
// are never activated.
IN_PROC_BROWSER_TEST_P(DIPSBounceDetectorBFCacheTest,
                       PrerenderedPagesAreNotPrimary) {}

// Confirm that IsOrWasInPrimaryPage() returns true for prerendered pages that
// get activated.
IN_PROC_BROWSER_TEST_P(DIPSBounceDetectorBFCacheTest,
                       PrerenderedPagesCanBecomePrimary) {}

INSTANTIATE_TEST_SUITE_P();