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 4ccab789b2bf2054a016a74d9664d1b01b4dfeaa..35bacb14b65143b9ef1946cb84490ddfddf2778d 100644 |
--- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc |
+++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc |
@@ -3205,14 +3205,7 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, |
} |
ASSERT_EQ(1U, root->child_count()); |
EXPECT_EQ(main_url, root->current_url()); |
- |
- // TODO(creis): The child's current_url should be about:blank, but we're not |
- // currently getting a commit in this case. For now, we'll lack a commit for |
- // this frame, similar to the slow URL case. See https://crbug.com/626416. |
- if (SiteIsolationPolicy::UseSubframeNavigationEntries()) |
- EXPECT_TRUE(root->child_at(0)->current_url().is_empty()); |
- else |
- EXPECT_EQ(blank_url, root->child_at(0)->current_url()); |
+ EXPECT_EQ(blank_url, root->child_at(0)->current_url()); |
// Verify that the parent was able to script the iframe. |
{ |
@@ -3234,6 +3227,195 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, |
} |
} |
+// Verify that we correctly load nested iframes injected into a page if we go |
+// back and recreate them. Also confirm that form values are not restored for |
+// forms injected into about:blank pages. See https://crbug.com/657896. |
+IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, |
+ FrameNavigationEntry_RecreatedInjectedBlankSubframe) { |
+ // 1. Start on a page that injects a nested iframe into an injected |
+ // about:blank iframe. |
+ GURL main_url(embedded_test_server()->GetURL( |
+ "/navigation_controller/inject_subframe_into_blank_iframe.html")); |
+ GURL blank_url(url::kAboutBlankURL); |
+ GURL inner_url( |
+ embedded_test_server()->GetURL("/navigation_controller/form.html")); |
+ EXPECT_TRUE(NavigateToURL(shell(), main_url)); |
+ NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( |
+ shell()->web_contents()->GetController()); |
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) |
+ ->GetFrameTree() |
+ ->root(); |
+ |
+ // Verify that the inner iframe was able to load. |
+ ASSERT_EQ(1U, root->child_count()); |
+ ASSERT_EQ(1U, root->child_at(0)->child_count()); |
+ ASSERT_EQ(0U, root->child_at(0)->child_at(0)->child_count()); |
+ EXPECT_EQ(main_url, root->current_url()); |
+ EXPECT_EQ(blank_url, root->child_at(0)->current_url()); |
+ EXPECT_EQ(inner_url, root->child_at(0)->child_at(0)->current_url()); |
+ |
+ EXPECT_EQ(1, controller.GetEntryCount()); |
+ EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); |
+ NavigationEntryImpl* entry = controller.GetLastCommittedEntry(); |
+ |
+ // The entry should have FrameNavigationEntries for the subframes. |
+ if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { |
+ ASSERT_EQ(1U, entry->root_node()->children.size()); |
+ EXPECT_EQ(blank_url, entry->root_node()->children[0]->frame_entry->url()); |
+ EXPECT_EQ(inner_url, |
+ entry->root_node()->children[0]->children[0]->frame_entry->url()); |
+ } |
+ |
+ // Set a value in the form which will be stored in the PageState. |
+ EXPECT_TRUE( |
+ ExecuteScript(root->child_at(0)->child_at(0), |
+ "document.getElementById('itext').value = 'modified';")); |
+ |
+ // 2. Navigate the main frame same-site, destroying the subframes. |
+ GURL main_url_2(embedded_test_server()->GetURL( |
+ "/navigation_controller/simple_page_1.html")); |
+ EXPECT_TRUE(NavigateToURL(shell(), main_url_2)); |
+ ASSERT_EQ(0U, root->child_count()); |
+ EXPECT_EQ(main_url_2, root->current_url()); |
+ |
+ EXPECT_EQ(2, controller.GetEntryCount()); |
+ EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); |
+ |
+ // 3. Go back, recreating the subframes. |
+ { |
+ TestNavigationObserver back_load_observer(shell()->web_contents()); |
+ controller.GoBack(); |
+ back_load_observer.Wait(); |
+ } |
+ ASSERT_EQ(1U, root->child_count()); |
+ EXPECT_EQ(main_url, root->current_url()); |
+ EXPECT_EQ(blank_url, root->child_at(0)->current_url()); |
+ |
+ // Verify that the inner iframe went to the correct URL. |
+ EXPECT_EQ(inner_url, root->child_at(0)->child_at(0)->current_url()); |
+ |
+ EXPECT_EQ(2, controller.GetEntryCount()); |
+ EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); |
+ EXPECT_EQ(entry, controller.GetLastCommittedEntry()); |
+ |
+ // The entry should have FrameNavigationEntries for the subframes. |
+ if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { |
+ ASSERT_EQ(1U, entry->root_node()->children.size()); |
+ EXPECT_EQ(blank_url, entry->root_node()->children[0]->frame_entry->url()); |
+ EXPECT_EQ(inner_url, |
+ entry->root_node()->children[0]->children[0]->frame_entry->url()); |
+ } |
+ |
+ // With injected about:blank iframes, we never restore form values from |
+ // PageState. |
+ std::string form_value; |
alexmos
2016/10/21 06:34:16
nit: maybe initialize to something other than ""?
Charlie Reis
2016/10/21 07:34:30
Done.
|
+ EXPECT_TRUE( |
+ ExecuteScriptAndExtractString(root->child_at(0)->child_at(0), |
+ "window.domAutomationController.send(" |
+ "document.getElementById('itext').value);", |
+ &form_value)); |
+ EXPECT_EQ("", form_value); |
+} |
+ |
+// Verify that we correctly load a nested iframe created by an injected iframe |
+// srcdoc if we go back and recreate the frames. Also verify that form values |
+// are correctly restored for forms within srcdoc frames, unlike forms injected |
+// into about:blank pages (as tested in |
+// FrameNavigationEntry_RecreatedInjectedBlankSubframe). |
+// |
+// This test worked before and after the fix for https://crbug.com/657896, but |
+// it failed with a preliminary version of the fix. |
+IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, |
+ FrameNavigationEntry_RecreatedInjectedSrcdocSubframe) { |
+ // 1. Start on a page that injects a nested iframe srcdoc which contains a |
+ // nested iframe. |
+ GURL main_url(embedded_test_server()->GetURL( |
+ "/navigation_controller/inject_iframe_srcdoc_with_nested_frame.html")); |
+ GURL blank_url(url::kAboutBlankURL); |
+ GURL inner_url( |
+ embedded_test_server()->GetURL("/navigation_controller/form.html")); |
+ EXPECT_TRUE(NavigateToURL(shell(), main_url)); |
+ NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( |
+ shell()->web_contents()->GetController()); |
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) |
+ ->GetFrameTree() |
+ ->root(); |
+ |
+ // Verify that the inner iframe was able to load. |
+ ASSERT_EQ(1U, root->child_count()); |
+ ASSERT_EQ(1U, root->child_at(0)->child_count()); |
+ ASSERT_EQ(0U, root->child_at(0)->child_at(0)->child_count()); |
+ EXPECT_EQ(main_url, root->current_url()); |
+ EXPECT_EQ(blank_url, root->child_at(0)->current_url()); |
+ EXPECT_EQ(inner_url, root->child_at(0)->child_at(0)->current_url()); |
+ |
+ EXPECT_EQ(1, controller.GetEntryCount()); |
+ EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); |
+ NavigationEntryImpl* entry = controller.GetLastCommittedEntry(); |
+ |
+ // The entry should have FrameNavigationEntries for the subframes. |
+ if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { |
+ ASSERT_EQ(1U, entry->root_node()->children.size()); |
+ EXPECT_EQ(blank_url, entry->root_node()->children[0]->frame_entry->url()); |
+ EXPECT_EQ(inner_url, |
+ entry->root_node()->children[0]->children[0]->frame_entry->url()); |
+ } |
+ |
+ // Set a value in the form which will be stored in the PageState. |
+ EXPECT_TRUE( |
+ ExecuteScript(root->child_at(0)->child_at(0), |
+ "document.getElementById('itext').value = 'modified';")); |
+ |
+ // 2. Navigate the main frame same-site, destroying the subframes. |
+ GURL main_url_2(embedded_test_server()->GetURL( |
+ "/navigation_controller/simple_page_1.html")); |
+ EXPECT_TRUE(NavigateToURL(shell(), main_url_2)); |
+ ASSERT_EQ(0U, root->child_count()); |
+ EXPECT_EQ(main_url_2, root->current_url()); |
+ |
+ EXPECT_EQ(2, controller.GetEntryCount()); |
+ EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); |
+ |
+ // 3. Go back, recreating the subframes. |
+ { |
+ TestNavigationObserver back_load_observer(shell()->web_contents()); |
+ controller.GoBack(); |
+ back_load_observer.Wait(); |
+ } |
+ ASSERT_EQ(1U, root->child_count()); |
+ // TODO(creis): This line is unexpectedly failing in PlzNavigate, so the test |
+ // is disabled there for now. |
+ ASSERT_EQ(1U, root->child_at(0)->child_count()); |
Charlie Reis
2016/10/21 04:39:25
Not sure why this isn't working in PlzNavigate (ev
alexmos
2016/10/21 06:34:16
Acknowledged. I tried it out locally, and it seem
|
+ ASSERT_EQ(0U, root->child_at(0)->child_at(0)->child_count()); |
+ EXPECT_EQ(main_url, root->current_url()); |
+ EXPECT_EQ(blank_url, root->child_at(0)->current_url()); |
+ |
+ // Verify that the inner iframe went to the correct URL. |
+ EXPECT_EQ(inner_url, root->child_at(0)->child_at(0)->current_url()); |
+ |
+ EXPECT_EQ(2, controller.GetEntryCount()); |
+ EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); |
+ EXPECT_EQ(entry, controller.GetLastCommittedEntry()); |
+ |
+ // The entry should have FrameNavigationEntries for the subframes. |
+ if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { |
+ ASSERT_EQ(1U, entry->root_node()->children.size()); |
+ EXPECT_EQ(blank_url, entry->root_node()->children[0]->frame_entry->url()); |
+ EXPECT_EQ(inner_url, |
+ entry->root_node()->children[0]->children[0]->frame_entry->url()); |
+ } |
+ |
+ // With injected iframe srcdoc pages, we do restore form values from |
+ // PageState. |
+ std::string form_value; |
+ EXPECT_TRUE( |
+ ExecuteScriptAndExtractString(root->child_at(0)->child_at(0), |
+ "window.domAutomationController.send(" |
+ "document.getElementById('itext').value);", |
+ &form_value)); |
+ EXPECT_EQ("modified", form_value); |
+} |
+ |
// Ensure we don't crash if an onload handler removes an about:blank frame after |
// recreating it on a back/forward. See https://crbug.com/638166. |
IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, |
@@ -5507,14 +5689,7 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, |
EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); |
EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); |
EXPECT_EQ(url_b, root->current_url()); |
- |
- // TODO(creis): The child's current_url should be about:blank, but we're not |
- // currently getting a commit in this case. For now, we'll lack a commit for |
- // this frame, similar to the slow URL case. See https://crbug.com/626416. |
- if (SiteIsolationPolicy::UseSubframeNavigationEntries()) |
- EXPECT_TRUE(root->child_at(0)->current_url().is_empty()); |
- else |
- EXPECT_EQ(frame_url_b1, root->child_at(0)->current_url()); |
+ EXPECT_EQ(frame_url_b1, root->child_at(0)->current_url()); |
// Check the PageState of the previous entry to ensure it isn't corrupted. |
NavigationEntry* entry = controller.GetEntryAtIndex(1); |