Index: content/browser/site_per_process_browsertest.cc |
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc |
index f758c2f07d3e04068c5d4d9d875463397d58d71d..6535e9878bdb0daecaaad613d2200b3785d1e161 100644 |
--- a/content/browser/site_per_process_browsertest.cc |
+++ b/content/browser/site_per_process_browsertest.cc |
@@ -8,15 +8,20 @@ |
#include "base/strings/stringprintf.h" |
#include "base/strings/utf_string_conversions.h" |
#include "content/browser/frame_host/cross_process_frame_connector.h" |
+#include "content/browser/frame_host/frame_navigation_entry.h" |
#include "content/browser/frame_host/frame_tree.h" |
+#include "content/browser/frame_host/navigation_entry_impl.h" |
#include "content/browser/frame_host/navigator.h" |
#include "content/browser/frame_host/render_frame_proxy_host.h" |
#include "content/browser/frame_host/render_widget_host_view_child_frame.h" |
#include "content/browser/renderer_host/render_view_host_impl.h" |
#include "content/browser/web_contents/web_contents_impl.h" |
+#include "content/public/browser/navigation_controller.h" |
#include "content/public/browser/notification_observer.h" |
#include "content/public/browser/notification_service.h" |
#include "content/public/browser/notification_types.h" |
+#include "content/public/browser/web_contents.h" |
+#include "content/public/browser/web_contents_observer.h" |
#include "content/public/common/content_switches.h" |
#include "content/public/test/browser_test_utils.h" |
#include "content/public/test/content_browser_test_utils.h" |
@@ -646,6 +651,116 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, |
} |
} |
+// Test cross-process back/forward navigations in a subframe. |
+// Session history entries: |
+// 1) localhost with subframe localhost/title1 |
+// 2) localhost with subframe foo/title2 |
+// 3) localhost with subframe bar/title3 |
+// Go back twice, then forward twice. |
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, SubframeBackForward) { |
+ GURL main_url(embedded_test_server()->GetURL("/site_per_process_main.html")); |
+ NavigateToURL(shell(), main_url); |
+ SiteInstance* main_site_instance = shell()->web_contents()->GetSiteInstance(); |
+ |
+ // It is safe to obtain the root frame tree node here, as it doesn't change. |
+ FrameTreeNode* root = |
+ static_cast<WebContentsImpl*>(shell()->web_contents())-> |
+ GetFrameTree()->root(); |
+ |
+ TestNavigationObserver observer(shell()->web_contents()); |
+ |
+ // Load same-site page into iframe. |
+ FrameTreeNode* child = root->child_at(0); |
+ GURL frame_url1(embedded_test_server()->GetURL("/title1.html")); |
+ NavigateFrameToURL(child, frame_url1); |
+ EXPECT_EQ(frame_url1, observer.last_navigation_url()); |
+ EXPECT_TRUE(observer.last_navigation_succeeded()); |
+ |
+ // Load foo.com page into iframe. |
+ GURL frame_url2 = embedded_test_server()->GetURL("foo.com", "/title2.html"); |
+ NavigateFrameToURL(root->child_at(0), frame_url2); |
+ EXPECT_TRUE(observer.last_navigation_succeeded()); |
+ EXPECT_EQ(frame_url2, observer.last_navigation_url()); |
+ SiteInstance* foo_site_instance = |
+ child->current_frame_host()->GetSiteInstance(); |
+ EXPECT_EQ(main_site_instance, shell()->web_contents()->GetSiteInstance()); |
+ EXPECT_NE(main_site_instance, foo_site_instance); |
+ |
+ // Load bar.com page into iframe. |
+ GURL frame_url3 = embedded_test_server()->GetURL("bar.com", "/title3.html"); |
+ NavigateFrameToURL(root->child_at(0), frame_url3); |
+ EXPECT_TRUE(observer.last_navigation_succeeded()); |
+ EXPECT_EQ(frame_url3, observer.last_navigation_url()); |
+ SiteInstance* bar_site_instance = |
+ child->current_frame_host()->GetSiteInstance(); |
+ EXPECT_NE(main_site_instance, bar_site_instance); |
+ EXPECT_NE(foo_site_instance, bar_site_instance); |
+ |
+ // Go back to foo. |
+ { |
+ TestFrameNavigationObserver back_nav_load_observer(child); |
+ shell()->web_contents()->GetController().GoBack(); |
+ back_nav_load_observer.Wait(); |
+ } |
+ EXPECT_EQ(main_url, root->current_url()); |
+ EXPECT_EQ(frame_url2, child->current_url()); |
+ NavigationEntryImpl* entry = static_cast<NavigationEntryImpl*>( |
+ shell()->web_contents()->GetController().GetLastCommittedEntry()); |
+ FrameNavigationEntry* frame_entry = |
+ entry->root_node()->children[0]->frame_entry.get(); |
+ EXPECT_EQ(main_url, entry->GetURL()); |
+ EXPECT_EQ(frame_url2, frame_entry->url()); |
+ EXPECT_EQ(foo_site_instance, child->current_frame_host()->GetSiteInstance()); |
+ |
+ // Go back to localhost. |
+ { |
+ TestFrameNavigationObserver back_nav_load_observer(child); |
+ shell()->web_contents()->GetController().GoBack(); |
+ back_nav_load_observer.Wait(); |
+ } |
+ EXPECT_EQ(main_url, root->current_url()); |
+ EXPECT_EQ(frame_url1, child->current_url()); |
+ entry = static_cast<NavigationEntryImpl*>( |
+ shell()->web_contents()->GetController().GetLastCommittedEntry()); |
+ frame_entry = entry->root_node()->children[0]->frame_entry.get(); |
+ EXPECT_EQ(main_url, entry->GetURL()); |
+ EXPECT_EQ(frame_url1, frame_entry->url()); |
+ EXPECT_EQ(main_site_instance, child->current_frame_host()->GetSiteInstance()); |
+ |
+ /* |
+ // Go forward to foo. |
+ // TODO(creis): Why is the test crashing here in OnDeleteProxy? |
+ { |
+ TestFrameNavigationObserver forward_nav_load_observer(child); |
+ shell()->web_contents()->GetController().GoForward(); |
+ forward_nav_load_observer.Wait(); |
+ } |
+ EXPECT_EQ(main_url, root->current_url()); |
+ EXPECT_EQ(frame_url2, child->current_url()); |
+ entry = static_cast<NavigationEntryImpl*>( |
+ shell()->web_contents()->GetController().GetLastCommittedEntry()); |
+ frame_entry = entry->root_node()->children.at(0)->frame_entry; |
+ EXPECT_EQ(main_url, entry->GetURL()); |
+ EXPECT_EQ(frame_url2, frame_entry->GetURL()); |
+ EXPECT_EQ(foo_site_instance, child->current_frame_host()->GetSiteInstance()); |
+ |
+ // Go forward to bar. |
+ { |
+ TestFrameNavigationObserver forward_nav_load_observer(child); |
+ shell()->web_contents()->GetController().GoForward(); |
+ forward_nav_load_observer.Wait(); |
+ } |
+ EXPECT_EQ(main_url, root->current_url()); |
+ EXPECT_EQ(frame_url2, child->current_url()); |
+ entry = static_cast<NavigationEntryImpl*>( |
+ shell()->web_contents()->GetController().GetLastCommittedEntry()); |
+ frame_entry = entry->root_node()->children.at(0)->frame_entry; |
+ EXPECT_EQ(main_url, entry->GetURL()); |
+ EXPECT_EQ(frame_url2, frame_entry->GetURL()); |
+ EXPECT_EQ(foo_site_instance, child->current_frame_host()->GetSiteInstance()); |
+ */ |
+} |
+ |
// Crash a subframe and ensures its children are cleared from the FrameTree. |
// See http://crbug.com/338508. |
// TODO(creis): Disabled for flakiness; see http://crbug.com/405582. |