Index: content/browser/frame_host/navigator_impl_unittest.cc |
diff --git a/content/browser/frame_host/navigator_impl_unittest.cc b/content/browser/frame_host/navigator_impl_unittest.cc |
index e31ce22eb170c76e91378ca9d111bec52f4da125..dc9a43478f1851e49613fbf224dff0ffdc83c6f8 100644 |
--- a/content/browser/frame_host/navigator_impl_unittest.cc |
+++ b/content/browser/frame_host/navigator_impl_unittest.cc |
@@ -161,9 +161,9 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, |
contents()->NavigateAndCommit(kUrl1); |
EXPECT_TRUE(main_test_rfh()->IsRenderFrameLive()); |
- // Start a renderer-initiated navigation. |
+ // Start a renderer-initiated non-user-initiated navigation. |
process()->sink().ClearMessages(); |
- main_test_rfh()->SendBeginNavigationWithURL(kUrl2); |
+ main_test_rfh()->SendBeginNavigationWithURL(kUrl2, false); |
FrameTreeNode* node = main_test_rfh()->frame_tree_node(); |
NavigationRequest* request = GetNavigationRequestForFrameTreeNode(node); |
ASSERT_TRUE(request); |
@@ -171,6 +171,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, |
// The navigation is immediately started as there's no need to wait for |
// beforeUnload to be executed. |
EXPECT_EQ(NavigationRequest::STARTED, request->state()); |
+ EXPECT_FALSE(request->begin_params().has_user_gesture); |
EXPECT_EQ(kUrl2, request->common_params().url); |
EXPECT_FALSE(request->browser_initiated()); |
EXPECT_FALSE(GetSpeculativeRenderFrameHost(node)); |
@@ -375,9 +376,12 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, CrossSiteNavigation) { |
// Navigate to a different site. |
process()->sink().ClearMessages(); |
RequestNavigation(node, kUrl2); |
- main_test_rfh()->SendBeforeUnloadACK(true); |
NavigationRequest* main_request = GetNavigationRequestForFrameTreeNode(node); |
ASSERT_TRUE(main_request); |
+ EXPECT_FALSE(GetSpeculativeRenderFrameHost(node)); |
+ |
+ // Receive the beforeUnload ACK. |
+ main_test_rfh()->SendBeforeUnloadACK(true); |
EXPECT_TRUE(GetSpeculativeRenderFrameHost(node)); |
scoped_refptr<ResourceResponse> response(new ResourceResponse); |
@@ -475,6 +479,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, |
EXPECT_TRUE(request1->browser_initiated()); |
base::WeakPtr<TestNavigationURLLoader> loader1 = |
GetLoaderForNavigationRequest(request1)->AsWeakPtr(); |
+ EXPECT_TRUE(loader1); |
// Confirm a speculative RFH was created. |
TestRenderFrameHost* speculative_rfh = GetSpeculativeRenderFrameHost(node); |
@@ -519,6 +524,210 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, |
EXPECT_EQ(site_instance_id_2, main_test_rfh()->GetSiteInstance()->GetId()); |
} |
+// PlzNavigate: Test that a navigation is canceled if another renderer-initiated |
+// user-initiated request has been issued in the meantime. |
+TEST_F(NavigatorTestWithBrowserSideNavigation, |
+ RendererUserInitiatedNavigationCancel) { |
+ const GURL kUrl0("http://www.wikipedia.org/"); |
+ const GURL kUrl1("http://www.chromium.org/"); |
+ const GURL kUrl2("http://www.google.com/"); |
+ |
+ // Initialization. |
+ contents()->NavigateAndCommit(kUrl0); |
+ FrameTreeNode* node = main_test_rfh()->frame_tree_node(); |
+ |
+ // Start a browser-initiated navigation to the 1st URL and receive its |
+ // beforeUnload ACK. |
+ process()->sink().ClearMessages(); |
+ RequestNavigation(node, kUrl1); |
+ main_test_rfh()->SendBeforeUnloadACK(true); |
+ NavigationRequest* request1 = GetNavigationRequestForFrameTreeNode(node); |
+ ASSERT_TRUE(request1); |
+ EXPECT_EQ(kUrl1, request1->common_params().url); |
+ EXPECT_TRUE(request1->browser_initiated()); |
+ base::WeakPtr<TestNavigationURLLoader> loader1 = |
+ GetLoaderForNavigationRequest(request1)->AsWeakPtr(); |
+ EXPECT_TRUE(loader1); |
+ |
+ // Confirm a speculative RFH was created. |
+ TestRenderFrameHost* speculative_rfh = GetSpeculativeRenderFrameHost(node); |
+ ASSERT_TRUE(speculative_rfh); |
+ int32 site_instance_id_1 = speculative_rfh->GetSiteInstance()->GetId(); |
+ |
+ // Now receive a renderer-initiated user-initiated request. It should replace |
+ // the current NavigationRequest. |
+ main_test_rfh()->SendBeginNavigationWithURL(kUrl2, true); |
+ NavigationRequest* request2 = GetNavigationRequestForFrameTreeNode(node); |
+ ASSERT_TRUE(request2); |
+ EXPECT_EQ(kUrl2, request2->common_params().url); |
+ EXPECT_FALSE(request2->browser_initiated()); |
+ EXPECT_TRUE(request2->begin_params().has_user_gesture); |
+ |
+ // Confirm that the first loader got destroyed. |
+ EXPECT_FALSE(loader1); |
+ |
+ // Confirm that a new speculative RFH was created. |
+ speculative_rfh = GetSpeculativeRenderFrameHost(node); |
+ ASSERT_TRUE(speculative_rfh); |
+ int32 site_instance_id_2 = speculative_rfh->GetSiteInstance()->GetId(); |
+ EXPECT_NE(site_instance_id_1, site_instance_id_2); |
+ |
+ // Request the RenderFrameHost to commit. |
clamy
2015/02/13 14:56:35
nit: I would rephrase that as "Have the RenderFram
carlosk
2015/02/13 15:57:13
Done, here and everywhere else.
|
+ scoped_refptr<ResourceResponse> response(new ResourceResponse); |
+ GetLoaderForNavigationRequest(request2) |
+ ->CallOnResponseStarted(response, MakeEmptyStream()); |
+ EXPECT_TRUE(DidRenderFrameHostRequestCommit(speculative_rfh)); |
+ EXPECT_FALSE(DidRenderFrameHostRequestCommit(main_test_rfh())); |
+ |
+ // Commit the navigation. |
+ speculative_rfh->SendNavigate(0, kUrl2); |
+ |
+ // Confirm that the commit corresponds to the new request. |
+ ASSERT_TRUE(main_test_rfh()); |
+ EXPECT_EQ(kUrl2, contents()->GetLastCommittedURL()); |
+ |
+ // Confirm that the committed RFH is the latest speculative one. |
clamy
2015/02/13 14:56:35
nit: I would rephrase as "Confirm that the RFH tha
carlosk
2015/02/13 15:57:13
Done, here and everywhere else.
|
+ EXPECT_EQ(site_instance_id_2, main_test_rfh()->GetSiteInstance()->GetId()); |
+} |
+ |
+// PlzNavigate: Test that a renderer-initiated user-initiated navigation is NOT |
+// canceled if a renderer-initiated non-user-initiated request is issued in the |
+// meantime. |
+TEST_F(NavigatorTestWithBrowserSideNavigation, |
+ RendererNonUserInitiatedNavigationDoesntCancelRendererUserInitiated) { |
+ const GURL kUrl0("http://www.wikipedia.org/"); |
+ const GURL kUrl1("http://www.chromium.org/"); |
+ const GURL kUrl2("http://www.google.com/"); |
+ |
+ // Initialization. |
+ contents()->NavigateAndCommit(kUrl0); |
+ FrameTreeNode* node = main_test_rfh()->frame_tree_node(); |
+ |
+ // Start a renderer-initiated user-initiated navigation to the 1st URL. |
+ process()->sink().ClearMessages(); |
+ main_test_rfh()->SendBeginNavigationWithURL(kUrl1, true); |
+ NavigationRequest* request1 = GetNavigationRequestForFrameTreeNode(node); |
+ ASSERT_TRUE(request1); |
+ EXPECT_EQ(kUrl1, request1->common_params().url); |
+ EXPECT_FALSE(request1->browser_initiated()); |
+ EXPECT_TRUE(request1->begin_params().has_user_gesture); |
+ EXPECT_TRUE(GetSpeculativeRenderFrameHost(node)); |
+ |
+ // Now receive a renderer-initiated non-user-initiated request. Nothing should |
+ // change. |
+ main_test_rfh()->SendBeginNavigationWithURL(kUrl2, false); |
+ NavigationRequest* request2 = GetNavigationRequestForFrameTreeNode(node); |
+ ASSERT_TRUE(request2); |
+ EXPECT_EQ(request1, request2); |
+ EXPECT_EQ(kUrl1, request2->common_params().url); |
+ EXPECT_FALSE(request2->browser_initiated()); |
+ EXPECT_TRUE(request2->begin_params().has_user_gesture); |
+ TestRenderFrameHost* speculative_rfh = GetSpeculativeRenderFrameHost(node); |
+ ASSERT_TRUE(speculative_rfh); |
+ |
+ // Request the RenderFrameHost to commit. |
+ scoped_refptr<ResourceResponse> response(new ResourceResponse); |
+ GetLoaderForNavigationRequest(request2) |
+ ->CallOnResponseStarted(response, MakeEmptyStream()); |
+ EXPECT_TRUE(DidRenderFrameHostRequestCommit(speculative_rfh)); |
+ EXPECT_FALSE(DidRenderFrameHostRequestCommit(main_test_rfh())); |
+ |
+ // Commit the navigation. |
+ speculative_rfh->SendNavigate(0, kUrl1); |
+ EXPECT_EQ(kUrl1, contents()->GetLastCommittedURL()); |
+} |
+ |
+// PlzNavigate: Test that a browser-initiated navigation is NOT canceled if a |
+// renderer-initiated non-user-initiated request is issued in the meantime. |
+TEST_F(NavigatorTestWithBrowserSideNavigation, |
+ RendererNonUserInitiatedNavigationDoesntCancelBrowserInitiated) { |
+ const GURL kUrl0("http://www.wikipedia.org/"); |
+ const GURL kUrl1("http://www.chromium.org/"); |
+ const GURL kUrl2("http://www.google.com/"); |
+ |
+ // Initialization. |
+ contents()->NavigateAndCommit(kUrl0); |
+ FrameTreeNode* node = main_test_rfh()->frame_tree_node(); |
+ |
+ // Start a browser-initiated navigation to the 1st URL. |
+ process()->sink().ClearMessages(); |
+ RequestNavigation(node, kUrl1); |
+ NavigationRequest* request1 = GetNavigationRequestForFrameTreeNode(node); |
+ ASSERT_TRUE(request1); |
+ EXPECT_EQ(kUrl1, request1->common_params().url); |
+ EXPECT_TRUE(request1->browser_initiated()); |
+ EXPECT_FALSE(GetSpeculativeRenderFrameHost(node)); |
+ |
+ // Now receive a renderer-initiated non-user-initiated request. Nothing should |
+ // change. |
+ main_test_rfh()->SendBeginNavigationWithURL(kUrl2, false); |
+ NavigationRequest* request2 = GetNavigationRequestForFrameTreeNode(node); |
+ ASSERT_TRUE(request2); |
+ EXPECT_EQ(request1, request2); |
+ EXPECT_EQ(kUrl1, request2->common_params().url); |
+ EXPECT_TRUE(request2->browser_initiated()); |
+ EXPECT_FALSE(GetSpeculativeRenderFrameHost(node)); |
+ |
+ // Now receive the beforeUnload ACK from the still ongoing navigation. |
+ main_test_rfh()->SendBeforeUnloadACK(true); |
+ TestRenderFrameHost* speculative_rfh = GetSpeculativeRenderFrameHost(node); |
+ ASSERT_TRUE(speculative_rfh); |
+ |
+ // Request the RenderFrameHost to commit. |
+ scoped_refptr<ResourceResponse> response(new ResourceResponse); |
+ GetLoaderForNavigationRequest(request2) |
+ ->CallOnResponseStarted(response, MakeEmptyStream()); |
+ EXPECT_TRUE(DidRenderFrameHostRequestCommit(speculative_rfh)); |
+ EXPECT_FALSE(DidRenderFrameHostRequestCommit(main_test_rfh())); |
+ |
+ // Commit the navigation. |
+ speculative_rfh->SendNavigate(0, kUrl1); |
+ EXPECT_EQ(kUrl1, contents()->GetLastCommittedURL()); |
+} |
+ |
+// PlzNavigate: Test that a renderer-initiated non-user-initiated navigation is |
+// canceled if a another similar request is issued in the meantime. |
+TEST_F(NavigatorTestWithBrowserSideNavigation, |
+ RendererNonUserInitiatedNavigationCancelSimilarNavigation) { |
+ const GURL kUrl0("http://www.wikipedia.org/"); |
+ const GURL kUrl1("http://www.chromium.org/"); |
+ const GURL kUrl2("http://www.google.com/"); |
+ |
+ // Initialization. |
+ contents()->NavigateAndCommit(kUrl0); |
+ FrameTreeNode* node = main_test_rfh()->frame_tree_node(); |
+ |
+ // Start a renderer-initiated non-user-initiated navigation to the 1st URL. |
+ process()->sink().ClearMessages(); |
+ main_test_rfh()->SendBeginNavigationWithURL(kUrl1, false); |
+ NavigationRequest* request1 = GetNavigationRequestForFrameTreeNode(node); |
+ ASSERT_TRUE(request1); |
+ EXPECT_EQ(kUrl1, request1->common_params().url); |
+ EXPECT_FALSE(request1->browser_initiated()); |
+ EXPECT_FALSE(request1->begin_params().has_user_gesture); |
+ EXPECT_TRUE(GetSpeculativeRenderFrameHost(node)); |
+ |
+ // Now receive a 2nd similar request that should replace the current one. |
+ main_test_rfh()->SendBeginNavigationWithURL(kUrl2, false); |
+ NavigationRequest* request2 = GetNavigationRequestForFrameTreeNode(node); |
+ EXPECT_EQ(kUrl2, request2->common_params().url); |
+ EXPECT_FALSE(request2->browser_initiated()); |
+ EXPECT_FALSE(request2->begin_params().has_user_gesture); |
+ TestRenderFrameHost* speculative_rfh = GetSpeculativeRenderFrameHost(node); |
+ ASSERT_TRUE(speculative_rfh); |
+ |
+ // Request the RenderFrameHost to commit. |
+ scoped_refptr<ResourceResponse> response(new ResourceResponse); |
+ GetLoaderForNavigationRequest(request2) |
+ ->CallOnResponseStarted(response, MakeEmptyStream()); |
+ EXPECT_TRUE(DidRenderFrameHostRequestCommit(speculative_rfh)); |
+ EXPECT_FALSE(DidRenderFrameHostRequestCommit(main_test_rfh())); |
+ |
+ // Commit the navigation. |
+ speculative_rfh->SendNavigate(0, kUrl2); |
+ EXPECT_EQ(kUrl2, contents()->GetLastCommittedURL()); |
+} |
+ |
// PlzNavigate: Test that a reload navigation is properly signaled to the |
// RenderFrame when the navigation can commit. A speculative RenderFrameHost |
// should not be created at any step. |
@@ -567,6 +776,9 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, |
const GURL kUrl("http://google.com/"); |
process()->sink().ClearMessages(); |
RequestNavigation(node, kUrl); |
+ EXPECT_FALSE(GetSpeculativeRenderFrameHost(node)); |
+ |
+ // Receive the beforeUnload ACK. |
main_test_rfh()->SendBeforeUnloadACK(true); |
TestRenderFrameHost* speculative_rfh = GetSpeculativeRenderFrameHost(node); |
ASSERT_TRUE(speculative_rfh); |
@@ -608,6 +820,9 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, |
const GURL kUrl("http://google.com/"); |
process()->sink().ClearMessages(); |
RequestNavigation(node, kUrl); |
+ EXPECT_FALSE(GetSpeculativeRenderFrameHost(node)); |
+ |
+ // Receive the beforeUnload ACK. |
main_test_rfh()->SendBeforeUnloadACK(true); |
TestRenderFrameHost* speculative_rfh = GetSpeculativeRenderFrameHost(node); |
int32 site_instance_id = speculative_rfh->GetSiteInstance()->GetId(); |
@@ -698,6 +913,8 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, |
->sink() |
.ClearMessages(); |
RequestNavigation(node, kUrl1); |
+ EXPECT_FALSE(GetSpeculativeRenderFrameHost(node)); |
+ |
main_test_rfh()->SendBeforeUnloadACK(true); |
EXPECT_EQ(rfh1, GetSpeculativeRenderFrameHost(node)); |
EXPECT_NE(RenderFrameHostImpl::STATE_DEFAULT, |