Index: content/browser/frame_host/navigation_controller_impl_browsertest.cc |
diff --git a/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/content/browser/frame_host/navigation_controller_impl_browsertest.cc |
index 079902d6041b44b7db2351bb032e40ad9f45f36e..795402bbec2ecf91b397dd9271ffe20202563410 100644 |
--- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc |
+++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc |
@@ -6909,4 +6909,61 @@ IN_PROC_BROWSER_TEST_F(RequestMonitoringNavigationBrowserTest, |
testing::Key("X-ExtraHeadersVsSubresources")))); |
} |
+// Test that a same-page navigation does not lead to the deletion of the |
+// NavigationHandle for an ongoing different page navigation. |
+IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, |
+ SamePageNavigationDoesntDeleteNavigationHandle) { |
+ const GURL kURL1 = embedded_test_server()->GetURL("/title1.html"); |
+ const GURL kPushStateURL = |
+ embedded_test_server()->GetURL("/title1.html#fragment"); |
+ const GURL kURL2 = embedded_test_server()->GetURL("/title2.html"); |
+ |
+ // Navigate to the initial page. |
+ EXPECT_TRUE(NavigateToURL(shell(), kURL1)); |
+ RenderFrameHostImpl* main_frame = |
+ static_cast<WebContentsImpl*>(shell()->web_contents())->GetMainFrame(); |
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) |
+ ->GetFrameTree() |
+ ->root(); |
+ EXPECT_FALSE(main_frame->navigation_handle()); |
+ EXPECT_FALSE(root->navigation_request()); |
+ |
+ // Start navigating to the second page. |
+ TestNavigationManager manager(shell()->web_contents(), kURL2); |
+ shell()->web_contents()->GetController().LoadURL( |
+ kURL2, Referrer(), ui::PAGE_TRANSITION_LINK, std::string()); |
+ EXPECT_TRUE(manager.WaitForRequestStart()); |
+ |
+ // This should create a NavigationHandle. |
+ if (IsBrowserSideNavigationEnabled()) { |
+ EXPECT_TRUE(root->navigation_request()); |
+ } else { |
+ EXPECT_TRUE(main_frame->navigation_handle()); |
+ } |
+ |
+ // The current page does a PushState. |
+ std::string push_state = |
+ "var stateObj = {}; history.pushState(stateObj, \"title 1\", \"" + |
+ kPushStateURL.spec() + "\");"; |
+ EXPECT_TRUE(ExecuteScript(shell()->web_contents(), push_state)); |
+ NavigationEntry* last_committed = |
+ shell()->web_contents()->GetController().GetLastCommittedEntry(); |
+ ASSERT_TRUE(last_committed); |
+ EXPECT_EQ(kPushStateURL, last_committed->GetURL()); |
+ |
+ // This shouldn't affect the ongoing navigation. |
+ if (IsBrowserSideNavigationEnabled()) { |
+ EXPECT_TRUE(root->navigation_request()); |
+ } else { |
+ EXPECT_TRUE(main_frame->navigation_handle()); |
+ } |
+ |
+ // Let the navigation finish. It should commit successfully. |
+ manager.WaitForNavigationFinished(); |
+ last_committed = |
+ shell()->web_contents()->GetController().GetLastCommittedEntry(); |
+ ASSERT_TRUE(last_committed); |
+ EXPECT_EQ(kURL2, last_committed->GetURL()); |
+} |
+ |
} // namespace content |