blob: 515dec1c366c3ba73ba666793ee32cf971cee2fa [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2021 The Chromium Authors
Fergal Dalyf5a50ab2021-11-09 05:36:182// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CONTENT_BROWSER_BACK_FORWARD_CACHE_BROWSERTEST_H_
6#define CONTENT_BROWSER_BACK_FORWARD_CACHE_BROWSERTEST_H_
7
8#include <memory>
Arthur Sonzognic686e8f2024-01-11 08:36:379#include <optional>
Fergal Dalyf5a50ab2021-11-09 05:36:1810
Fergal Daly5495b0e2021-11-19 02:03:2811#include "base/compiler_specific.h"
Fergal Dalyf5a50ab2021-11-09 05:36:1812#include "base/feature_list.h"
13#include "base/hash/hash.h"
14#include "base/test/scoped_feature_list.h"
Fergal Daly432aa7c2022-06-14 07:30:5415#include "base/test/scoped_logging_settings.h"
Fergal Dalyf5a50ab2021-11-09 05:36:1816#include "components/ukm/test_ukm_recorder.h"
Ming-Ying Chungee9b9ea2022-08-15 08:24:2517#include "content/browser/back_forward_cache_test_util.h"
Fergal Dalyf5a50ab2021-11-09 05:36:1818#include "content/browser/renderer_host/page_lifecycle_state_manager.h"
19#include "content/browser/renderer_host/render_frame_host_impl.h"
20#include "content/browser/renderer_host/render_frame_host_manager.h"
21#include "content/public/browser/render_frame_host.h"
22#include "content/public/browser/web_contents_observer.h"
23#include "content/public/test/content_browser_test.h"
24#include "content/public/test/content_mock_cert_verifier.h"
25#include "content/test/content_browser_test_utils_internal.h"
Fergal Dalyf5a50ab2021-11-09 05:36:1826#include "testing/gmock/include/gmock/gmock.h"
Dave Tapuskaef8b1582024-10-23 21:49:3827#include "third_party/blink/public/mojom/back_forward_cache_not_restored_reasons.mojom.h"
Fergal Dalyf5a50ab2021-11-09 05:36:1828
29namespace content {
30
Yuzu Saijodcabe562022-04-25 06:06:3931using NotRestoredReasons =
32 BackForwardCacheCanStoreDocumentResult::NotRestoredReasons;
Yuzu Saijoc3478072022-03-24 06:15:2633using NotRestoredReason = BackForwardCacheMetrics::NotRestoredReason;
34
Fergal Daly25b51802022-11-28 06:01:2435using ReasonsMatcher = testing::Matcher<
36 const blink::mojom::BackForwardCacheNotRestoredReasonsPtr&>;
37using SameOriginMatcher = testing::Matcher<
38 const blink::mojom::SameOriginBfcacheNotRestoredDetailsPtr&>;
Kurumi Muto576c0a02024-02-08 04:17:3239using BlockingDetailsReasonsMatcher =
40 testing::Matcher<const blink::mojom::BFCacheBlockingDetailedReasonPtr&>;
Kurumi Muto0cf12802024-02-21 08:36:4241using SourceLocationMatcher =
42 testing::Matcher<const blink::mojom::ScriptSourceLocationPtr&>;
rubberyuzu15d29d32023-07-28 05:22:2443using BlockingDetailsMatcher =
44 testing::Matcher<const blink::mojom::BlockingDetailsPtr&>;
Fergal Daly25b51802022-11-28 06:01:2445
Fergal Dalyf5a50ab2021-11-09 05:36:1846// Match RenderFrameHostImpl* that are in the BackForwardCache.
47MATCHER(InBackForwardCache, "") {
48 return arg->IsInBackForwardCache();
49}
50
Takashi Toyoshimae40aa1e2022-03-30 08:32:1651// Match RenderFrameDeletedObserver* which observed deletion of the RenderFrame.
Fergal Dalyf5a50ab2021-11-09 05:36:1852MATCHER(Deleted, "") {
53 return arg->deleted();
54}
55
56// Helper function to pass an initializer list to the EXPECT_THAT macro. This is
57// indeed the identity function.
58std::initializer_list<RenderFrameHostImpl*> Elements(
59 std::initializer_list<RenderFrameHostImpl*> t);
60
Fergal Daly7e0c67bd2023-02-18 02:49:0361enum class TestFrameType {
62 kMainFrame,
63 kSubFrame,
64 kSubFrameOfSubframe,
65};
66
Fergal Dalyf5a50ab2021-11-09 05:36:1867// Test about the BackForwardCache.
Yuzu Saijoc3478072022-03-24 06:15:2668class BackForwardCacheBrowserTest
69 : public ContentBrowserTest,
70 public WebContentsObserver,
Ming-Ying Chungee9b9ea2022-08-15 08:24:2571 public BackForwardCacheMetrics::TestObserver,
72 public BackForwardCacheMetricsTestMatcher {
Fergal Dalyf5a50ab2021-11-09 05:36:1873 public:
74 BackForwardCacheBrowserTest();
75 ~BackForwardCacheBrowserTest() override;
76
Yuzu Saijoc3478072022-03-24 06:15:2677 // TestObserver:
78 void NotifyNotRestoredReasons(
79 std::unique_ptr<BackForwardCacheCanStoreTreeResult> tree_result) override;
80
Fergal Dalyf5a50ab2021-11-09 05:36:1881 protected:
Fergal Dalyf5a50ab2021-11-09 05:36:1882 void SetUpCommandLine(base::CommandLine* command_line) override;
83
84 void SetUpInProcessBrowserTestFixture() override;
85
86 void TearDownInProcessBrowserTestFixture() override;
87
88 void SetupFeaturesAndParameters();
89
Fergal Daly7e9b4caa2025-07-17 13:56:0990 // Enabled and disable only takes effect once per feature and each param can
91 // only be set once. This allows subclasses to set values and then call
92 // `SetUpCommandLine` and not have them overridden.
Daniel Chengc9ead4b2022-10-05 03:54:2993 void EnableFeatureAndSetParams(const base::Feature& feature,
Fergal Dalyf5a50ab2021-11-09 05:36:1894 std::string param_name,
95 std::string param_value);
Daniel Chengc9ead4b2022-10-05 03:54:2996 void DisableFeature(const base::Feature& feature);
Fergal Dalyb1258112025-07-15 03:00:5197 // Convenience method for setting up cache-sizes.
98 void EnableCacheSize(std::optional<int> cache_size,
99 std::optional<int> foreground_cache_size);
Fergal Dalyf5a50ab2021-11-09 05:36:18100
Fergal Dalyf5a50ab2021-11-09 05:36:18101 void SetUpOnMainThread() override;
102
103 void TearDownOnMainThread() override;
104
105 WebContentsImpl* web_contents() const;
106
107 RenderFrameHostImpl* current_frame_host();
108
109 RenderFrameHostManager* render_frame_host_manager();
110
111 std::string DepictFrameTree(FrameTreeNode* node);
112
Ramon Cano Aparicio6797d4e2025-01-10 16:09:02113 bool HistogramContainsIntValue(base::HistogramBase::Sample32 sample,
Fergal Dalyf5a50ab2021-11-09 05:36:18114 std::vector<base::Bucket> histogram_values);
115
Fergal Dalyf5a50ab2021-11-09 05:36:18116 void EvictByJavaScript(RenderFrameHostImpl* rfh);
117
118 void StartRecordingEvents(RenderFrameHostImpl* rfh);
119
120 void MatchEventList(RenderFrameHostImpl* rfh,
Matt Menke0500b4f42022-06-28 17:06:58121 base::Value list,
Fergal Dalyf5a50ab2021-11-09 05:36:18122 base::Location location = base::Location::Current());
123
124 // Creates a minimal HTTPS server, accessible through https_server().
125 // Returns a pointer to the server.
126 net::EmbeddedTestServer* CreateHttpsServer();
127
128 net::EmbeddedTestServer* https_server();
129
Fergal Dalyf5a50ab2021-11-09 05:36:18130 // Do not fail this test if a message from a renderer arrives at the browser
131 // for a cached page.
132 void DoNotFailForUnexpectedMessagesWhileCached();
133
134 // Navigates to a page at |page_url| with an img element with src set to
135 // "image.png".
136 RenderFrameHostImpl* NavigateToPageWithImage(const GURL& page_url);
137
138 void AcquireKeyboardLock(RenderFrameHostImpl* rfh);
139
140 void ReleaseKeyboardLock(RenderFrameHostImpl* rfh);
141
Fergal Daly7a05b4262022-03-15 09:18:40142 // Start a navigation to |url| but block it on an error. If |history_offset|
143 // is not 0, then the navigation will be a history navigation and this will
144 // assert that the URL after navigation is |url|.
145 void NavigateAndBlock(GURL url, int history_offset);
146
Yuzu Saijoc3478072022-03-24 06:15:26147 static testing::Matcher<BackForwardCacheCanStoreDocumentResult>
Yuzu Saijodcabe562022-04-25 06:06:39148 MatchesDocumentResult(testing::Matcher<NotRestoredReasons> not_stored,
Yuzu Saijoc3478072022-03-24 06:15:26149 BlockListedFeatures block_listed);
150
Yuzu Saijoe12e7ae2022-08-22 05:56:55151 ReasonsMatcher MatchesNotRestoredReasons(
Arthur Sonzognic686e8f2024-01-11 08:36:37152 const std::optional<testing::Matcher<std::string>>& id,
153 const std::optional<testing::Matcher<std::string>>& name,
154 const std::optional<testing::Matcher<std::string>>& src,
Kurumi Muto576c0a02024-02-08 04:17:32155 const std::vector<BlockingDetailsReasonsMatcher>& reasons,
Arthur Sonzognic686e8f2024-01-11 08:36:37156 const std::optional<SameOriginMatcher>& same_origin_details);
Kurumi Muto576c0a02024-02-08 04:17:32157
Yuzu Saijoe12e7ae2022-08-22 05:56:55158 SameOriginMatcher MatchesSameOriginDetails(
Luke Gu990c227b2024-03-07 00:36:38159 const testing::Matcher<GURL>& url,
Yuzu Saijoe12e7ae2022-08-22 05:56:55160 const std::vector<ReasonsMatcher>& children);
161
Kurumi Muto576c0a02024-02-08 04:17:32162 // Used in tests that ensure source location is sent to the renderer side from
163 // the browser one
164 BlockingDetailsReasonsMatcher MatchesDetailedReason(
165 const testing::Matcher<std::string>& name,
Kurumi Muto0cf12802024-02-21 08:36:42166 const std::optional<SourceLocationMatcher>& source);
Kurumi Muto576c0a02024-02-08 04:17:32167
168 // Used in tests that ensure source location is sent to the browser side from
169 // the renderer one.
rubberyuzu15d29d32023-07-28 05:22:24170 BlockingDetailsMatcher MatchesBlockingDetails(
Kurumi Muto0cf12802024-02-21 08:36:42171 const std::optional<SourceLocationMatcher>& source);
172
173 SourceLocationMatcher MatchesSourceLocation(
Luke Gud2d21b842024-03-19 09:49:41174 const testing::Matcher<GURL>& url,
Kurumi Muto0cf12802024-02-21 08:36:42175 const testing::Matcher<std::string>& function_name,
176 const testing::Matcher<uint64_t>& line_number,
177 const testing::Matcher<uint64_t>& column_number);
rubberyuzu15d29d32023-07-28 05:22:24178
Yuzu Saijoc3478072022-03-24 06:15:26179 // Access the tree result of NotRestoredReason for the last main frame
180 // navigation.
181 BackForwardCacheCanStoreTreeResult* GetTreeResult() {
182 return tree_result_.get();
183 }
184
Yuzu Saijo7b7b9a72022-04-20 05:12:08185 void InstallUnloadHandlerOnMainFrame();
186 void InstallUnloadHandlerOnSubFrame();
187 EvalJsResult GetUnloadRunCount();
188
Fergal Daly9909e092022-07-06 14:09:34189 // Adds a blocklisted feature to the document to prevent caching. Currently
190 // this means adding a plugin. We expect that plugins will never become
191 // cacheable, so this should be stable (at least until plugins cease to
192 // exist). If you need the feature to be sticky, then
193 // `RenderFrameHostImpl::UseDummyStickyBackForwardCacheDisablingFeatureForTesting`
194 // provides that.
195 [[nodiscard]] bool AddBlocklistedFeature(RenderFrameHost* rfh);
196 // Check that the document was not restored for the reason added by
197 // `AddBlocklistedFeature`.
198 void ExpectNotRestoredDueToBlocklistedFeature(base::Location location);
199
Ming-Ying Chunga8e8a2e2022-08-16 06:04:50200 const ukm::TestAutoSetUkmRecorder& ukm_recorder() override;
201 const base::HistogramTester& histogram_tester() override;
Fergal Dalyf5a50ab2021-11-09 05:36:18202
Fergal Dalyf5a50ab2021-11-09 05:36:18203 private:
Fergal Dalyf5a50ab2021-11-09 05:36:18204 content::ContentMockCertVerifier mock_cert_verifier_;
205
206 base::test::ScopedFeatureList feature_list_;
Fergal Daly432aa7c2022-06-14 07:30:54207 logging::ScopedVmoduleSwitches vmodule_switches_;
Fergal Dalyf5a50ab2021-11-09 05:36:18208
209 FrameTreeVisualizer visualizer_;
Fergal Dalyf5a50ab2021-11-09 05:36:18210 std::unique_ptr<net::EmbeddedTestServer> https_server_;
Daniel Chengc9ead4b2022-10-05 03:54:29211 std::map<base::test::FeatureRef, std::map<std::string, std::string>>
Fergal Dalyf5a50ab2021-11-09 05:36:18212 features_with_params_;
Daniel Chengccd5b412022-10-05 06:20:45213 std::vector<base::test::FeatureRef> disabled_features_;
Fergal Dalyf5a50ab2021-11-09 05:36:18214
Fergal Dalyf5a50ab2021-11-09 05:36:18215 std::unique_ptr<ukm::TestAutoSetUkmRecorder> ukm_recorder_;
Ming-Ying Chunga8e8a2e2022-08-16 06:04:50216 std::unique_ptr<base::HistogramTester> histogram_tester_;
Fergal Dalyf5a50ab2021-11-09 05:36:18217
Yuzu Saijoc3478072022-03-24 06:15:26218 // Store the tree result of NotRestoredReasons for the last main frame
219 // navigation.
220 std::unique_ptr<BackForwardCacheCanStoreTreeResult> tree_result_;
221
Fergal Dalyf5a50ab2021-11-09 05:36:18222 // Whether we should fail the test if a message arrived at the browser from a
223 // renderer for a bfcached page.
224 bool fail_for_unexpected_messages_while_cached_ = true;
Fergal Dalyf5a50ab2021-11-09 05:36:18225};
226
Fergal Daly973dc9e2021-11-19 09:38:17227class HighCacheSizeBackForwardCacheBrowserTest
228 : public BackForwardCacheBrowserTest {
229 protected:
230 void SetUpCommandLine(base::CommandLine* command_line) override;
231
232 // The number of pages the BackForwardCache can hold per tab.
233 // The number 5 was picked since Android ASAN trybot failed to keep more than
234 // 6 pages in memory.
235 const size_t kBackForwardCacheSize = 5;
236};
237
Fergal Daly97c4e592023-02-28 10:27:33238// Test that enables the BackForwardCacheAllowUnload flag.
239class BackForwardCacheUnloadBrowserTest : public BackForwardCacheBrowserTest {
240 public:
241 void SetUpCommandLine(base::CommandLine* command_line) override;
242
243 private:
244 base::test::ScopedFeatureList scoped_feature_list_;
245};
246
Hajime Hoshia12414a2021-12-08 08:21:23247// An implementation of PageLifecycleStateManager::TestDelegate for testing.
248class PageLifecycleStateManagerTestDelegate
249 : public PageLifecycleStateManager::TestDelegate {
250 public:
251 explicit PageLifecycleStateManagerTestDelegate(
252 PageLifecycleStateManager* manager);
253
254 ~PageLifecycleStateManagerTestDelegate() override;
255
256 // Waits for the renderer finishing to set the state of being in back/forward
257 // cache.
Fergal Daly52ba1e12022-10-20 07:53:00258 [[nodiscard]] bool WaitForInBackForwardCacheAck();
Hajime Hoshia12414a2021-12-08 08:21:23259
260 void OnStoreInBackForwardCacheSent(base::OnceClosure cb);
261 void OnDisableJsEvictionSent(base::OnceClosure cb);
262 void OnRestoreFromBackForwardCacheSent(base::OnceClosure cb);
263
264 private:
265 // PageLifecycleStateManager::TestDelegate:
266 void OnLastAcknowledgedStateChanged(
267 const blink::mojom::PageLifecycleState& old_state,
268 const blink::mojom::PageLifecycleState& new_state) override;
269 void OnUpdateSentToRenderer(
270 const blink::mojom::PageLifecycleState& new_state) override;
271 void OnDeleted() override;
272
Arthur Sonzogni4c9cdac2022-06-13 17:22:56273 raw_ptr<PageLifecycleStateManager, DanglingUntriaged> manager_;
Hajime Hoshia12414a2021-12-08 08:21:23274 base::OnceClosure store_in_back_forward_cache_sent_;
275 base::OnceClosure store_in_back_forward_cache_ack_received_;
276 base::OnceClosure restore_from_back_forward_cache_sent_;
277 base::OnceClosure disable_eviction_sent_;
278};
279
Fergal Daly19b904892023-10-31 06:04:35280// Gets the value of a key in local storage by evaluating JS. Use
281// `WaitForLocalStorage` if you are dealing with multiple renderer processes.
Fergal Daly2c7bc4052021-12-23 14:42:22282EvalJsResult GetLocalStorage(RenderFrameHostImpl* rfh, std::string key);
283
Fergal Daly19b904892023-10-31 06:04:35284// Because we are dealing with multiple renderer processes and the storage
285// service, we sometimes need to wait for the storage changes to show up the
286// renderer. See https://crbug.com/1494646.
287// Returns whether the expected value was found (so timeouts can be recognized).
288[[nodiscard]] bool WaitForLocalStorage(RenderFrameHostImpl* rfh,
289 std::string key,
290 std::string expected_value);
291
Fergal Dalyf5a50ab2021-11-09 05:36:18292} // namespace content
293
294#endif // CONTENT_BROWSER_BACK_FORWARD_CACHE_BROWSERTEST_H_