blob: 70266037f98fa0f0e51af49c7affc8bf05297d91 [file] [log] [blame]
clamy71a42ec2014-10-02 18:43:221// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
danakjc492bf82020-09-09 20:02:445#include "content/browser/renderer_host/navigator.h"
arthursonzognia2754522019-07-03 18:25:366
avib7348942015-12-25 20:57:107#include <stdint.h>
8
toyoshim7ae0fd52016-07-08 09:29:509#include "base/feature_list.h"
Avi Drissman9d3ded92018-12-25 20:50:2110#include "base/stl_util.h"
Todd Sahlb2f798302021-01-21 16:32:0711#include "base/test/test_simple_task_runner.h"
clamy71a42ec2014-10-02 18:43:2212#include "base/time/time.h"
avib7348942015-12-25 20:57:1013#include "build/build_config.h"
danakjc492bf82020-09-09 20:02:4414#include "content/browser/renderer_host/navigation_controller_impl.h"
15#include "content/browser/renderer_host/navigation_entry_impl.h"
16#include "content/browser/renderer_host/navigation_request.h"
17#include "content/browser/renderer_host/navigation_request_info.h"
18#include "content/browser/renderer_host/navigator.h"
19#include "content/browser/renderer_host/render_frame_host_manager.h"
clamy71a42ec2014-10-02 18:43:2220#include "content/browser/site_instance_impl.h"
[email protected]ee8ae332020-01-29 03:49:4521#include "content/common/content_navigation_policy.h"
Ken Rockot48785452017-10-25 19:33:1422#include "content/common/frame.mojom.h"
clamy0ab288e2015-02-05 17:39:1423#include "content/common/frame_messages.h"
clamy71a42ec2014-10-02 18:43:2224#include "content/common/navigation_params.h"
Aaron Colwellf45e3a852019-06-06 00:48:2725#include "content/public/browser/child_process_security_policy.h"
toyoshim7ae0fd52016-07-08 09:29:5026#include "content/public/common/content_features.h"
clamy71a42ec2014-10-02 18:43:2227#include "content/public/common/url_constants.h"
28#include "content/public/common/url_utils.h"
carlosk39337112015-01-14 21:44:5129#include "content/public/test/mock_render_process_host.h"
arthursonzogni63aa3f372017-08-09 14:28:3930#include "content/public/test/navigation_simulator.h"
Todd Sahlb2f798302021-01-21 16:32:0731#include "content/public/test/test_navigation_throttle_inserter.h"
carlosk15fb0f02015-07-29 17:07:5132#include "content/public/test/test_utils.h"
Arthur Hemery4aa413c42019-01-14 18:53:3033#include "content/test/navigation_simulator_impl.h"
Todd Sahlb2f798302021-01-21 16:32:0734#include "content/test/task_runner_deferring_throttle.h"
clamy72c72792014-11-18 18:09:4635#include "content/test/test_navigation_url_loader.h"
clamy71a42ec2014-10-02 18:43:2236#include "content/test/test_render_frame_host.h"
37#include "content/test/test_web_contents.h"
38#include "net/base/load_flags.h"
davidben8b339132014-10-08 02:27:0139#include "net/http/http_response_headers.h"
davidben6b77cd72014-10-29 21:13:4540#include "net/url_request/redirect_info.h"
clamy71a42ec2014-10-02 18:43:2241#include "ui/base/page_transition_types.h"
davidben61814fd2014-10-15 19:45:0742#include "url/url_constants.h"
clamy71a42ec2014-10-02 18:43:2243
44namespace content {
45
Aaron Colwell5fb878042020-12-17 19:48:4446namespace {
47
48// Helper function that determines if a test should expect a cross-site
49// navigation to trigger a SiteInstance change based on the current process
50// model.
51bool ExpectSiteInstanceChange(SiteInstanceImpl* site_instance) {
52 return AreAllSitesIsolatedForTesting() ||
53 CanCrossSiteNavigationsProactivelySwapBrowsingInstances() ||
54 !site_instance->IsDefaultSiteInstance();
55}
56
57} // namespace
58
Camille Lamy07c49cdf2019-03-11 15:53:5759class NavigatorTest : public RenderViewHostImplTestHarness {
davidben6b77cd72014-10-29 21:13:4560 public:
nickd5bbd0b2016-03-31 19:52:4461 using SiteInstanceDescriptor = RenderFrameHostManager::SiteInstanceDescriptor;
62 using SiteInstanceRelation = RenderFrameHostManager::SiteInstanceRelation;
carlosk078298a82015-04-07 10:33:2063
Aran Gilman37d11632019-10-08 23:07:1564 void SetUp() override { RenderViewHostImplTestHarness::SetUp(); }
davidben6b77cd72014-10-29 21:13:4565
Aran Gilman37d11632019-10-08 23:07:1566 void TearDown() override { RenderViewHostImplTestHarness::TearDown(); }
kenrb99afb082015-06-02 13:35:5867
davidben6b77cd72014-10-29 21:13:4568 TestNavigationURLLoader* GetLoaderForNavigationRequest(
69 NavigationRequest* request) const {
70 return static_cast<TestNavigationURLLoader*>(request->loader_for_testing());
71 }
72
carlosk39337112015-01-14 21:44:5173 TestRenderFrameHost* GetSpeculativeRenderFrameHost(FrameTreeNode* node) {
74 return static_cast<TestRenderFrameHost*>(
75 node->render_manager()->speculative_render_frame_host_.get());
76 }
77
Aaron Colwell91e32b12021-02-17 01:40:5678 scoped_refptr<SiteInstanceImpl> ConvertToSiteInstance(
dchengbccd6b82016-03-30 16:24:1979 RenderFrameHostManager* rfhm,
80 const SiteInstanceDescriptor& descriptor,
81 SiteInstance* candidate_instance) {
Aaron Colwell91e32b12021-02-17 01:40:5682 return static_cast<SiteInstanceImpl*>(
83 rfhm->ConvertToSiteInstance(
84 descriptor, static_cast<SiteInstanceImpl*>(candidate_instance),
85 false /* is_speculative */)
86 .get());
87 }
88
89 SiteInfo CreateExpectedSiteInfo(const GURL& url) {
90 return SiteInfo::CreateForTesting(IsolationContext(browser_context()), url);
carlosk078298a82015-04-07 10:33:2091 }
clamy71a42ec2014-10-02 18:43:2292};
93
Arthur Hemery859f3462019-01-29 16:29:0794// Tests a complete browser-initiated navigation starting with a non-live
95// renderer.
Camille Lamy07c49cdf2019-03-11 15:53:5796TEST_F(NavigatorTest, SimpleBrowserInitiatedNavigationFromNonLiveRenderer) {
carlosk39337112015-01-14 21:44:5197 const GURL kUrl("http://chromium.org/");
carloske24d11782015-02-13 10:10:0298
99 EXPECT_FALSE(main_test_rfh()->IsRenderFrameLive());
100
101 // Start a browser-initiated navigation.
Arthur Hemery859f3462019-01-29 16:29:07102 auto navigation =
103 NavigationSimulator::CreateBrowserInitiated(kUrl, contents());
avib7348942015-12-25 20:57:10104 int32_t site_instance_id = main_test_rfh()->GetSiteInstance()->GetId();
carloske24d11782015-02-13 10:10:02105 FrameTreeNode* node = main_test_rfh()->frame_tree_node();
Arthur Hemery859f3462019-01-29 16:29:07106 navigation->Start();
clamydcb434c12015-04-16 19:29:16107 NavigationRequest* request = node->navigation_request();
carloske24d11782015-02-13 10:10:02108 ASSERT_TRUE(request);
109 EXPECT_EQ(kUrl, request->common_params().url);
110 EXPECT_TRUE(request->browser_initiated());
111
112 // As there's no live renderer the navigation should not wait for a
Antonio Gomes8678a202020-03-02 20:03:25113 // beforeUnload completion callback being invoked by the renderer and
114 // start right away.
Mohamed Abdelhalimccd149af2019-10-31 14:48:53115 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, request->state());
carloske24d11782015-02-13 10:10:02116 ASSERT_TRUE(GetLoaderForNavigationRequest(request));
117 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
carloske24d11782015-02-13 10:10:02118
Arthur Hemery859f3462019-01-29 16:29:07119 navigation->ReadyToCommit();
clamyefdb7a42015-07-01 16:55:47120 EXPECT_TRUE(main_test_rfh()->is_loading());
121 EXPECT_FALSE(node->navigation_request());
carloske24d11782015-02-13 10:10:02122
123 // Commit the navigation.
Arthur Hemery859f3462019-01-29 16:29:07124 navigation->Commit();
Sreeja Kamishettye25ac752020-05-12 18:15:48125 EXPECT_TRUE(main_test_rfh()->IsCurrent());
126 EXPECT_EQ(main_test_rfh()->lifecycle_state(),
127 RenderFrameHostImpl::LifecycleState::kActive);
Aaron Colwelle953e562019-07-24 16:47:36128 if (AreDefaultSiteInstancesEnabled()) {
129 EXPECT_TRUE(main_test_rfh()->GetSiteInstance()->IsDefaultSiteInstance());
130 } else {
Aaron Colwell91e32b12021-02-17 01:40:56131 EXPECT_EQ(CreateExpectedSiteInfo(kUrl),
132 main_test_rfh()->GetSiteInstance()->GetSiteInfo());
Aaron Colwelle953e562019-07-24 16:47:36133 }
carlosk39337112015-01-14 21:44:51134 EXPECT_EQ(kUrl, contents()->GetLastCommittedURL());
carloske24d11782015-02-13 10:10:02135
carloskf4707892015-02-19 18:47:40136 // The main RenderFrameHost should not have been changed, and the renderer
137 // should have been initialized.
carloske24d11782015-02-13 10:10:02138 EXPECT_EQ(site_instance_id, main_test_rfh()->GetSiteInstance()->GetId());
139 EXPECT_TRUE(main_test_rfh()->IsRenderFrameLive());
carlosk39337112015-01-14 21:44:51140
141 // After a navigation is finished no speculative RenderFrameHost should
142 // exist.
carlosk39337112015-01-14 21:44:51143 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
carlosk39337112015-01-14 21:44:51144}
145
Arthur Hemery0dd65812019-08-01 14:18:45146// Tests a complete renderer-initiated same-site navigation.
Camille Lamy07c49cdf2019-03-11 15:53:57147TEST_F(NavigatorTest, SimpleRendererInitiatedSameSiteNavigation) {
carloske24d11782015-02-13 10:10:02148 const GURL kUrl1("http://www.chromium.org/");
149 const GURL kUrl2("http://www.chromium.org/Home");
150
151 contents()->NavigateAndCommit(kUrl1);
152 EXPECT_TRUE(main_test_rfh()->IsRenderFrameLive());
Mario Sanchez Pradacb83d6c82020-09-11 13:11:51153 static_cast<mojom::FrameHost*>(main_test_rfh())->DidStopLoading();
Nasko Oskov2e9e0112020-12-22 21:34:43154 FrameTreeNode* node = main_test_rfh()->frame_tree_node();
carloske24d11782015-02-13 10:10:02155
carloskf4707892015-02-19 18:47:40156 // Start a renderer-initiated non-user-initiated navigation.
Nasko Oskov2e9e0112020-12-22 21:34:43157 EXPECT_FALSE(node->navigation_request());
arthursonzogni91439432017-08-16 16:32:37158 auto navigation =
159 NavigationSimulator::CreateRendererInitiated(kUrl2, main_test_rfh());
160 navigation->SetTransition(ui::PageTransitionFromInt(
161 ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_CLIENT_REDIRECT));
162 navigation->SetHasUserGesture(false);
163 navigation->Start();
clamydcb434c12015-04-16 19:29:16164 NavigationRequest* request = node->navigation_request();
carloske24d11782015-02-13 10:10:02165 ASSERT_TRUE(request);
166
167 // The navigation is immediately started as there's no need to wait for
168 // beforeUnload to be executed.
Mohamed Abdelhalimccd149af2019-10-31 14:48:53169 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, request->state());
Arthur Hemery14a71ad22017-10-27 10:54:39170 EXPECT_FALSE(request->common_params().has_user_gesture);
carloske24d11782015-02-13 10:10:02171 EXPECT_EQ(kUrl2, request->common_params().url);
172 EXPECT_FALSE(request->browser_initiated());
Rakina Zata Amni1d15cfb2020-08-05 02:32:55173
174 if (CanSameSiteMainFrameNavigationsChangeRenderFrameHosts()) {
175 // If same-site ProactivelySwapBrowsingInstance or main-frame RenderDocument
176 // is enabled, the RFH should change so we should have a speculative RFH.
177 EXPECT_TRUE(GetSpeculativeRenderFrameHost(node));
178 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node)->is_loading());
179 } else {
180 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
181 }
arthursonzogni91439432017-08-16 16:32:37182 EXPECT_FALSE(main_test_rfh()->is_loading());
carloske24d11782015-02-13 10:10:02183
arthursonzogni91439432017-08-16 16:32:37184 // Have the current RenderFrameHost commit the navigation
185 navigation->ReadyToCommit();
Rakina Zata Amni1d15cfb2020-08-05 02:32:55186 if (CanSameSiteMainFrameNavigationsChangeRenderFrameHosts()) {
187 EXPECT_TRUE(GetSpeculativeRenderFrameHost(node)->is_loading());
188 } else {
189 EXPECT_TRUE(main_test_rfh()->is_loading());
190 }
clamyefdb7a42015-07-01 16:55:47191 EXPECT_FALSE(node->navigation_request());
carloske24d11782015-02-13 10:10:02192
193 // Commit the navigation.
arthursonzogni91439432017-08-16 16:32:37194 navigation->Commit();
Sreeja Kamishettye25ac752020-05-12 18:15:48195 EXPECT_TRUE(main_test_rfh()->IsCurrent());
Aaron Colwelle953e562019-07-24 16:47:36196 if (AreDefaultSiteInstancesEnabled()) {
197 EXPECT_TRUE(main_test_rfh()->GetSiteInstance()->IsDefaultSiteInstance());
198 } else {
Aaron Colwell91e32b12021-02-17 01:40:56199 EXPECT_EQ(CreateExpectedSiteInfo(kUrl2),
200 main_test_rfh()->GetSiteInstance()->GetSiteInfo());
Aaron Colwelle953e562019-07-24 16:47:36201 }
carloske24d11782015-02-13 10:10:02202 EXPECT_EQ(kUrl2, contents()->GetLastCommittedURL());
carloske24d11782015-02-13 10:10:02203 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
carloske24d11782015-02-13 10:10:02204}
205
Arthur Hemery0dd65812019-08-01 14:18:45206// Tests a complete renderer-initiated navigation that should be
carlosk42f59e62015-03-16 19:02:36207// cross-site but does not result in a SiteInstance swap because its
208// renderer-initiated.
Camille Lamy07c49cdf2019-03-11 15:53:57209TEST_F(NavigatorTest, SimpleRendererInitiatedCrossSiteNavigation) {
carlosk42f59e62015-03-16 19:02:36210 const GURL kUrl1("http://www.chromium.org/");
211 const GURL kUrl2("http://www.google.com");
212
213 contents()->NavigateAndCommit(kUrl1);
214 EXPECT_TRUE(main_test_rfh()->IsRenderFrameLive());
Aaron Colwell5fb878042020-12-17 19:48:44215 scoped_refptr<SiteInstanceImpl> site_instance_1 =
216 main_test_rfh()->GetSiteInstance();
217 bool expect_site_instance_change =
218 ExpectSiteInstanceChange(site_instance_1.get());
Nasko Oskov2e9e0112020-12-22 21:34:43219 FrameTreeNode* node = main_test_rfh()->frame_tree_node();
carlosk42f59e62015-03-16 19:02:36220
arthursonzogni91439432017-08-16 16:32:37221 // Start a renderer-initiated navigation.
Nasko Oskov2e9e0112020-12-22 21:34:43222 EXPECT_FALSE(node->navigation_request());
arthursonzogni91439432017-08-16 16:32:37223 auto navigation =
224 NavigationSimulator::CreateRendererInitiated(kUrl2, main_test_rfh());
225 navigation->Start();
clamydcb434c12015-04-16 19:29:16226 NavigationRequest* request = node->navigation_request();
carlosk42f59e62015-03-16 19:02:36227 ASSERT_TRUE(request);
228
229 // The navigation is immediately started as there's no need to wait for
230 // beforeUnload to be executed.
Mohamed Abdelhalimccd149af2019-10-31 14:48:53231 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, request->state());
carlosk42f59e62015-03-16 19:02:36232 EXPECT_EQ(kUrl2, request->common_params().url);
233 EXPECT_FALSE(request->browser_initiated());
Aaron Colwell5fb878042020-12-17 19:48:44234 if (expect_site_instance_change) {
clamy61dfb232016-02-26 18:08:49235 EXPECT_TRUE(GetSpeculativeRenderFrameHost(node));
236 } else {
237 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
238 }
carlosk42f59e62015-03-16 19:02:36239
240 // Have the current RenderFrameHost commit the navigation.
arthursonzogni91439432017-08-16 16:32:37241 navigation->ReadyToCommit();
Aaron Colwell5fb878042020-12-17 19:48:44242 if (expect_site_instance_change) {
arthursonzogni91439432017-08-16 16:32:37243 EXPECT_EQ(navigation->GetFinalRenderFrameHost(),
244 GetSpeculativeRenderFrameHost(node));
clamy61dfb232016-02-26 18:08:49245 }
clamyefdb7a42015-07-01 16:55:47246 EXPECT_FALSE(node->navigation_request());
carlosk42f59e62015-03-16 19:02:36247
248 // Commit the navigation.
arthursonzogni91439432017-08-16 16:32:37249 navigation->Commit();
Sreeja Kamishettye25ac752020-05-12 18:15:48250 EXPECT_TRUE(main_test_rfh()->IsCurrent());
carlosk42f59e62015-03-16 19:02:36251 EXPECT_EQ(kUrl2, contents()->GetLastCommittedURL());
carlosk42f59e62015-03-16 19:02:36252 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
carlosk42f59e62015-03-16 19:02:36253
Aaron Colwell5fb878042020-12-17 19:48:44254 if (expect_site_instance_change) {
255 EXPECT_NE(site_instance_1->GetId(),
256 main_test_rfh()->GetSiteInstance()->GetId());
257 EXPECT_EQ(site_instance_1->IsDefaultSiteInstance(),
258 main_test_rfh()->GetSiteInstance()->IsDefaultSiteInstance());
clamy5d947f52017-05-24 19:51:18259 } else {
Aaron Colwell5fb878042020-12-17 19:48:44260 EXPECT_EQ(site_instance_1->GetId(),
261 main_test_rfh()->GetSiteInstance()->GetId());
clamy5d947f52017-05-24 19:51:18262 }
carlosk42f59e62015-03-16 19:02:36263}
264
Todd Sahlb2f798302021-01-21 16:32:07265// Tests that when a navigation to about:blank is renderer-aborted,
266// after another cross-site navigation has been initiated, that the
267// second navigation is undisturbed.
268TEST_F(NavigatorTest, RendererAbortedAboutBlankNavigation) {
269 const GURL kUrl0("http://www.google.com/");
270 const GURL kUrl1("about:blank");
271 const GURL kUrl2("http://www.chromium.org/Home");
272
273 contents()->NavigateAndCommit(kUrl0);
274 EXPECT_TRUE(main_test_rfh()->IsRenderFrameLive());
275 if (!ExpectSiteInstanceChange(main_test_rfh()->GetSiteInstance()))
276 return;
277
278 // Start a renderer-initiated navigation to about:blank.
279 EXPECT_FALSE(main_test_rfh()->is_loading());
280 auto navigation1 =
281 NavigationSimulator::CreateRendererInitiated(kUrl1, main_test_rfh());
282 navigation1->SetTransition(ui::PAGE_TRANSITION_LINK);
283 navigation1->Start();
284 navigation1->ReadyToCommit();
285
286 // about:blank should load on the main rfhi, not a speculative one,
287 // and automatically advance to READY_TO_COMMIT since it requires
288 // no network resources.
289 FrameTreeNode* node = main_test_rfh()->frame_tree_node();
290 ASSERT_FALSE(node->navigation_request());
291 EXPECT_TRUE(main_test_rfh()->is_loading());
292 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
293
294 // Start a second, cross-origin navigation.
295 auto navigation2 =
296 NavigationSimulator::CreateRendererInitiated(kUrl2, main_test_rfh());
297 navigation2->SetTransition(ui::PAGE_TRANSITION_LINK);
298 navigation2->Start();
299 ASSERT_TRUE(node->navigation_request());
300 EXPECT_TRUE(GetSpeculativeRenderFrameHost(node));
301
302 // Abort the initial navigation.
303 navigation1->AbortFromRenderer();
304
305 // But the speculative rfhi and second navigation request
306 // should be unaffected.
307 ASSERT_TRUE(node->navigation_request());
308 EXPECT_TRUE(GetSpeculativeRenderFrameHost(node));
309}
310
311// Tests that when a navigation to about:blank is renderer-aborted,
312// after another cross-site navigation has been initiated, that the
313// second navigation is undisturbed. In this variation, the second
314// navigation is initially same-site, then redirects cross-site,
315// and a throttle DEFERs during WillProcessResponse(). The initial
316// navigation gets aborted during this defer.
317TEST_F(NavigatorTest,
318 RedirectedRendererAbortedAboutBlankNavigationwithDeferredCommit) {
319 const GURL kUrl0("http://www.google.com/");
320 const GURL kUrl0SameSiteVariation("http://www.google.com/home");
321 const GURL kUrl1("about:blank");
322 const GURL kUrl2("http://www.chromium.org/Home");
323
324 contents()->NavigateAndCommit(kUrl0);
325 EXPECT_TRUE(main_test_rfh()->IsRenderFrameLive());
326 if (!ExpectSiteInstanceChange(main_test_rfh()->GetSiteInstance()))
327 return;
328
329 // Start a renderer-initiated navigation to about:blank.
330 EXPECT_FALSE(main_test_rfh()->is_loading());
331 auto navigation1 =
332 NavigationSimulator::CreateRendererInitiated(kUrl1, main_test_rfh());
333 navigation1->SetTransition(ui::PAGE_TRANSITION_LINK);
334 navigation1->Start();
335 navigation1->ReadyToCommit();
336
337 // about:blank should load on the main rfhi, not a speculative one,
338 // and automatically advance to READY_TO_COMMIT since it requires
339 // no network resources.
340 FrameTreeNode* node = main_test_rfh()->frame_tree_node();
341 ASSERT_FALSE(node->navigation_request());
342 EXPECT_TRUE(main_test_rfh()->is_loading());
343 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
344
345 // Start a second, same-origin navigation.
346 auto navigation2 = NavigationSimulator::CreateRendererInitiated(
347 kUrl0SameSiteVariation, main_test_rfh());
348 navigation2->SetTransition(ui::PAGE_TRANSITION_LINK);
349 navigation2->SetAutoAdvance(false);
350
351 // Insert a TaskRunnerDeferringThrottle that will defer
352 // during WillProcessResponse() of navigation2.
353 auto task_runner = base::MakeRefCounted<base::TestSimpleTaskRunner>();
354 auto* raw_runner = task_runner.get();
355 TestNavigationThrottleInserter throttle_inserter(
356 web_contents(),
357 base::BindRepeating(&TaskRunnerDeferringThrottle::Create,
358 std::move(task_runner), false /* defer_start */,
359 false /* defer-redirect */,
360 true /* defer_response */));
361
362 navigation2->Start();
363 ASSERT_TRUE(node->navigation_request());
364 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
365
366 // Redirect navigation2 cross-site, which, once ReadyCommit()
367 // is called, will force a speculative RFHI to be created,
368 // and update the associated site instance type of the
369 // NavigationRequest for navigation2. This will prevent
370 // the abort of navigation1 from destroying the speculative
371 // RFHI that navigation2 depends on.
372 navigation2->Redirect(kUrl2);
373 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
374 EXPECT_TRUE(node->navigation_request()->associated_site_instance_type() ==
375 NavigationRequest::AssociatedSiteInstanceType::CURRENT);
376
377 navigation2->ReadyToCommit();
378 EXPECT_EQ(1u, raw_runner->NumPendingTasks());
379 EXPECT_TRUE(navigation2->IsDeferred());
380 EXPECT_TRUE(GetSpeculativeRenderFrameHost(node));
381 EXPECT_EQ(node->navigation_request()->associated_site_instance_type(),
382 NavigationRequest::AssociatedSiteInstanceType::SPECULATIVE);
383
384 // Abort the initial navigation.
385 navigation1->AbortFromRenderer();
386
387 // The speculative rfhi and second navigation request
388 // should be unaffected.
389 ASSERT_TRUE(node->navigation_request());
390 EXPECT_TRUE(GetSpeculativeRenderFrameHost(node));
391}
392
Arthur Hemery0dd65812019-08-01 14:18:45393// Tests that a beforeUnload denial cancels the navigation.
Camille Lamy07c49cdf2019-03-11 15:53:57394TEST_F(NavigatorTest, BeforeUnloadDenialCancelNavigation) {
carloske24d11782015-02-13 10:10:02395 const GURL kUrl1("http://www.google.com/");
396 const GURL kUrl2("http://www.chromium.org/");
397
398 contents()->NavigateAndCommit(kUrl1);
399
400 // Start a new navigation.
401 FrameTreeNode* node = main_test_rfh()->frame_tree_node();
Arthur Hemery56fb25c2019-02-08 17:55:13402 auto navigation =
403 NavigationSimulatorImpl::CreateBrowserInitiated(kUrl2, contents());
404 navigation->BrowserInitiatedStartAndWaitBeforeUnload();
clamydcb434c12015-04-16 19:29:16405 NavigationRequest* request = node->navigation_request();
carloske24d11782015-02-13 10:10:02406 ASSERT_TRUE(request);
407 EXPECT_TRUE(request->browser_initiated());
408 EXPECT_EQ(NavigationRequest::WAITING_FOR_RENDERER_RESPONSE, request->state());
carloskc49005eb2015-06-16 11:25:07409 EXPECT_TRUE(GetSpeculativeRenderFrameHost(node));
carloska0350db2015-07-30 20:10:57410 RenderFrameDeletedObserver rfh_deleted_observer(
411 GetSpeculativeRenderFrameHost(node));
carloske24d11782015-02-13 10:10:02412
413 // Simulate a beforeUnload denial.
Antonio Gomes8678a202020-03-02 20:03:25414 main_test_rfh()->SimulateBeforeUnloadCompleted(false);
clamydcb434c12015-04-16 19:29:16415 EXPECT_FALSE(node->navigation_request());
carloske24d11782015-02-13 10:10:02416 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
carloska0350db2015-07-30 20:10:57417 EXPECT_TRUE(rfh_deleted_observer.deleted());
carloske24d11782015-02-13 10:10:02418}
419
Arthur Hemery56fb25c2019-02-08 17:55:13420// Test that a proper NavigationRequest is created at navigation start.
Camille Lamy07c49cdf2019-03-11 15:53:57421TEST_F(NavigatorTest, BeginNavigation) {
clamy71a42ec2014-10-02 18:43:22422 const GURL kUrl1("http://www.google.com/");
423 const GURL kUrl2("http://www.chromium.org/");
424 const GURL kUrl3("http://www.gmail.com/");
clamy71a42ec2014-10-02 18:43:22425
clamy71a42ec2014-10-02 18:43:22426 contents()->NavigateAndCommit(kUrl1);
427
428 // Add a subframe.
carlosk39337112015-01-14 21:44:51429 FrameTreeNode* root_node = contents()->GetFrameTree()->root();
carloskfdf32b52015-02-06 17:58:30430 TestRenderFrameHost* subframe_rfh = main_test_rfh()->AppendChild("Child");
carlosk39337112015-01-14 21:44:51431 ASSERT_TRUE(subframe_rfh);
clamy71a42ec2014-10-02 18:43:22432
carloske24d11782015-02-13 10:10:02433 // Start a navigation at the subframe.
clamy71a42ec2014-10-02 18:43:22434 FrameTreeNode* subframe_node = subframe_rfh->frame_tree_node();
Arthur Hemery56fb25c2019-02-08 17:55:13435 auto navigation =
436 NavigationSimulatorImpl::CreateBrowserInitiated(kUrl2, contents());
437 NavigationController::LoadURLParams load_url_params(kUrl2);
438 load_url_params.frame_tree_node_id = subframe_node->frame_tree_node_id();
439 navigation->SetLoadURLParams(&load_url_params);
440 navigation->BrowserInitiatedStartAndWaitBeforeUnload();
clamydcb434c12015-04-16 19:29:16441 NavigationRequest* subframe_request = subframe_node->navigation_request();
clamy3f8ab9c2017-01-26 14:42:14442
jam40444982017-04-11 03:01:41443 // We should be waiting for the BeforeUnload event to execute in the subframe.
clamy3f8ab9c2017-01-26 14:42:14444 ASSERT_TRUE(subframe_request);
jam40444982017-04-11 03:01:41445 EXPECT_EQ(NavigationRequest::WAITING_FOR_RENDERER_RESPONSE,
446 subframe_request->state());
Antonio Gomes8678a202020-03-02 20:03:25447 EXPECT_TRUE(subframe_rfh->is_waiting_for_beforeunload_completion());
clamy3f8ab9c2017-01-26 14:42:14448
Arthur Hemery56fb25c2019-02-08 17:55:13449 // Start the navigation, which will internally simulate that the beforeUnload
Antonio Gomes8678a202020-03-02 20:03:25450 // completion callback has been invoked.
Arthur Hemery56fb25c2019-02-08 17:55:13451 navigation->Start();
davidben6b77cd72014-10-29 21:13:45452 TestNavigationURLLoader* subframe_loader =
453 GetLoaderForNavigationRequest(subframe_request);
carloske24d11782015-02-13 10:10:02454 ASSERT_TRUE(subframe_loader);
Mohamed Abdelhalimccd149af2019-10-31 14:48:53455 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, subframe_request->state());
clamy71a42ec2014-10-02 18:43:22456 EXPECT_EQ(kUrl2, subframe_request->common_params().url);
Lucas Furukawa Gadanief8290a2019-07-29 20:27:51457 EXPECT_EQ(kUrl2, subframe_loader->request_info()->common_params->url);
Matt Menkea56c5992020-04-10 20:53:56458 EXPECT_TRUE(
Shuran Huang0e0aaa52020-12-02 22:24:54459 net::IsolationInfo::Create(
460 net::IsolationInfo::RequestType::kSubFrame,
461 url::Origin::Create(kUrl1), url::Origin::Create(kUrl2),
462 net::SiteForCookies::FromUrl(kUrl1), std::set<net::SchemefulSite>())
Matt Menkea56c5992020-04-10 20:53:56463 .IsEqualForTesting(subframe_loader->request_info()->isolation_info));
Shivani Sharma8ae506c2019-07-21 21:08:27464
davidben6b77cd72014-10-29 21:13:45465 EXPECT_FALSE(subframe_loader->request_info()->is_main_frame);
466 EXPECT_TRUE(subframe_loader->request_info()->parent_is_main_frame);
carloske24d11782015-02-13 10:10:02467 EXPECT_TRUE(subframe_request->browser_initiated());
carlosk39337112015-01-14 21:44:51468 EXPECT_FALSE(GetSpeculativeRenderFrameHost(root_node));
clamy71a42ec2014-10-02 18:43:22469
carlosk39337112015-01-14 21:44:51470 // Subframe navigations should never create a speculative RenderFrameHost,
Aaron Colwell5fb878042020-12-17 19:48:44471 // unless site-per-process or ProcessSharingWithStrictSiteInstances is
472 // enabled. In that case, as the subframe navigation is to a different site
473 // and is still ongoing, it should have one.
474 bool expect_site_instance_change = AreStrictSiteInstancesEnabled();
475 if (expect_site_instance_change) {
carlosk39337112015-01-14 21:44:51476 EXPECT_TRUE(GetSpeculativeRenderFrameHost(subframe_node));
477 } else {
478 EXPECT_FALSE(GetSpeculativeRenderFrameHost(subframe_node));
479 }
480
carloske24d11782015-02-13 10:10:02481 // Now start a navigation at the root node.
Arthur Hemery56fb25c2019-02-08 17:55:13482 auto navigation2 =
483 NavigationSimulatorImpl::CreateBrowserInitiated(kUrl3, contents());
484 navigation2->BrowserInitiatedStartAndWaitBeforeUnload();
clamydcb434c12015-04-16 19:29:16485 NavigationRequest* main_request = root_node->navigation_request();
carloske24d11782015-02-13 10:10:02486 ASSERT_TRUE(main_request);
jam40444982017-04-11 03:01:41487 EXPECT_EQ(NavigationRequest::WAITING_FOR_RENDERER_RESPONSE,
488 main_request->state());
carloskc49005eb2015-06-16 11:25:07489
490 // Main frame navigation to a different site should use a speculative
491 // RenderFrameHost.
492 EXPECT_TRUE(GetSpeculativeRenderFrameHost(root_node));
carloske24d11782015-02-13 10:10:02493
Arthur Hemery56fb25c2019-02-08 17:55:13494 // Start the navigation, which will internally simulate that the beforeUnload
Antonio Gomes8678a202020-03-02 20:03:25495 // completion callback has been invoked.
Arthur Hemery56fb25c2019-02-08 17:55:13496 navigation2->Start();
davidben6b77cd72014-10-29 21:13:45497 TestNavigationURLLoader* main_loader =
498 GetLoaderForNavigationRequest(main_request);
clamy71a42ec2014-10-02 18:43:22499 EXPECT_EQ(kUrl3, main_request->common_params().url);
Lucas Furukawa Gadanief8290a2019-07-29 20:27:51500 EXPECT_EQ(kUrl3, main_loader->request_info()->common_params->url);
Matt Menkea56c5992020-04-10 20:53:56501 EXPECT_TRUE(
Shuran Huang0e0aaa52020-12-02 22:24:54502 net::IsolationInfo::Create(
503 net::IsolationInfo::RequestType::kMainFrame,
504 url::Origin::Create(kUrl3), url::Origin::Create(kUrl3),
505 net::SiteForCookies::FromUrl(kUrl3), std::set<net::SchemefulSite>())
Matt Menkea56c5992020-04-10 20:53:56506 .IsEqualForTesting(main_loader->request_info()->isolation_info));
davidben6b77cd72014-10-29 21:13:45507 EXPECT_TRUE(main_loader->request_info()->is_main_frame);
508 EXPECT_FALSE(main_loader->request_info()->parent_is_main_frame);
carloske24d11782015-02-13 10:10:02509 EXPECT_TRUE(main_request->browser_initiated());
Antonio Gomes8678a202020-03-02 20:03:25510 // BeforeUnloadCompleted callback was invoked by the renderer so the
511 // navigation should have started.
Mohamed Abdelhalimccd149af2019-10-31 14:48:53512 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, main_request->state());
carlosk39337112015-01-14 21:44:51513 EXPECT_TRUE(GetSpeculativeRenderFrameHost(root_node));
514
515 // As the main frame hasn't yet committed the subframe still exists. Thus, the
516 // above situation regarding subframe navigations is valid here.
Aaron Colwell5fb878042020-12-17 19:48:44517 if (expect_site_instance_change) {
carlosk39337112015-01-14 21:44:51518 EXPECT_TRUE(GetSpeculativeRenderFrameHost(subframe_node));
519 } else {
520 EXPECT_FALSE(GetSpeculativeRenderFrameHost(subframe_node));
521 }
clamy71a42ec2014-10-02 18:43:22522}
523
Arthur Hemery0dd65812019-08-01 14:18:45524// Tests that committing an HTTP 204 or HTTP 205 response cancels
carlosk39337112015-01-14 21:44:51525// the navigation.
Camille Lamy07c49cdf2019-03-11 15:53:57526TEST_F(NavigatorTest, NoContent) {
davidben8b339132014-10-08 02:27:01527 const GURL kUrl1("http://www.chromium.org/");
528 const GURL kUrl2("http://www.google.com/");
529
530 // Load a URL.
531 contents()->NavigateAndCommit(kUrl1);
davidben8b339132014-10-08 02:27:01532 FrameTreeNode* node = main_test_rfh()->frame_tree_node();
533
davidben8b339132014-10-08 02:27:01534 // Navigate to a different site.
Nasko Oskov2e9e0112020-12-22 21:34:43535 EXPECT_FALSE(node->navigation_request());
Arthur Hemery56fb25c2019-02-08 17:55:13536 auto navigation =
537 NavigationSimulator::CreateBrowserInitiated(kUrl2, contents());
538 navigation->Start();
carlosk39337112015-01-14 21:44:51539
clamydcb434c12015-04-16 19:29:16540 NavigationRequest* main_request = node->navigation_request();
davidben8b339132014-10-08 02:27:01541 ASSERT_TRUE(main_request);
542
carlosk39337112015-01-14 21:44:51543 // Navigations to a different site do create a speculative RenderFrameHost.
544 EXPECT_TRUE(GetSpeculativeRenderFrameHost(node));
545
davidben8b339132014-10-08 02:27:01546 // Commit an HTTP 204 response.
Lucas Furukawa Gadanid661c0d2019-12-02 19:58:16547 auto response = network::mojom::URLResponseHead::New();
davidben8b339132014-10-08 02:27:01548 const char kNoContentHeaders[] = "HTTP/1.1 204 No Content\0\0";
Lucas Furukawa Gadanid661c0d2019-12-02 19:58:16549 response->headers = new net::HttpResponseHeaders(
Avi Drissman9d3ded92018-12-25 20:50:21550 std::string(kNoContentHeaders, base::size(kNoContentHeaders)));
Lucas Furukawa Gadanid661c0d2019-12-02 19:58:16551 GetLoaderForNavigationRequest(main_request)
552 ->CallOnResponseStarted(std::move(response));
davidben8b339132014-10-08 02:27:01553
carlosk39337112015-01-14 21:44:51554 // There should be no pending nor speculative RenderFrameHost; the navigation
555 // was aborted.
clamydcb434c12015-04-16 19:29:16556 EXPECT_FALSE(node->navigation_request());
carlosk39337112015-01-14 21:44:51557 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
davidben8b339132014-10-08 02:27:01558
559 // Now, repeat the test with 205 Reset Content.
560
561 // Navigate to a different site again.
Arthur Hemery56fb25c2019-02-08 17:55:13562 auto navigation2 =
563 NavigationSimulator::CreateBrowserInitiated(kUrl2, contents());
564 navigation2->Start();
carlosk39337112015-01-14 21:44:51565
clamydcb434c12015-04-16 19:29:16566 main_request = node->navigation_request();
davidben8b339132014-10-08 02:27:01567 ASSERT_TRUE(main_request);
carlosk39337112015-01-14 21:44:51568 EXPECT_TRUE(GetSpeculativeRenderFrameHost(node));
davidben8b339132014-10-08 02:27:01569
570 // Commit an HTTP 205 response.
Lucas Furukawa Gadanid661c0d2019-12-02 19:58:16571 response = network::mojom::URLResponseHead::New();
davidben8b339132014-10-08 02:27:01572 const char kResetContentHeaders[] = "HTTP/1.1 205 Reset Content\0\0";
Lucas Furukawa Gadanid661c0d2019-12-02 19:58:16573 response->headers = new net::HttpResponseHeaders(
Avi Drissman9d3ded92018-12-25 20:50:21574 std::string(kResetContentHeaders, base::size(kResetContentHeaders)));
Lucas Furukawa Gadanid661c0d2019-12-02 19:58:16575 GetLoaderForNavigationRequest(main_request)
576 ->CallOnResponseStarted(std::move(response));
davidben8b339132014-10-08 02:27:01577
carlosk39337112015-01-14 21:44:51578 // There should be no pending nor speculative RenderFrameHost; the navigation
579 // was aborted.
clamydcb434c12015-04-16 19:29:16580 EXPECT_FALSE(node->navigation_request());
carlosk39337112015-01-14 21:44:51581 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
davidben8b339132014-10-08 02:27:01582}
583
arthursonzognif34adf092018-04-24 17:06:13584// Test that a new RenderFrameHost is created when doing a cross site
585// navigation.
Camille Lamy07c49cdf2019-03-11 15:53:57586TEST_F(NavigatorTest, CrossSiteNavigation) {
clamy71a42ec2014-10-02 18:43:22587 const GURL kUrl1("http://www.chromium.org/");
588 const GURL kUrl2("http://www.google.com/");
589
clamy71a42ec2014-10-02 18:43:22590 contents()->NavigateAndCommit(kUrl1);
carlosk39337112015-01-14 21:44:51591 RenderFrameHostImpl* initial_rfh = main_test_rfh();
clamy71a42ec2014-10-02 18:43:22592 FrameTreeNode* node = main_test_rfh()->frame_tree_node();
593
594 // Navigate to a different site.
Arthur Hemery859f3462019-01-29 16:29:07595 EXPECT_EQ(main_test_rfh()->navigation_requests().size(), 0u);
596 auto navigation =
597 NavigationSimulator::CreateBrowserInitiated(kUrl2, contents());
598 navigation->Start();
clamydcb434c12015-04-16 19:29:16599 NavigationRequest* main_request = node->navigation_request();
clamy71a42ec2014-10-02 18:43:22600 ASSERT_TRUE(main_request);
carloskc49005eb2015-06-16 11:25:07601 TestRenderFrameHost* speculative_rfh = GetSpeculativeRenderFrameHost(node);
602 ASSERT_TRUE(speculative_rfh);
carloskc49005eb2015-06-16 11:25:07603 EXPECT_EQ(speculative_rfh, GetSpeculativeRenderFrameHost(node));
clamy71a42ec2014-10-02 18:43:22604
Arthur Hemery859f3462019-01-29 16:29:07605 navigation->ReadyToCommit();
carloskc49005eb2015-06-16 11:25:07606 EXPECT_EQ(speculative_rfh, GetSpeculativeRenderFrameHost(node));
Arthur Hemery859f3462019-01-29 16:29:07607 EXPECT_EQ(speculative_rfh->navigation_requests().size(), 1u);
608 EXPECT_EQ(main_test_rfh()->navigation_requests().size(), 0u);
carlosk39337112015-01-14 21:44:51609
Arthur Hemery859f3462019-01-29 16:29:07610 navigation->Commit();
carlosk39337112015-01-14 21:44:51611 RenderFrameHostImpl* final_rfh = main_test_rfh();
612 EXPECT_EQ(speculative_rfh, final_rfh);
613 EXPECT_NE(initial_rfh, final_rfh);
614 EXPECT_TRUE(final_rfh->IsRenderFrameLive());
615 EXPECT_TRUE(final_rfh->render_view_host()->IsRenderViewLive());
616 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
davidben6b77cd72014-10-29 21:13:45617}
618
arthursonzognif34adf092018-04-24 17:06:13619// Test that redirects are followed and the speculative RenderFrameHost logic
620// behaves as expected.
Camille Lamy07c49cdf2019-03-11 15:53:57621TEST_F(NavigatorTest, RedirectCrossSite) {
davidben6b77cd72014-10-29 21:13:45622 const GURL kUrl1("http://www.chromium.org/");
623 const GURL kUrl2("http://www.google.com/");
624
625 contents()->NavigateAndCommit(kUrl1);
626 RenderFrameHostImpl* rfh = main_test_rfh();
davidben6b77cd72014-10-29 21:13:45627 FrameTreeNode* node = main_test_rfh()->frame_tree_node();
628
davidben6b77cd72014-10-29 21:13:45629 // Navigate to a URL on the same site.
Arthur Hemery859f3462019-01-29 16:29:07630 EXPECT_EQ(main_test_rfh()->navigation_requests().size(), 0u);
631 auto navigation =
632 NavigationSimulator::CreateBrowserInitiated(kUrl1, contents());
633 navigation->Start();
clamydcb434c12015-04-16 19:29:16634 NavigationRequest* main_request = node->navigation_request();
davidben6b77cd72014-10-29 21:13:45635 ASSERT_TRUE(main_request);
carlosk39337112015-01-14 21:44:51636 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
davidben6b77cd72014-10-29 21:13:45637
638 // It then redirects to another site.
Arthur Hemery859f3462019-01-29 16:29:07639 navigation->Redirect(kUrl2);
davidben6b77cd72014-10-29 21:13:45640
641 // The redirect should have been followed.
642 EXPECT_EQ(1, GetLoaderForNavigationRequest(main_request)->redirect_count());
carlosk39337112015-01-14 21:44:51643 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
davidben6b77cd72014-10-29 21:13:45644
Arthur Hemery859f3462019-01-29 16:29:07645 navigation->ReadyToCommit();
carlosk39337112015-01-14 21:44:51646 TestRenderFrameHost* final_speculative_rfh =
647 GetSpeculativeRenderFrameHost(node);
648 EXPECT_TRUE(final_speculative_rfh);
Arthur Hemery859f3462019-01-29 16:29:07649 EXPECT_EQ(final_speculative_rfh->navigation_requests().size(), 1u);
carlosk39337112015-01-14 21:44:51650
Arthur Hemery859f3462019-01-29 16:29:07651 navigation->Commit();
carlosk39337112015-01-14 21:44:51652 RenderFrameHostImpl* final_rfh = main_test_rfh();
653 ASSERT_TRUE(final_rfh);
654 EXPECT_NE(rfh, final_rfh);
655 EXPECT_EQ(final_speculative_rfh, final_rfh);
656 EXPECT_TRUE(final_rfh->IsRenderFrameLive());
657 EXPECT_TRUE(final_rfh->render_view_host()->IsRenderViewLive());
658 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
clamy71a42ec2014-10-02 18:43:22659}
660
arthursonzognif34adf092018-04-24 17:06:13661// Test that a navigation is canceled if another browser-initiated request has
662// been issued in the meantime. Also confirms that the speculative
carloske24d11782015-02-13 10:10:02663// RenderFrameHost is correctly updated in the process.
Camille Lamy07c49cdf2019-03-11 15:53:57664TEST_F(NavigatorTest, BrowserInitiatedNavigationCancel) {
clamy71a42ec2014-10-02 18:43:22665 const GURL kUrl0("http://www.wikipedia.org/");
clamy71a42ec2014-10-02 18:43:22666 const GURL kUrl1("http://www.chromium.org/");
Aaron Colwell91e32b12021-02-17 01:40:56667 const auto kUrl1SiteInfo = CreateExpectedSiteInfo(kUrl1);
clamy71a42ec2014-10-02 18:43:22668 const GURL kUrl2("http://www.google.com/");
Aaron Colwell91e32b12021-02-17 01:40:56669 const auto kUrl2SiteInfo = CreateExpectedSiteInfo(kUrl2);
clamy71a42ec2014-10-02 18:43:22670
671 // Initialization.
672 contents()->NavigateAndCommit(kUrl0);
673 FrameTreeNode* node = main_test_rfh()->frame_tree_node();
clamy71a42ec2014-10-02 18:43:22674
davidbena5496d62014-10-07 18:52:04675 // Request navigation to the 1st URL.
Nasko Oskov2e9e0112020-12-22 21:34:43676 EXPECT_FALSE(node->navigation_request());
Arthur Hemery859f3462019-01-29 16:29:07677 auto navigation1 =
678 NavigationSimulator::CreateBrowserInitiated(kUrl1, contents());
679 navigation1->Start();
clamydcb434c12015-04-16 19:29:16680 NavigationRequest* request1 = node->navigation_request();
clamy71a42ec2014-10-02 18:43:22681 ASSERT_TRUE(request1);
davidbena5496d62014-10-07 18:52:04682 EXPECT_EQ(kUrl1, request1->common_params().url);
carloske24d11782015-02-13 10:10:02683 EXPECT_TRUE(request1->browser_initiated());
davidben6b77cd72014-10-29 21:13:45684 base::WeakPtr<TestNavigationURLLoader> loader1 =
685 GetLoaderForNavigationRequest(request1)->AsWeakPtr();
carloskf4707892015-02-19 18:47:40686 EXPECT_TRUE(loader1);
clamy71a42ec2014-10-02 18:43:22687
carloskf4707892015-02-19 18:47:40688 // Confirm a speculative RenderFrameHost was created.
carlosk39337112015-01-14 21:44:51689 TestRenderFrameHost* speculative_rfh = GetSpeculativeRenderFrameHost(node);
690 ASSERT_TRUE(speculative_rfh);
avib7348942015-12-25 20:57:10691 int32_t site_instance_id_1 = speculative_rfh->GetSiteInstance()->GetId();
Aaron Colwellf45e3a852019-06-06 00:48:27692 if (AreDefaultSiteInstancesEnabled()) {
693 EXPECT_TRUE(speculative_rfh->GetSiteInstance()->IsDefaultSiteInstance());
694 } else {
Aaron Colwell91e32b12021-02-17 01:40:56695 EXPECT_EQ(kUrl1SiteInfo, speculative_rfh->GetSiteInstance()->GetSiteInfo());
Aaron Colwellf45e3a852019-06-06 00:48:27696 }
carlosk39337112015-01-14 21:44:51697
davidbena5496d62014-10-07 18:52:04698 // Request navigation to the 2nd URL; the NavigationRequest must have been
699 // replaced by a new one with a different URL.
Arthur Hemery859f3462019-01-29 16:29:07700 auto navigation2 =
701 NavigationSimulator::CreateBrowserInitiated(kUrl2, contents());
702 navigation2->Start();
clamydcb434c12015-04-16 19:29:16703 NavigationRequest* request2 = node->navigation_request();
clamy71a42ec2014-10-02 18:43:22704 ASSERT_TRUE(request2);
davidbena5496d62014-10-07 18:52:04705 EXPECT_EQ(kUrl2, request2->common_params().url);
carloske24d11782015-02-13 10:10:02706 EXPECT_TRUE(request2->browser_initiated());
clamy71a42ec2014-10-02 18:43:22707
davidben6b77cd72014-10-29 21:13:45708 // Confirm that the first loader got destroyed.
709 EXPECT_FALSE(loader1);
710
carloskf4707892015-02-19 18:47:40711 // Confirm that a new speculative RenderFrameHost was created.
carlosk39337112015-01-14 21:44:51712 speculative_rfh = GetSpeculativeRenderFrameHost(node);
713 ASSERT_TRUE(speculative_rfh);
avib7348942015-12-25 20:57:10714 int32_t site_instance_id_2 = speculative_rfh->GetSiteInstance()->GetId();
Aaron Colwellf45e3a852019-06-06 00:48:27715
716 if (AreDefaultSiteInstancesEnabled()) {
717 EXPECT_TRUE(speculative_rfh->GetSiteInstance()->IsDefaultSiteInstance());
718 EXPECT_EQ(site_instance_id_1, site_instance_id_2);
719 } else {
720 EXPECT_NE(site_instance_id_1, site_instance_id_2);
721 }
carlosk39337112015-01-14 21:44:51722
Arthur Hemery859f3462019-01-29 16:29:07723 navigation2->ReadyToCommit();
724 EXPECT_EQ(speculative_rfh->navigation_requests().size(), 1u);
725 EXPECT_EQ(main_test_rfh()->navigation_requests().size(), 0u);
726
carloskf4707892015-02-19 18:47:40727 // Have the RenderFrameHost commit the navigation.
Arthur Hemery859f3462019-01-29 16:29:07728 navigation2->Commit();
carlosk39337112015-01-14 21:44:51729
730 // Confirm that the commit corresponds to the new request.
731 ASSERT_TRUE(main_test_rfh());
Aaron Colwellf45e3a852019-06-06 00:48:27732 if (AreDefaultSiteInstancesEnabled()) {
733 EXPECT_TRUE(main_test_rfh()->GetSiteInstance()->IsDefaultSiteInstance());
734 } else {
Aaron Colwell91e32b12021-02-17 01:40:56735 EXPECT_EQ(kUrl2SiteInfo, main_test_rfh()->GetSiteInstance()->GetSiteInfo());
Aaron Colwellf45e3a852019-06-06 00:48:27736 }
carlosk39337112015-01-14 21:44:51737 EXPECT_EQ(kUrl2, contents()->GetLastCommittedURL());
738
carloskf4707892015-02-19 18:47:40739 // Confirm that the committed RenderFrameHost is the latest speculative one.
carlosk39337112015-01-14 21:44:51740 EXPECT_EQ(site_instance_id_2, main_test_rfh()->GetSiteInstance()->GetId());
clamy71a42ec2014-10-02 18:43:22741}
742
arthursonzognif34adf092018-04-24 17:06:13743// Test that a browser-initiated navigation is canceled if a renderer-initiated
744// user-initiated request has been issued in the meantime.
Camille Lamy07c49cdf2019-03-11 15:53:57745TEST_F(NavigatorTest, RendererUserInitiatedNavigationCancel) {
carloskf4707892015-02-19 18:47:40746 const GURL kUrl0("http://www.wikipedia.org/");
747 const GURL kUrl1("http://www.chromium.org/");
748 const GURL kUrl2("http://www.google.com/");
749
750 // Initialization.
751 contents()->NavigateAndCommit(kUrl0);
752 FrameTreeNode* node = main_test_rfh()->frame_tree_node();
Aaron Colwell5fb878042020-12-17 19:48:44753 bool expect_site_instance_change =
754 ExpectSiteInstanceChange(main_test_rfh()->GetSiteInstance());
carloskf4707892015-02-19 18:47:40755
Antonio Gomes8678a202020-03-02 20:03:25756 // Start a browser-initiated navigation to the 1st URL and invoke its
757 // beforeUnload completion callback.
Nasko Oskov2e9e0112020-12-22 21:34:43758 EXPECT_FALSE(node->navigation_request());
Arthur Hemery56fb25c2019-02-08 17:55:13759 auto navigation2 =
760 NavigationSimulator::CreateBrowserInitiated(kUrl1, contents());
761 navigation2->Start();
clamydcb434c12015-04-16 19:29:16762 NavigationRequest* request1 = node->navigation_request();
carloskf4707892015-02-19 18:47:40763 ASSERT_TRUE(request1);
764 EXPECT_EQ(kUrl1, request1->common_params().url);
765 EXPECT_TRUE(request1->browser_initiated());
766 base::WeakPtr<TestNavigationURLLoader> loader1 =
767 GetLoaderForNavigationRequest(request1)->AsWeakPtr();
768 EXPECT_TRUE(loader1);
769
carlosk42f59e62015-03-16 19:02:36770 // Confirm that a speculative RenderFrameHost was created.
771 ASSERT_TRUE(GetSpeculativeRenderFrameHost(node));
carloskf4707892015-02-19 18:47:40772
773 // Now receive a renderer-initiated user-initiated request. It should replace
774 // the current NavigationRequest.
arthursonzogni91439432017-08-16 16:32:37775 auto navigation =
776 NavigationSimulator::CreateRendererInitiated(kUrl2, main_test_rfh());
777 navigation->SetTransition(ui::PAGE_TRANSITION_LINK);
778 navigation->SetHasUserGesture(true);
779 navigation->Start();
clamydcb434c12015-04-16 19:29:16780 NavigationRequest* request2 = node->navigation_request();
carloskf4707892015-02-19 18:47:40781 ASSERT_TRUE(request2);
782 EXPECT_EQ(kUrl2, request2->common_params().url);
783 EXPECT_FALSE(request2->browser_initiated());
Arthur Hemery14a71ad22017-10-27 10:54:39784 EXPECT_TRUE(request2->common_params().has_user_gesture);
carloskf4707892015-02-19 18:47:40785
786 // Confirm that the first loader got destroyed.
787 EXPECT_FALSE(loader1);
788
clamy61dfb232016-02-26 18:08:49789 // Confirm that the speculative RenderFrameHost was destroyed in the non
790 // SitePerProcess case.
Aaron Colwell5fb878042020-12-17 19:48:44791 if (expect_site_instance_change) {
clamy61dfb232016-02-26 18:08:49792 EXPECT_TRUE(GetSpeculativeRenderFrameHost(node));
793 } else {
794 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
795 }
carloskf4707892015-02-19 18:47:40796
carloskf4707892015-02-19 18:47:40797 // Commit the navigation.
arthursonzogni91439432017-08-16 16:32:37798 navigation->Commit();
carloskf4707892015-02-19 18:47:40799
800 // Confirm that the commit corresponds to the new request.
801 ASSERT_TRUE(main_test_rfh());
802 EXPECT_EQ(kUrl2, contents()->GetLastCommittedURL());
carloskf4707892015-02-19 18:47:40803}
804
Arthur Hemery0dd65812019-08-01 14:18:45805// Tests that a renderer-initiated user-initiated navigation is
carloskf4707892015-02-19 18:47:40806// canceled if a renderer-initiated non-user-initiated request is issued in the
807// meantime.
Camille Lamy07c49cdf2019-03-11 15:53:57808TEST_F(NavigatorTest,
Nasko Oskov6cbfad52017-08-17 11:31:01809 RendererNonUserInitiatedNavigationCancelsRendererUserInitiated) {
carloskf4707892015-02-19 18:47:40810 const GURL kUrl0("http://www.wikipedia.org/");
811 const GURL kUrl1("http://www.chromium.org/");
812 const GURL kUrl2("http://www.google.com/");
813
814 // Initialization.
815 contents()->NavigateAndCommit(kUrl0);
816 FrameTreeNode* node = main_test_rfh()->frame_tree_node();
Aaron Colwell5fb878042020-12-17 19:48:44817 bool expect_site_instance_change =
818 ExpectSiteInstanceChange(main_test_rfh()->GetSiteInstance());
carloskf4707892015-02-19 18:47:40819
820 // Start a renderer-initiated user-initiated navigation to the 1st URL.
Nasko Oskov2e9e0112020-12-22 21:34:43821 EXPECT_FALSE(node->navigation_request());
arthursonzogni91439432017-08-16 16:32:37822 auto user_initiated_navigation =
823 NavigationSimulator::CreateRendererInitiated(kUrl1, main_test_rfh());
824 user_initiated_navigation->SetTransition(ui::PAGE_TRANSITION_LINK);
825 user_initiated_navigation->SetHasUserGesture(true);
826 user_initiated_navigation->Start();
clamydcb434c12015-04-16 19:29:16827 NavigationRequest* request1 = node->navigation_request();
carloskf4707892015-02-19 18:47:40828 ASSERT_TRUE(request1);
829 EXPECT_EQ(kUrl1, request1->common_params().url);
830 EXPECT_FALSE(request1->browser_initiated());
Arthur Hemery14a71ad22017-10-27 10:54:39831 EXPECT_TRUE(request1->common_params().has_user_gesture);
Aaron Colwell5fb878042020-12-17 19:48:44832 if (expect_site_instance_change) {
clamy61dfb232016-02-26 18:08:49833 EXPECT_TRUE(GetSpeculativeRenderFrameHost(node));
834 } else {
835 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
836 }
carloskf4707892015-02-19 18:47:40837
Nasko Oskov6cbfad52017-08-17 11:31:01838 // Now receive a renderer-initiated non-user-initiated request. The previous
839 // navigation should be replaced.
840 auto non_user_initiated_navigation =
841 NavigationSimulator::CreateRendererInitiated(kUrl2, main_test_rfh());
842 non_user_initiated_navigation->SetTransition(ui::PAGE_TRANSITION_LINK);
843 non_user_initiated_navigation->SetHasUserGesture(false);
844 non_user_initiated_navigation->Start();
845
clamydcb434c12015-04-16 19:29:16846 NavigationRequest* request2 = node->navigation_request();
carloskf4707892015-02-19 18:47:40847 ASSERT_TRUE(request2);
Nasko Oskov6cbfad52017-08-17 11:31:01848 EXPECT_NE(request1, request2);
849 EXPECT_EQ(kUrl2, request2->common_params().url);
carloskf4707892015-02-19 18:47:40850 EXPECT_FALSE(request2->browser_initiated());
Arthur Hemery14a71ad22017-10-27 10:54:39851 EXPECT_FALSE(request2->common_params().has_user_gesture);
Aaron Colwell5fb878042020-12-17 19:48:44852 if (expect_site_instance_change) {
clamy61dfb232016-02-26 18:08:49853 EXPECT_TRUE(GetSpeculativeRenderFrameHost(node));
854 } else {
855 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
856 }
carloskf4707892015-02-19 18:47:40857
carloskf4707892015-02-19 18:47:40858 // Commit the navigation.
Nasko Oskov6cbfad52017-08-17 11:31:01859 non_user_initiated_navigation->Commit();
860 EXPECT_EQ(kUrl2, contents()->GetLastCommittedURL());
carloskf4707892015-02-19 18:47:40861}
862
863// PlzNavigate: Test that a browser-initiated navigation is NOT canceled if a
864// renderer-initiated non-user-initiated request is issued in the meantime.
Camille Lamy07c49cdf2019-03-11 15:53:57865TEST_F(NavigatorTest,
carloskf4707892015-02-19 18:47:40866 RendererNonUserInitiatedNavigationDoesntCancelBrowserInitiated) {
867 const GURL kUrl0("http://www.wikipedia.org/");
868 const GURL kUrl1("http://www.chromium.org/");
869 const GURL kUrl2("http://www.google.com/");
870
871 // Initialization.
872 contents()->NavigateAndCommit(kUrl0);
873 FrameTreeNode* node = main_test_rfh()->frame_tree_node();
874
875 // Start a browser-initiated navigation to the 1st URL.
Nasko Oskov2e9e0112020-12-22 21:34:43876 EXPECT_FALSE(node->navigation_request());
Arthur Hemery859f3462019-01-29 16:29:07877 auto navigation =
878 NavigationSimulator::CreateBrowserInitiated(kUrl1, contents());
879 navigation->Start();
clamydcb434c12015-04-16 19:29:16880 NavigationRequest* request1 = node->navigation_request();
carloskf4707892015-02-19 18:47:40881 ASSERT_TRUE(request1);
882 EXPECT_EQ(kUrl1, request1->common_params().url);
883 EXPECT_TRUE(request1->browser_initiated());
Arthur Hemery859f3462019-01-29 16:29:07884 TestRenderFrameHost* speculative_rfh = GetSpeculativeRenderFrameHost(node);
885 ASSERT_TRUE(speculative_rfh);
carloskf4707892015-02-19 18:47:40886
887 // Now receive a renderer-initiated non-user-initiated request. Nothing should
888 // change.
Arthur Hemery7b67a972017-12-01 15:24:49889 main_test_rfh()->SendRendererInitiatedNavigationRequest(
890 kUrl2, false /* has_user_gesture */);
clamydcb434c12015-04-16 19:29:16891 NavigationRequest* request2 = node->navigation_request();
carloskf4707892015-02-19 18:47:40892 ASSERT_TRUE(request2);
893 EXPECT_EQ(request1, request2);
894 EXPECT_EQ(kUrl1, request2->common_params().url);
895 EXPECT_TRUE(request2->browser_initiated());
Arthur Hemery859f3462019-01-29 16:29:07896 EXPECT_TRUE(speculative_rfh);
carloskf4707892015-02-19 18:47:40897
Arthur Hemery859f3462019-01-29 16:29:07898 navigation->ReadyToCommit();
899 EXPECT_EQ(speculative_rfh->navigation_requests().size(), 1u);
900 EXPECT_EQ(main_test_rfh()->navigation_requests().size(), 0u);
carloskf4707892015-02-19 18:47:40901
Arthur Hemery859f3462019-01-29 16:29:07902 navigation->Commit();
carloskf4707892015-02-19 18:47:40903 EXPECT_EQ(kUrl1, contents()->GetLastCommittedURL());
904}
905
906// PlzNavigate: Test that a renderer-initiated non-user-initiated navigation is
907// canceled if a another similar request is issued in the meantime.
Camille Lamy07c49cdf2019-03-11 15:53:57908TEST_F(NavigatorTest,
carloskf4707892015-02-19 18:47:40909 RendererNonUserInitiatedNavigationCancelSimilarNavigation) {
910 const GURL kUrl0("http://www.wikipedia.org/");
911 const GURL kUrl1("http://www.chromium.org/");
912 const GURL kUrl2("http://www.google.com/");
913
914 // Initialization.
915 contents()->NavigateAndCommit(kUrl0);
916 FrameTreeNode* node = main_test_rfh()->frame_tree_node();
avib7348942015-12-25 20:57:10917 int32_t site_instance_id_0 = main_test_rfh()->GetSiteInstance()->GetId();
Aaron Colwell5fb878042020-12-17 19:48:44918 bool expect_site_instance_change =
919 ExpectSiteInstanceChange(main_test_rfh()->GetSiteInstance());
carloskf4707892015-02-19 18:47:40920
921 // Start a renderer-initiated non-user-initiated navigation to the 1st URL.
Nasko Oskov2e9e0112020-12-22 21:34:43922 EXPECT_FALSE(node->navigation_request());
arthursonzogni91439432017-08-16 16:32:37923 auto navigation1 =
924 NavigationSimulator::CreateRendererInitiated(kUrl1, main_test_rfh());
925 navigation1->SetTransition(ui::PageTransitionFromInt(
926 ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_CLIENT_REDIRECT));
927 navigation1->SetHasUserGesture(false);
928 navigation1->Start();
clamydcb434c12015-04-16 19:29:16929 NavigationRequest* request1 = node->navigation_request();
carloskf4707892015-02-19 18:47:40930 ASSERT_TRUE(request1);
931 EXPECT_EQ(kUrl1, request1->common_params().url);
932 EXPECT_FALSE(request1->browser_initiated());
Arthur Hemery14a71ad22017-10-27 10:54:39933 EXPECT_FALSE(request1->common_params().has_user_gesture);
Aaron Colwell5fb878042020-12-17 19:48:44934 if (expect_site_instance_change) {
clamy61dfb232016-02-26 18:08:49935 EXPECT_TRUE(GetSpeculativeRenderFrameHost(node));
936 } else {
937 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
938 }
carloskf4707892015-02-19 18:47:40939 base::WeakPtr<TestNavigationURLLoader> loader1 =
940 GetLoaderForNavigationRequest(request1)->AsWeakPtr();
941 EXPECT_TRUE(loader1);
942
943 // Now receive a 2nd similar request that should replace the current one.
arthursonzogni91439432017-08-16 16:32:37944 auto navigation2 =
945 NavigationSimulator::CreateRendererInitiated(kUrl2, main_test_rfh());
946 navigation2->SetTransition(ui::PageTransitionFromInt(
947 ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_CLIENT_REDIRECT));
948 navigation2->SetHasUserGesture(false);
949 navigation2->Start();
clamydcb434c12015-04-16 19:29:16950 NavigationRequest* request2 = node->navigation_request();
carloskf4707892015-02-19 18:47:40951 EXPECT_EQ(kUrl2, request2->common_params().url);
952 EXPECT_FALSE(request2->browser_initiated());
Arthur Hemery14a71ad22017-10-27 10:54:39953 EXPECT_FALSE(request2->common_params().has_user_gesture);
Aaron Colwell5fb878042020-12-17 19:48:44954 if (expect_site_instance_change) {
clamy61dfb232016-02-26 18:08:49955 EXPECT_TRUE(GetSpeculativeRenderFrameHost(node));
956 } else {
957 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
958 }
carloskf4707892015-02-19 18:47:40959
960 // Confirm that the first loader got destroyed.
961 EXPECT_FALSE(loader1);
962
carloskf4707892015-02-19 18:47:40963 // Commit the navigation.
arthursonzogni91439432017-08-16 16:32:37964 navigation2->Commit();
carloskf4707892015-02-19 18:47:40965 EXPECT_EQ(kUrl2, contents()->GetLastCommittedURL());
carlosk42f59e62015-03-16 19:02:36966
Aaron Colwell5fb878042020-12-17 19:48:44967 if (expect_site_instance_change) {
arthursonzogni91439432017-08-16 16:32:37968 EXPECT_NE(site_instance_id_0, main_test_rfh()->GetSiteInstance()->GetId());
969 } else {
970 EXPECT_EQ(site_instance_id_0, main_test_rfh()->GetSiteInstance()->GetId());
971 }
carloskf4707892015-02-19 18:47:40972}
973
clamy71a42ec2014-10-02 18:43:22974// PlzNavigate: Test that a reload navigation is properly signaled to the
carlosk39337112015-01-14 21:44:51975// RenderFrame when the navigation can commit. A speculative RenderFrameHost
976// should not be created at any step.
Camille Lamy07c49cdf2019-03-11 15:53:57977TEST_F(NavigatorTest, Reload) {
clamy71a42ec2014-10-02 18:43:22978 const GURL kUrl("http://www.google.com/");
979 contents()->NavigateAndCommit(kUrl);
980
clamy71a42ec2014-10-02 18:43:22981 FrameTreeNode* node = main_test_rfh()->frame_tree_node();
toyoshim6142d96f2016-12-19 09:07:25982 controller().Reload(ReloadType::NORMAL, false);
Camille Lamy07c49cdf2019-03-11 15:53:57983 auto reload1 = NavigationSimulator::CreateFromPending(contents());
clamy71a42ec2014-10-02 18:43:22984 // A NavigationRequest should have been generated.
clamydcb434c12015-04-16 19:29:16985 NavigationRequest* main_request = node->navigation_request();
Ivan Kotenkov2c0d2bb32017-11-01 15:41:28986 ASSERT_TRUE(main_request != nullptr);
Lucas Furukawa Gadanief8290a2019-07-29 20:27:51987 EXPECT_EQ(mojom::NavigationType::RELOAD,
toyoshim980f11702016-12-02 08:15:53988 main_request->common_params().navigation_type);
Camille Lamy07c49cdf2019-03-11 15:53:57989 reload1->ReadyToCommit();
carlosk39337112015-01-14 21:44:51990 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
991
Camille Lamy07c49cdf2019-03-11 15:53:57992 reload1->Commit();
carlosk39337112015-01-14 21:44:51993 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
clamy71a42ec2014-10-02 18:43:22994
995 // Now do a shift+reload.
toyoshim6142d96f2016-12-19 09:07:25996 controller().Reload(ReloadType::BYPASSING_CACHE, false);
Camille Lamy07c49cdf2019-03-11 15:53:57997 auto reload2 = NavigationSimulator::CreateFromPending(contents());
clamy71a42ec2014-10-02 18:43:22998 // A NavigationRequest should have been generated.
clamydcb434c12015-04-16 19:29:16999 main_request = node->navigation_request();
Ivan Kotenkov2c0d2bb32017-11-01 15:41:281000 ASSERT_TRUE(main_request != nullptr);
Lucas Furukawa Gadanief8290a2019-07-29 20:27:511001 EXPECT_EQ(mojom::NavigationType::RELOAD_BYPASSING_CACHE,
clamy71a42ec2014-10-02 18:43:221002 main_request->common_params().navigation_type);
Camille Lamy07c49cdf2019-03-11 15:53:571003 reload2->ReadyToCommit();
carlosk39337112015-01-14 21:44:511004 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
1005}
1006
1007// PlzNavigate: Confirm that a speculative RenderFrameHost is used when
1008// navigating from one site to another.
Camille Lamy07c49cdf2019-03-11 15:53:571009TEST_F(NavigatorTest, SpeculativeRendererWorksBaseCase) {
carlosk39337112015-01-14 21:44:511010 // Navigate to an initial site.
1011 const GURL kUrlInit("http://wikipedia.org/");
1012 contents()->NavigateAndCommit(kUrlInit);
1013 FrameTreeNode* node = main_test_rfh()->frame_tree_node();
1014
1015 // Begin navigating to another site.
1016 const GURL kUrl("http://google.com/");
Nasko Oskov2e9e0112020-12-22 21:34:431017 EXPECT_FALSE(node->navigation_request());
Arthur Hemery859f3462019-01-29 16:29:071018 auto navigation =
1019 NavigationSimulator::CreateBrowserInitiated(kUrl, contents());
1020 navigation->Start();
carlosk39337112015-01-14 21:44:511021 TestRenderFrameHost* speculative_rfh = GetSpeculativeRenderFrameHost(node);
Arthur Hemery859f3462019-01-29 16:29:071022 int32_t site_instance_id = speculative_rfh->GetSiteInstance()->GetId();
carlosk39337112015-01-14 21:44:511023 ASSERT_TRUE(speculative_rfh);
1024 EXPECT_NE(speculative_rfh, main_test_rfh());
Aaron Colwellf45e3a852019-06-06 00:48:271025 if (AreDefaultSiteInstancesEnabled()) {
1026 EXPECT_TRUE(speculative_rfh->GetSiteInstance()->IsDefaultSiteInstance());
1027 } else {
Aaron Colwell91e32b12021-02-17 01:40:561028 EXPECT_EQ(CreateExpectedSiteInfo(kUrl),
1029 speculative_rfh->GetSiteInstance()->GetSiteInfo());
Aaron Colwellf45e3a852019-06-06 00:48:271030 }
carlosk39337112015-01-14 21:44:511031
Arthur Hemery859f3462019-01-29 16:29:071032 navigation->ReadyToCommit();
1033 EXPECT_EQ(speculative_rfh->navigation_requests().size(), 1u);
carlosk39337112015-01-14 21:44:511034
Arthur Hemery859f3462019-01-29 16:29:071035 // Ask the navigation to commit.
1036 navigation->Commit();
carlosk39337112015-01-14 21:44:511037 EXPECT_EQ(site_instance_id, main_test_rfh()->GetSiteInstance()->GetId());
1038 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
carlosk39337112015-01-14 21:44:511039}
1040
1041// PlzNavigate: Confirm that a speculative RenderFrameHost is thrown away when
1042// the final URL's site differs from the initial one due to redirects.
Camille Lamy07c49cdf2019-03-11 15:53:571043TEST_F(NavigatorTest, SpeculativeRendererDiscardedAfterRedirectToAnotherSite) {
carlosk39337112015-01-14 21:44:511044 // Navigate to an initial site.
1045 const GURL kUrlInit("http://wikipedia.org/");
1046 contents()->NavigateAndCommit(kUrlInit);
1047 FrameTreeNode* node = main_test_rfh()->frame_tree_node();
avib7348942015-12-25 20:57:101048 int32_t init_site_instance_id = main_test_rfh()->GetSiteInstance()->GetId();
carlosk39337112015-01-14 21:44:511049
1050 // Begin navigating to another site.
1051 const GURL kUrl("http://google.com/");
Nasko Oskov2e9e0112020-12-22 21:34:431052 EXPECT_FALSE(node->navigation_request());
Arthur Hemery859f3462019-01-29 16:29:071053 auto navigation =
1054 NavigationSimulator::CreateBrowserInitiated(kUrl, contents());
1055 navigation->Start();
1056
carlosk39337112015-01-14 21:44:511057 TestRenderFrameHost* speculative_rfh = GetSpeculativeRenderFrameHost(node);
carloskc49005eb2015-06-16 11:25:071058 ASSERT_TRUE(speculative_rfh);
avib7348942015-12-25 20:57:101059 int32_t site_instance_id = speculative_rfh->GetSiteInstance()->GetId();
carloska0350db2015-07-30 20:10:571060 RenderFrameDeletedObserver rfh_deleted_observer(speculative_rfh);
carlosk39337112015-01-14 21:44:511061 EXPECT_NE(init_site_instance_id, site_instance_id);
1062 EXPECT_EQ(init_site_instance_id, main_test_rfh()->GetSiteInstance()->GetId());
carlosk39337112015-01-14 21:44:511063 EXPECT_NE(speculative_rfh, main_test_rfh());
Aaron Colwellf45e3a852019-06-06 00:48:271064
1065 if (AreDefaultSiteInstancesEnabled()) {
1066 EXPECT_TRUE(speculative_rfh->GetSiteInstance()->IsDefaultSiteInstance());
1067 } else {
Aaron Colwell91e32b12021-02-17 01:40:561068 EXPECT_EQ(CreateExpectedSiteInfo(kUrl),
1069 speculative_rfh->GetSiteInstance()->GetSiteInfo());
Aaron Colwellf45e3a852019-06-06 00:48:271070 }
carlosk39337112015-01-14 21:44:511071
1072 // It then redirects to yet another site.
clamydcb434c12015-04-16 19:29:161073 NavigationRequest* main_request = node->navigation_request();
carlosk39337112015-01-14 21:44:511074 ASSERT_TRUE(main_request);
1075 const GURL kUrlRedirect("https://www.google.com/");
Arthur Hemery859f3462019-01-29 16:29:071076 navigation->Redirect(kUrlRedirect);
carlosk39337112015-01-14 21:44:511077 EXPECT_EQ(init_site_instance_id, main_test_rfh()->GetSiteInstance()->GetId());
carlosk39337112015-01-14 21:44:511078
carloskf4707892015-02-19 18:47:401079 // For now, ensure that the speculative RenderFrameHost does not change after
1080 // the redirect.
carlosk39337112015-01-14 21:44:511081 // TODO(carlosk): once the speculative RenderFrameHost updates with redirects
1082 // this next check will be changed to verify that it actually happens.
carloskc49005eb2015-06-16 11:25:071083 EXPECT_EQ(speculative_rfh, GetSpeculativeRenderFrameHost(node));
carlosk39337112015-01-14 21:44:511084 EXPECT_EQ(site_instance_id, speculative_rfh->GetSiteInstance()->GetId());
carloska0350db2015-07-30 20:10:571085 EXPECT_FALSE(rfh_deleted_observer.deleted());
carlosk39337112015-01-14 21:44:511086
Arthur Hemery859f3462019-01-29 16:29:071087 // Send the commit to the renderer.
1088 navigation->ReadyToCommit();
Aaron Colwellf45e3a852019-06-06 00:48:271089
1090 // Once commit happens the speculative RenderFrameHost is updated to match the
1091 // known final SiteInstance.
carlosk39337112015-01-14 21:44:511092 speculative_rfh = GetSpeculativeRenderFrameHost(node);
carloskc49005eb2015-06-16 11:25:071093 ASSERT_TRUE(speculative_rfh);
Arthur Hemery859f3462019-01-29 16:29:071094 EXPECT_EQ(speculative_rfh->navigation_requests().size(), 1u);
carlosk39337112015-01-14 21:44:511095 EXPECT_EQ(init_site_instance_id, main_test_rfh()->GetSiteInstance()->GetId());
1096
avib7348942015-12-25 20:57:101097 int32_t redirect_site_instance_id =
1098 speculative_rfh->GetSiteInstance()->GetId();
Aaron Colwellf45e3a852019-06-06 00:48:271099
1100 // Expect the initial and redirect SiteInstances to be different because
1101 // they should be associated with different BrowsingInstances.
carlosk39337112015-01-14 21:44:511102 EXPECT_NE(init_site_instance_id, redirect_site_instance_id);
Aaron Colwellf45e3a852019-06-06 00:48:271103
1104 if (AreDefaultSiteInstancesEnabled()) {
1105 EXPECT_TRUE(speculative_rfh->GetSiteInstance()->IsDefaultSiteInstance());
1106 EXPECT_EQ(site_instance_id, redirect_site_instance_id);
1107
1108 // Verify the old speculative RenderFrameHost was not deleted because
1109 // the SiteInstance stayed the same.
1110 EXPECT_FALSE(rfh_deleted_observer.deleted());
1111 } else {
Aaron Colwell91e32b12021-02-17 01:40:561112 EXPECT_EQ(CreateExpectedSiteInfo(kUrlRedirect),
1113 speculative_rfh->GetSiteInstance()->GetSiteInfo());
Aaron Colwellf45e3a852019-06-06 00:48:271114 EXPECT_NE(site_instance_id, redirect_site_instance_id);
1115
1116 // Verify the old speculative RenderFrameHost was deleted because
1117 // the SiteInstance changed.
1118 EXPECT_TRUE(rfh_deleted_observer.deleted());
1119 }
carlosk39337112015-01-14 21:44:511120
Balazs Engedya40712f2017-09-15 15:01:111121 // Invoke DidCommitProvisionalLoad.
Arthur Hemery859f3462019-01-29 16:29:071122 navigation->Commit();
carlosk39337112015-01-14 21:44:511123
1124 // Check that the speculative RenderFrameHost was swapped in.
1125 EXPECT_EQ(redirect_site_instance_id,
1126 main_test_rfh()->GetSiteInstance()->GetId());
1127 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
1128}
1129
clamy4cc9b8202015-03-02 13:51:361130// PlzNavigate: Verify that data urls are properly handled.
Camille Lamy07c49cdf2019-03-11 15:53:571131TEST_F(NavigatorTest, DataUrls) {
clamy4cc9b8202015-03-02 13:51:361132 const GURL kUrl1("http://wikipedia.org/");
1133 const GURL kUrl2("data:text/html,test");
1134
Aaron Colwelle953e562019-07-24 16:47:361135 // Isolate kUrl1 so it can't be mapped into a default SiteInstance along with
1136 // kUrl2. This ensures that the speculative RenderFrameHost will always be
1137 // used because the URLs map to different SiteInstances.
Alex Moshchukef8c2562021-03-12 06:37:451138 ChildProcessSecurityPolicy::GetInstance()->AddFutureIsolatedOrigins(
Aaron Colwelle953e562019-07-24 16:47:361139 {url::Origin::Create(kUrl1)},
1140 ChildProcessSecurityPolicy::IsolatedOriginSource::TEST,
1141 browser_context());
1142
clamy4cc9b8202015-03-02 13:51:361143 // Navigate to an initial site.
1144 contents()->NavigateAndCommit(kUrl1);
1145 FrameTreeNode* node = main_test_rfh()->frame_tree_node();
1146
Aaron Colwelle953e562019-07-24 16:47:361147 EXPECT_FALSE(main_test_rfh()->GetSiteInstance()->IsDefaultSiteInstance());
1148
arthursonzogni07499382016-09-20 10:24:291149 // Navigate to a data url. The request should have been sent to the IO
1150 // thread and not committed immediately.
Arthur Hemery56fb25c2019-02-08 17:55:131151 auto navigation =
1152 NavigationSimulator::CreateBrowserInitiated(kUrl2, contents());
1153 navigation->Start();
clamy4cc9b8202015-03-02 13:51:361154 TestRenderFrameHost* speculative_rfh = GetSpeculativeRenderFrameHost(node);
1155 ASSERT_TRUE(speculative_rfh);
arthursonzogni07499382016-09-20 10:24:291156 EXPECT_FALSE(speculative_rfh->is_loading());
1157 EXPECT_TRUE(node->navigation_request());
Arthur Hemery56fb25c2019-02-08 17:55:131158 navigation->ReadyToCommit();
clamyefdb7a42015-07-01 16:55:471159 EXPECT_TRUE(speculative_rfh->is_loading());
1160 EXPECT_FALSE(node->navigation_request());
arthursonzogni07499382016-09-20 10:24:291161 EXPECT_NE(main_test_rfh(), speculative_rfh);
Arthur Hemery56fb25c2019-02-08 17:55:131162 navigation->Commit();
clamy4cc9b8202015-03-02 13:51:361163 EXPECT_EQ(main_test_rfh(), speculative_rfh);
1164
1165 // Go back to the initial site.
1166 contents()->NavigateAndCommit(kUrl1);
1167
arthursonzogni07499382016-09-20 10:24:291168 // Do a renderer-initiated navigation to a data url. The request should be
1169 // sent to the IO thread.
arthursonzogni63aa3f372017-08-09 14:28:391170 auto navigation_to_data_url =
1171 NavigationSimulator::CreateRendererInitiated(kUrl2, main_test_rfh());
1172 navigation_to_data_url->Start();
Arthur Hemery70030a12019-08-05 10:51:161173 EXPECT_FALSE(main_test_rfh()->is_loading());
arthursonzogni07499382016-09-20 10:24:291174 EXPECT_TRUE(node->navigation_request());
carlosk42f59e62015-03-16 19:02:361175 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
clamy4cc9b8202015-03-02 13:51:361176}
1177
carlosk078298a82015-04-07 10:33:201178// Tests several cases for converting SiteInstanceDescriptors into
1179// SiteInstances:
1180// 1) Pointer to the current SiteInstance.
1181// 2) Pointer to an unrelated SiteInstance.
1182// 3) Same-site URL, related.
1183// 4) Cross-site URL, related.
1184// 5) Same-site URL, unrelated (with and without candidate SiteInstances).
1185// 6) Cross-site URL, unrelated (with candidate SiteInstance).
Camille Lamy07c49cdf2019-03-11 15:53:571186TEST_F(NavigatorTest, SiteInstanceDescriptionConversion) {
carlosk078298a82015-04-07 10:33:201187 // Navigate to set a current SiteInstance on the RenderFrameHost.
1188 GURL kUrl1("http://a.com");
Aaron Colwellf45e3a852019-06-06 00:48:271189 // Isolate one of the sites so the both can't be mapped to the default
1190 // site instance.
Alex Moshchukef8c2562021-03-12 06:37:451191 ChildProcessSecurityPolicy::GetInstance()->AddFutureIsolatedOrigins(
Alex Moshchukc4679422019-06-11 17:04:481192 {url::Origin::Create(kUrl1)},
1193 ChildProcessSecurityPolicy::IsolatedOriginSource::TEST,
Aaron Colwellf45e3a852019-06-06 00:48:271194 browser_context());
carlosk078298a82015-04-07 10:33:201195 contents()->NavigateAndCommit(kUrl1);
Aaron Colwell5fb878042020-12-17 19:48:441196 SiteInstanceImpl* current_instance = main_test_rfh()->GetSiteInstance();
carlosk078298a82015-04-07 10:33:201197 ASSERT_TRUE(current_instance);
1198
1199 // 1) Convert a descriptor pointing to the current instance.
1200 RenderFrameHostManager* rfhm =
1201 main_test_rfh()->frame_tree_node()->render_manager();
1202 {
1203 SiteInstanceDescriptor descriptor(current_instance);
dchengbccd6b82016-03-30 16:24:191204 scoped_refptr<SiteInstance> converted_instance =
carlosk078298a82015-04-07 10:33:201205 ConvertToSiteInstance(rfhm, descriptor, nullptr);
1206 EXPECT_EQ(current_instance, converted_instance);
1207 }
1208
1209 // 2) Convert a descriptor pointing an instance unrelated to the current one,
1210 // with a different site.
1211 GURL kUrl2("http://b.com");
1212 scoped_refptr<SiteInstance> unrelated_instance(
1213 SiteInstance::CreateForURL(browser_context(), kUrl2));
1214 EXPECT_FALSE(
1215 current_instance->IsRelatedSiteInstance(unrelated_instance.get()));
1216 {
1217 SiteInstanceDescriptor descriptor(unrelated_instance.get());
dchengbccd6b82016-03-30 16:24:191218 scoped_refptr<SiteInstance> converted_instance =
carlosk078298a82015-04-07 10:33:201219 ConvertToSiteInstance(rfhm, descriptor, nullptr);
1220 EXPECT_EQ(unrelated_instance.get(), converted_instance);
1221 }
1222
1223 // 3) Convert a descriptor of a related instance with the same site as the
1224 // current one.
1225 GURL kUrlSameSiteAs1("http://www.a.com/foo");
1226 {
Arthur Hemery2e1d149b2020-08-21 14:23:541227 SiteInstanceDescriptor descriptor(
W. James MacLean46cf26212020-10-01 16:43:371228 UrlInfo::CreateForTesting(kUrlSameSiteAs1),
1229 SiteInstanceRelation::RELATED,
Arthur Hemery920379612020-10-07 11:46:411230 CoopCoepCrossOriginIsolatedInfo::CreateNonIsolated());
dchengbccd6b82016-03-30 16:24:191231 scoped_refptr<SiteInstance> converted_instance =
carlosk078298a82015-04-07 10:33:201232 ConvertToSiteInstance(rfhm, descriptor, nullptr);
1233 EXPECT_EQ(current_instance, converted_instance);
1234 }
1235
1236 // 4) Convert a descriptor of a related instance with a site different from
1237 // the current one.
1238 GURL kUrlSameSiteAs2("http://www.b.com/foo");
Aaron Colwell91e32b12021-02-17 01:40:561239 scoped_refptr<SiteInstanceImpl> related_instance;
carlosk078298a82015-04-07 10:33:201240 {
Arthur Hemery2e1d149b2020-08-21 14:23:541241 SiteInstanceDescriptor descriptor(
W. James MacLean46cf26212020-10-01 16:43:371242 UrlInfo::CreateForTesting(kUrlSameSiteAs2),
1243 SiteInstanceRelation::RELATED,
Arthur Hemery920379612020-10-07 11:46:411244 CoopCoepCrossOriginIsolatedInfo::CreateNonIsolated());
carlosk078298a82015-04-07 10:33:201245 related_instance = ConvertToSiteInstance(rfhm, descriptor, nullptr);
Aaron Colwellddeccbdb2019-03-08 01:11:031246 // If kUrlSameSiteAs2 requires a dedicated process on this platform, this
1247 // should return a new instance, related to the current and set to the new
1248 // site URL.
1249 // Otherwise, this should return the default site instance
carlosk078298a82015-04-07 10:33:201250 EXPECT_TRUE(
1251 current_instance->IsRelatedSiteInstance(related_instance.get()));
1252 EXPECT_NE(current_instance, related_instance.get());
1253 EXPECT_NE(unrelated_instance.get(), related_instance.get());
Aaron Colwellddeccbdb2019-03-08 01:11:031254
Aaron Colwell5fb878042020-12-17 19:48:441255 if (AreDefaultSiteInstancesEnabled()) {
Aaron Colwell91e32b12021-02-17 01:40:561256 ASSERT_TRUE(related_instance->IsDefaultSiteInstance());
Aaron Colwellddeccbdb2019-03-08 01:11:031257 } else {
Aaron Colwell9d0f9392021-02-11 21:51:521258 EXPECT_EQ(SiteInfo::CreateForTesting(
Aaron Colwell5fb878042020-12-17 19:48:441259 current_instance->GetIsolationContext(), kUrlSameSiteAs2),
Aaron Colwell91e32b12021-02-17 01:40:561260 related_instance->GetSiteInfo());
Aaron Colwellddeccbdb2019-03-08 01:11:031261 }
carlosk078298a82015-04-07 10:33:201262 }
1263
1264 // 5) Convert a descriptor of an unrelated instance with the same site as the
1265 // current one, several times, with and without candidate sites.
1266 {
Arthur Hemery2e1d149b2020-08-21 14:23:541267 SiteInstanceDescriptor descriptor(
W. James MacLean46cf26212020-10-01 16:43:371268 UrlInfo::CreateForTesting(kUrlSameSiteAs1),
1269 SiteInstanceRelation::UNRELATED,
Arthur Hemery920379612020-10-07 11:46:411270 CoopCoepCrossOriginIsolatedInfo::CreateNonIsolated());
Aaron Colwell91e32b12021-02-17 01:40:561271 scoped_refptr<SiteInstanceImpl> converted_instance_1 =
carlosk078298a82015-04-07 10:33:201272 ConvertToSiteInstance(rfhm, descriptor, nullptr);
1273 // Should return a new instance, unrelated to the current one, set to the
1274 // provided site URL.
1275 EXPECT_FALSE(
1276 current_instance->IsRelatedSiteInstance(converted_instance_1.get()));
1277 EXPECT_NE(current_instance, converted_instance_1.get());
1278 EXPECT_NE(unrelated_instance.get(), converted_instance_1.get());
Aaron Colwell91e32b12021-02-17 01:40:561279 EXPECT_EQ(CreateExpectedSiteInfo(kUrlSameSiteAs1),
1280 converted_instance_1->GetSiteInfo());
carlosk078298a82015-04-07 10:33:201281
1282 // Does the same but this time using unrelated_instance as a candidate,
1283 // which has a different site.
Aaron Colwell91e32b12021-02-17 01:40:561284 scoped_refptr<SiteInstanceImpl> converted_instance_2 =
carlosk078298a82015-04-07 10:33:201285 ConvertToSiteInstance(rfhm, descriptor, unrelated_instance.get());
1286 // Should return yet another new instance, unrelated to the current one, set
1287 // to the same site URL.
1288 EXPECT_FALSE(
1289 current_instance->IsRelatedSiteInstance(converted_instance_2.get()));
1290 EXPECT_NE(current_instance, converted_instance_2.get());
1291 EXPECT_NE(unrelated_instance.get(), converted_instance_2.get());
1292 EXPECT_NE(converted_instance_1.get(), converted_instance_2.get());
Aaron Colwell91e32b12021-02-17 01:40:561293 EXPECT_EQ(CreateExpectedSiteInfo(kUrlSameSiteAs1),
1294 converted_instance_1->GetSiteInfo());
carlosk078298a82015-04-07 10:33:201295
1296 // Converts once more but with |converted_instance_1| as a candidate.
dchengbccd6b82016-03-30 16:24:191297 scoped_refptr<SiteInstance> converted_instance_3 =
carlosk078298a82015-04-07 10:33:201298 ConvertToSiteInstance(rfhm, descriptor, converted_instance_1.get());
1299 // Should return |converted_instance_1| because its site matches and it is
1300 // unrelated to the current SiteInstance.
1301 EXPECT_EQ(converted_instance_1.get(), converted_instance_3);
1302 }
1303
1304 // 6) Convert a descriptor of an unrelated instance with the same site of
1305 // related_instance and using it as a candidate.
1306 {
Arthur Hemery2e1d149b2020-08-21 14:23:541307 SiteInstanceDescriptor descriptor(
W. James MacLean46cf26212020-10-01 16:43:371308 UrlInfo::CreateForTesting(kUrlSameSiteAs2),
1309 SiteInstanceRelation::UNRELATED,
Arthur Hemery920379612020-10-07 11:46:411310 CoopCoepCrossOriginIsolatedInfo::CreateNonIsolated());
Aaron Colwell91e32b12021-02-17 01:40:561311 scoped_refptr<SiteInstanceImpl> converted_instance_1 =
carlosk078298a82015-04-07 10:33:201312 ConvertToSiteInstance(rfhm, descriptor, related_instance.get());
1313 // Should return a new instance, unrelated to the current, set to the
1314 // provided site URL.
1315 EXPECT_FALSE(
1316 current_instance->IsRelatedSiteInstance(converted_instance_1.get()));
1317 EXPECT_NE(related_instance.get(), converted_instance_1.get());
1318 EXPECT_NE(unrelated_instance.get(), converted_instance_1.get());
Aaron Colwellf45e3a852019-06-06 00:48:271319
1320 if (AreDefaultSiteInstancesEnabled()) {
Aaron Colwell91e32b12021-02-17 01:40:561321 EXPECT_TRUE(converted_instance_1->IsDefaultSiteInstance());
Aaron Colwellf45e3a852019-06-06 00:48:271322 } else {
Aaron Colwell91e32b12021-02-17 01:40:561323 EXPECT_EQ(CreateExpectedSiteInfo(kUrlSameSiteAs2),
1324 converted_instance_1->GetSiteInfo());
Aaron Colwellf45e3a852019-06-06 00:48:271325 }
carlosk078298a82015-04-07 10:33:201326
dchengbccd6b82016-03-30 16:24:191327 scoped_refptr<SiteInstance> converted_instance_2 =
carlosk078298a82015-04-07 10:33:201328 ConvertToSiteInstance(rfhm, descriptor, unrelated_instance.get());
1329 // Should return |unrelated_instance| because its site matches and it is
1330 // unrelated to the current SiteInstance.
1331 EXPECT_EQ(unrelated_instance.get(), converted_instance_2);
1332 }
1333}
1334
gzobqq8be1ff12016-03-01 17:12:011335// A renderer process might try and claim that a cross site navigation was
Balazs Engedya40712f2017-09-15 15:01:111336// within the same document by setting was_within_same_document = true in
arthursonzogni73fe3212020-11-17 13:24:071337// DidCommitProvisionalLoadParams. Such case should be detected on the browser
1338// side and the renderer process should be killed.
Camille Lamy07c49cdf2019-03-11 15:53:571339TEST_F(NavigatorTest, CrossSiteClaimWithinPage) {
gzobqq8be1ff12016-03-01 17:12:011340 const GURL kUrl1("http://www.chromium.org/");
1341 const GURL kUrl2("http://www.google.com/");
1342
Arthur Hemery7b0ae492018-02-05 16:04:451343 NavigationSimulator::NavigateAndCommitFromBrowser(contents(), kUrl1);
gzobqq8be1ff12016-03-01 17:12:011344
Arthur Hemery7b0ae492018-02-05 16:04:451345 // Navigate to a different site and claim that the navigation was within same
1346 // page.
gzobqq8be1ff12016-03-01 17:12:011347 int bad_msg_count = process()->bad_msg_count();
Arthur Hemery7b0ae492018-02-05 16:04:451348 auto simulator =
1349 NavigationSimulator::CreateRendererInitiated(kUrl2, main_test_rfh());
1350 simulator->CommitSameDocument();
gzobqq8be1ff12016-03-01 17:12:011351 EXPECT_EQ(process()->bad_msg_count(), bad_msg_count + 1);
1352}
1353
clamy9e542ce2016-09-23 23:26:041354// Tests that an ongoing NavigationRequest is deleted when a same-site
1355// user-initiated navigation commits.
Camille Lamy07c49cdf2019-03-11 15:53:571356TEST_F(NavigatorTest, NavigationRequestDeletedWhenUserInitiatedCommits) {
clamy9e542ce2016-09-23 23:26:041357 const GURL kUrl1("http://www.chromium.org/");
1358 const GURL kUrl2("http://www.chromium.org/foo");
1359 const GURL kUrl3("http://www.google.com/");
1360
1361 contents()->NavigateAndCommit(kUrl1);
1362 FrameTreeNode* node = main_test_rfh()->frame_tree_node();
1363
Rakina Zata Amni1d15cfb2020-08-05 02:32:551364 // The test below only makes sense if the same-site navigation below will not
1365 // create a speculative RFH, so we need to ensure that we won't trigger a
1366 // same-site cross-RFH navigation.
1367 // Note: this will not disable RenderDocument.
1368 // TODO(crbug.com/936696): Skip this test when main-frame RenderDocument is
1369 // enabled.
1370 DisableProactiveBrowsingInstanceSwapFor(main_test_rfh());
1371
clamy9e542ce2016-09-23 23:26:041372 // Navigate same-site.
Arthur Hemery56fb25c2019-02-08 17:55:131373 auto navigation =
1374 NavigationSimulator::CreateBrowserInitiated(kUrl2, contents());
1375 navigation->ReadyToCommit();
clamy9e542ce2016-09-23 23:26:041376 EXPECT_TRUE(main_test_rfh()->is_loading());
1377 EXPECT_FALSE(node->navigation_request());
1378
1379 // Start a new cross-site navigation. The current RFH should still be trying
1380 // to commit the previous navigation, but we create a NavigationRequest in the
1381 // FrameTreeNode.
Arthur Hemery56fb25c2019-02-08 17:55:131382 auto navigation2 =
1383 NavigationSimulator::CreateBrowserInitiated(kUrl3, contents());
1384 navigation2->Start();
clamy9e542ce2016-09-23 23:26:041385 EXPECT_TRUE(main_test_rfh()->is_loading());
1386 EXPECT_TRUE(node->navigation_request());
1387 EXPECT_TRUE(GetSpeculativeRenderFrameHost(node));
1388
1389 // The first navigation commits. This should clear up the speculative RFH and
1390 // the ongoing NavigationRequest.
Arthur Hemery56fb25c2019-02-08 17:55:131391 navigation->Commit();
clamy9e542ce2016-09-23 23:26:041392 EXPECT_FALSE(node->navigation_request());
1393 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
1394}
1395
1396// Tests that an ongoing NavigationRequest is deleted when a cross-site
1397// navigation commits.
Camille Lamy07c49cdf2019-03-11 15:53:571398TEST_F(NavigatorTest, NavigationRequestDeletedWhenCrossSiteCommits) {
clamy9e542ce2016-09-23 23:26:041399 const GURL kUrl1("http://www.chromium.org/");
1400 const GURL kUrl2("http://www.google.com/");
1401 const GURL kUrl3("http://www.google.com/foo");
1402
1403 contents()->NavigateAndCommit(kUrl1);
1404 FrameTreeNode* node = main_test_rfh()->frame_tree_node();
1405
1406 // Navigate cross-site.
Arthur Hemery56fb25c2019-02-08 17:55:131407 auto navigation =
1408 NavigationSimulator::CreateBrowserInitiated(kUrl2, contents());
1409 navigation->ReadyToCommit();
clamy9e542ce2016-09-23 23:26:041410 TestRenderFrameHost* speculative_rfh = GetSpeculativeRenderFrameHost(node);
1411 ASSERT_TRUE(speculative_rfh);
1412 EXPECT_TRUE(speculative_rfh->is_loading());
1413 EXPECT_FALSE(node->navigation_request());
1414
1415 // Start a new cross-site navigation to the same-site as the ongoing
1416 // navigation. The speculative RFH should still be live and trying
1417 // to commit the previous navigation, and we create a NavigationRequest in the
1418 // FrameTreeNode.
Arthur Hemery56fb25c2019-02-08 17:55:131419 auto navigation2 =
1420 NavigationSimulator::CreateBrowserInitiated(kUrl3, contents());
1421 navigation2->Start();
clamy9e542ce2016-09-23 23:26:041422 TestRenderFrameHost* speculative_rfh_2 = GetSpeculativeRenderFrameHost(node);
1423 ASSERT_TRUE(speculative_rfh_2);
1424 EXPECT_EQ(speculative_rfh_2, speculative_rfh);
1425 EXPECT_TRUE(speculative_rfh->is_loading());
1426 EXPECT_TRUE(node->navigation_request());
1427
1428 // The first navigation commits. This should clear up the speculative RFH and
1429 // the ongoing NavigationRequest.
Arthur Hemery56fb25c2019-02-08 17:55:131430 navigation->Commit();
clamy9e542ce2016-09-23 23:26:041431 EXPECT_FALSE(node->navigation_request());
1432 EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
1433 EXPECT_EQ(speculative_rfh, main_test_rfh());
1434}
1435
Charlie Hu5130d25e2021-03-05 21:53:391436// Permissions Policy: Test that the permissions policy is reset when navigating
1437// pages within a site.
Charlie Hubb5943d2021-03-09 19:46:121438TEST_F(NavigatorTest, PermissionsPolicySameSiteNavigation) {
iclellandf46f88a2017-03-04 14:01:441439 const GURL kUrl1("http://www.chromium.org/");
1440 const GURL kUrl2("http://www.chromium.org/Home");
1441
1442 contents()->NavigateAndCommit(kUrl1);
1443
Charlie Hu5130d25e2021-03-05 21:53:391444 // Check the permissions policy before navigation.
Charlie Hue20fe2f2021-03-07 03:39:591445 const blink::PermissionsPolicy* original_permissions_policy =
1446 main_test_rfh()->permissions_policy();
1447 ASSERT_TRUE(original_permissions_policy);
iclellandf46f88a2017-03-04 14:01:441448
1449 // Navigate to the new URL.
1450 contents()->NavigateAndCommit(kUrl2);
1451
Charlie Hu5130d25e2021-03-05 21:53:391452 // Check the permissions policy after navigation.
Charlie Hue20fe2f2021-03-07 03:39:591453 const blink::PermissionsPolicy* final_permissions_policy =
1454 main_test_rfh()->permissions_policy();
1455 ASSERT_TRUE(final_permissions_policy);
1456 ASSERT_NE(original_permissions_policy, final_permissions_policy);
iclellandf46f88a2017-03-04 14:01:441457}
1458
Charlie Hu5130d25e2021-03-05 21:53:391459// Permissions Policy: Test that the permissions policy is not reset when
1460// navigating within a page.
Charlie Hubb5943d2021-03-09 19:46:121461TEST_F(NavigatorTest, PermissionsPolicyFragmentNavigation) {
iclellandf46f88a2017-03-04 14:01:441462 const GURL kUrl1("http://www.chromium.org/");
1463 const GURL kUrl2("http://www.chromium.org/#Home");
1464
1465 contents()->NavigateAndCommit(kUrl1);
1466
Charlie Hu5130d25e2021-03-05 21:53:391467 // Check the permissions policy before navigation.
Charlie Hue20fe2f2021-03-07 03:39:591468 const blink::PermissionsPolicy* original_permissions_policy =
1469 main_test_rfh()->permissions_policy();
1470 ASSERT_TRUE(original_permissions_policy);
iclellandf46f88a2017-03-04 14:01:441471
1472 // Navigate to the new URL.
1473 contents()->NavigateAndCommit(kUrl2);
1474
Charlie Hu5130d25e2021-03-05 21:53:391475 // Check the permissions policy after navigation.
Charlie Hue20fe2f2021-03-07 03:39:591476 const blink::PermissionsPolicy* final_permissions_policy =
1477 main_test_rfh()->permissions_policy();
1478 ASSERT_EQ(original_permissions_policy, final_permissions_policy);
iclellandf46f88a2017-03-04 14:01:441479}
1480
Charlie Hu5130d25e2021-03-05 21:53:391481// Permissions Policy: Test that the permissions policy is set correctly when
1482// inserting a new child frame.
Charlie Hubb5943d2021-03-09 19:46:121483TEST_F(NavigatorTest, PermissionsPolicyNewChild) {
Ian Clelland784f56a92017-04-24 17:25:031484 const GURL kUrl1("http://www.chromium.org/");
1485 const GURL kUrl2("http://www.chromium.org/Home");
1486
1487 contents()->NavigateAndCommit(kUrl1);
1488
Camille Lamyb8155002019-03-13 13:46:391489 // Simulate the navigation triggered by inserting a child frame into a page.
Ian Clelland784f56a92017-04-24 17:25:031490 TestRenderFrameHost* subframe_rfh =
1491 contents()->GetMainFrame()->AppendChild("child");
Camille Lamyb8155002019-03-13 13:46:391492 NavigationSimulator::NavigateAndCommitFromDocument(kUrl2, subframe_rfh);
Ian Clelland784f56a92017-04-24 17:25:031493
Charlie Hue20fe2f2021-03-07 03:39:591494 const blink::PermissionsPolicy* subframe_permissions_policy =
1495 subframe_rfh->permissions_policy();
1496 ASSERT_TRUE(subframe_permissions_policy);
1497 ASSERT_FALSE(subframe_permissions_policy->GetOriginForTest().opaque());
Ian Clelland784f56a92017-04-24 17:25:031498}
1499
Camille Lamy07c49cdf2019-03-11 15:53:571500TEST_F(NavigatorTest, TwoNavigationsRacingCommit) {
clamyd3bfdb02018-07-12 13:52:181501 const GURL kUrl1("http://www.chromium.org/");
1502 const GURL kUrl2("http://www.chromium.org/Home");
1503
1504 EXPECT_EQ(0u, contents()->GetMainFrame()->navigation_requests_.size());
1505
1506 // Have the first navigation reach ReadyToCommit.
1507 auto first_navigation =
1508 NavigationSimulator::CreateBrowserInitiated(kUrl1, contents());
1509 first_navigation->ReadyToCommit();
1510 EXPECT_EQ(1u, contents()->GetMainFrame()->navigation_requests_.size());
1511
1512 // A second navigation starts and reaches ReadyToCommit.
1513 auto second_navigation =
1514 NavigationSimulator::CreateBrowserInitiated(kUrl1, contents());
1515 second_navigation->ReadyToCommit();
1516 EXPECT_EQ(2u, contents()->GetMainFrame()->navigation_requests_.size());
1517
1518 // The first navigation commits.
1519 first_navigation->Commit();
1520 EXPECT_EQ(1u, contents()->GetMainFrame()->navigation_requests_.size());
1521
1522 // The second navigation commits.
1523 second_navigation->Commit();
1524 EXPECT_EQ(0u, contents()->GetMainFrame()->navigation_requests_.size());
1525}
1526
clamy71a42ec2014-10-02 18:43:221527} // namespace content