| 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 cc00ec2b6317a78a46e6b3b964649aac1c2b36eb..f6820af7356556ee44caea3954c310cc483ee170 100644
|
| --- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc
|
| +++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
|
| @@ -3140,6 +3140,131 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
|
| EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
|
| }
|
|
|
| +// Similar to FrameNavigationEntry_BackWithRedirect but with same-origin frames.
|
| +// (This wasn't working initially).
|
| +IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
|
| + FrameNavigationEntry_SameOriginBackWithRedirect) {
|
| + // 1. Start on a page with an iframe.
|
| + GURL initial_url(embedded_test_server()->GetURL(
|
| + "/navigation_controller/page_with_data_iframe.html"));
|
| + EXPECT_TRUE(NavigateToURL(shell(), initial_url));
|
| + const NavigationControllerImpl& controller =
|
| + static_cast<const NavigationControllerImpl&>(
|
| + shell()->web_contents()->GetController());
|
| + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
|
| + ->GetFrameTree()
|
| + ->root();
|
| + EXPECT_EQ(initial_url, root->current_url());
|
| + EXPECT_EQ(1U, root->child_count());
|
| + NavigationEntryImpl* entry1 = controller.GetLastCommittedEntry();
|
| + if (SiteIsolationPolicy::UseSubframeNavigationEntries())
|
| + EXPECT_EQ(1U, entry1->root_node()->children.size());
|
| +
|
| + // 2. Navigate the iframe to a page with a nested iframe.
|
| + GURL frame_url(embedded_test_server()->GetURL(
|
| + "/navigation_controller/page_with_data_iframe.html"));
|
| + GURL data_url("data:text/html,Subframe");
|
| + NavigateFrameToURL(root->child_at(0), frame_url);
|
| + EXPECT_EQ(initial_url, root->current_url());
|
| + EXPECT_EQ(frame_url, root->child_at(0)->current_url());
|
| + EXPECT_EQ(data_url, root->child_at(0)->child_at(0)->current_url());
|
| +
|
| + EXPECT_EQ(2, controller.GetEntryCount());
|
| + EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
|
| + NavigationEntryImpl* entry2 = controller.GetLastCommittedEntry();
|
| + // Verify subframe entries if they're enabled (e.g. in --site-per-process).
|
| + if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
|
| + NavigationEntryImpl::TreeNode* root_node = entry2->root_node();
|
| + ASSERT_EQ(1U, root_node->children.size());
|
| + EXPECT_EQ(frame_url, root_node->children[0]->frame_entry->url());
|
| + EXPECT_EQ(data_url,
|
| + root_node->children[0]->children[0]->frame_entry->url());
|
| + }
|
| +
|
| + // Cause the iframe to redirect when we come back later. It will go
|
| + // same-origin to a page with an about:blank iframe.
|
| + GURL frame_redirect_dest_url(embedded_test_server()->GetURL(
|
| + "/navigation_controller/page_with_iframe.html"));
|
| + GURL blank_url(url::kAboutBlankURL);
|
| + {
|
| + TestNavigationObserver observer(shell()->web_contents());
|
| + std::string script = "history.replaceState({}, '', '/server-redirect?" +
|
| + frame_redirect_dest_url.spec() + "')";
|
| + EXPECT_TRUE(ExecuteScript(root->child_at(0), script));
|
| + observer.Wait();
|
| + }
|
| +
|
| + // We should not have lost subframe entries for the nested frame.
|
| + EXPECT_EQ(2, controller.GetEntryCount());
|
| + EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
|
| + if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
|
| + FrameNavigationEntry* nested_entry =
|
| + entry2->GetFrameEntry(root->child_at(0)->child_at(0));
|
| + EXPECT_TRUE(nested_entry);
|
| + EXPECT_EQ(data_url, nested_entry->url());
|
| + }
|
| +
|
| + // 3. Navigate the main frame to a different page. When we come back, we'll
|
| + // commit the main frame first and have no pending entry when navigating the
|
| + // subframes.
|
| + GURL url2(embedded_test_server()->GetURL(
|
| + "/navigation_controller/simple_page_1.html"));
|
| + EXPECT_TRUE(NavigateToURL(shell(), url2));
|
| + EXPECT_EQ(3, controller.GetEntryCount());
|
| + EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
|
| +
|
| + // 4. Go back. The first iframe should redirect to a cross-site page with a
|
| + // different nested iframe.
|
| + {
|
| + TestNavigationObserver back_load_observer(shell()->web_contents());
|
| + shell()->web_contents()->GetController().GoBack();
|
| + back_load_observer.Wait();
|
| + }
|
| + EXPECT_EQ(initial_url, root->current_url());
|
| + EXPECT_EQ(frame_redirect_dest_url, root->child_at(0)->current_url());
|
| + EXPECT_EQ(blank_url, root->child_at(0)->child_at(0)->current_url());
|
| +
|
| + // Check the FrameNavigationEntries as well.
|
| + EXPECT_EQ(3, controller.GetEntryCount());
|
| + EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
|
| + if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
|
| + EXPECT_EQ(frame_redirect_dest_url,
|
| + entry2->GetFrameEntry(root->child_at(0))->url());
|
| + EXPECT_EQ(blank_url,
|
| + entry2->GetFrameEntry(root->child_at(0)->child_at(0))->url());
|
| + }
|
| +
|
| + // Now cause the main frame to redirect to a page with no frames when we come
|
| + // back to it.
|
| + GURL redirect_dest_url(embedded_test_server()->GetURL(
|
| + "/navigation_controller/simple_page_2.html"));
|
| + {
|
| + TestNavigationObserver observer(shell()->web_contents());
|
| + std::string script = "history.replaceState({}, '', '/server-redirect?" +
|
| + redirect_dest_url.spec() + "')";
|
| + EXPECT_TRUE(ExecuteScript(root, script));
|
| + observer.Wait();
|
| + }
|
| +
|
| + // 5. Navigate the main frame to a different page.
|
| + EXPECT_TRUE(NavigateToURL(shell(), url2));
|
| + EXPECT_EQ(3, controller.GetEntryCount());
|
| + EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
|
| +
|
| + // 6. Go back, causing the main frame to redirect to a page with no frames.
|
| + // All child items should be gone.
|
| + {
|
| + TestNavigationObserver back_load_observer(shell()->web_contents());
|
| + shell()->web_contents()->GetController().GoBack();
|
| + back_load_observer.Wait();
|
| + }
|
| + EXPECT_EQ(redirect_dest_url, root->current_url());
|
| + EXPECT_EQ(0U, root->child_count());
|
| + EXPECT_EQ(0U, entry2->root_node()->children.size());
|
| + EXPECT_EQ(3, controller.GetEntryCount());
|
| + EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
|
| +}
|
| +
|
| // Verify that subframes can be restored in a new NavigationController using the
|
| // PageState of an existing NavigationEntry.
|
| IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
|
|
|