| 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 301f27a133c1f85ab24fd1fb4ea454418030f86a..eaf23603df3715fbb5221a39e3292d4558074994 100644
|
| --- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc
|
| +++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
|
| @@ -1692,6 +1692,116 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
|
| }
|
| }
|
|
|
| +// Verify that the tree of FrameNavigationEntries is preserved after in-page
|
| +// navigations (both in the main frame and in subframes). Otherwise we cannot
|
| +// navigate in those subframes or add new subframes to them.
|
| +// See https://crbug.com/522193.
|
| +IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
|
| + FrameNavigationEntry_SubframeAfterInPage) {
|
| + // 1. Start on a page with a subframe.
|
| + GURL main_url(embedded_test_server()->GetURL(
|
| + "/navigation_controller/page_with_iframe.html"));
|
| + NavigateToURL(shell(), main_url);
|
| + const NavigationControllerImpl& controller =
|
| + static_cast<const NavigationControllerImpl&>(
|
| + shell()->web_contents()->GetController());
|
| + FrameTreeNode* root =
|
| + static_cast<WebContentsImpl*>(shell()->web_contents())->
|
| + GetFrameTree()->root();
|
| +
|
| + ASSERT_EQ(1U, root->child_count());
|
| + ASSERT_NE(nullptr, root->child_at(0));
|
| +
|
| + // Navigate to a real page in the subframe, so that the next navigation will
|
| + // be MANUAL_SUBFRAME.
|
| + GURL subframe_url(embedded_test_server()->GetURL(
|
| + "/navigation_controller/simple_page_1.html"));
|
| + {
|
| + LoadCommittedCapturer capturer(root->child_at(0));
|
| + NavigateFrameToURL(root->child_at(0), subframe_url);
|
| + capturer.Wait();
|
| + EXPECT_EQ(ui::PAGE_TRANSITION_AUTO_SUBFRAME, capturer.transition_type());
|
| + }
|
| +
|
| + // 2. In-page navigation in the main frame.
|
| + std::string push_script = "history.pushState({}, 'page 2', 'page_2.html')";
|
| + EXPECT_TRUE(content::ExecuteScript(root->current_frame_host(), push_script));
|
| + EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
|
| +
|
| + // Verify subframe entries if they're enabled (e.g. in --site-per-process).
|
| + EXPECT_EQ(2, controller.GetEntryCount());
|
| + NavigationEntryImpl* entry = controller.GetLastCommittedEntry();
|
| + if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
|
| + // The entry should still have a subframe entry.
|
| + ASSERT_EQ(1U, entry->root_node()->children.size());
|
| + FrameNavigationEntry* frame_entry =
|
| + entry->root_node()->children[0]->frame_entry.get();
|
| + EXPECT_EQ(subframe_url, frame_entry->url());
|
| + } else {
|
| + // There are no subframe FrameNavigationEntries by default.
|
| + EXPECT_EQ(0U, entry->root_node()->children.size());
|
| + }
|
| +
|
| + // 3. Add a nested subframe.
|
| + {
|
| + LoadCommittedCapturer capturer(shell()->web_contents());
|
| + std::string script = "var iframe = document.createElement('iframe');"
|
| + "iframe.src = '" + subframe_url.spec() + "';"
|
| + "document.body.appendChild(iframe);";
|
| + EXPECT_TRUE(content::ExecuteScript(root->child_at(0)->current_frame_host(),
|
| + script));
|
| + capturer.Wait();
|
| + EXPECT_EQ(ui::PAGE_TRANSITION_AUTO_SUBFRAME, capturer.transition_type());
|
| + }
|
| +
|
| + // Verify subframe entries if they're enabled (e.g. in --site-per-process).
|
| + EXPECT_EQ(2, controller.GetEntryCount());
|
| + entry = controller.GetLastCommittedEntry();
|
| + if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
|
| + // The entry should have two subframe FrameNavigationEntries, nested.
|
| + ASSERT_EQ(1U, entry->root_node()->children.size());
|
| + ASSERT_EQ(1U, entry->root_node()->children[0]->children.size());
|
| + FrameNavigationEntry* frame_entry =
|
| + entry->root_node()->children[0]->children[0]->frame_entry.get();
|
| + EXPECT_EQ(subframe_url, frame_entry->url());
|
| + } else {
|
| + // There are no subframe FrameNavigationEntries by default.
|
| + EXPECT_EQ(0U, entry->root_node()->children.size());
|
| + }
|
| +
|
| + // 4. Navigate in-page in subframe.
|
| + EXPECT_TRUE(content::ExecuteScript(root->child_at(0)->current_frame_host(),
|
| + push_script));
|
| + EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
|
| +
|
| + // Verify subframe entries if they're enabled (e.g. in --site-per-process).
|
| + EXPECT_EQ(3, controller.GetEntryCount());
|
| + entry = controller.GetLastCommittedEntry();
|
| + if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
|
| + // The entry should still have two subframe FrameNavigationEntries, nested.
|
| + ASSERT_EQ(1U, entry->root_node()->children.size());
|
| + ASSERT_EQ(1U, entry->root_node()->children[0]->children.size());
|
| + FrameNavigationEntry* frame_entry =
|
| + entry->root_node()->children[0]->children[0]->frame_entry.get();
|
| + EXPECT_EQ(subframe_url, frame_entry->url());
|
| + } else {
|
| + // There are no subframe FrameNavigationEntries by default.
|
| + EXPECT_EQ(0U, entry->root_node()->children.size());
|
| + }
|
| +
|
| + // 5. Navigate in innermost subframe.
|
| + GURL nested_url(embedded_test_server()->GetURL(
|
| + "/navigation_controller/simple_page_2.html"));
|
| + {
|
| + FrameNavigateParamsCapturer capturer(root->child_at(0)->child_at(0));
|
| + NavigateFrameToURL(root->child_at(0)->child_at(0), nested_url);
|
| + capturer.Wait();
|
| + EXPECT_EQ(ui::PAGE_TRANSITION_MANUAL_SUBFRAME,
|
| + capturer.params().transition);
|
| + EXPECT_EQ(NAVIGATION_TYPE_NEW_SUBFRAME, capturer.details().type);
|
| + }
|
| +}
|
| +
|
| // Verify the tree of FrameNavigationEntries after back/forward navigations in a
|
| // cross-site subframe.
|
| IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
|
|
|