summaryrefslogtreecommitdiffstats
path: root/chromium/content/browser/frame_host/frame_tree_browsertest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/browser/frame_host/frame_tree_browsertest.cc')
-rw-r--r--chromium/content/browser/frame_host/frame_tree_browsertest.cc158
1 files changed, 158 insertions, 0 deletions
diff --git a/chromium/content/browser/frame_host/frame_tree_browsertest.cc b/chromium/content/browser/frame_host/frame_tree_browsertest.cc
new file mode 100644
index 00000000000..bc5f1cb04ff
--- /dev/null
+++ b/chromium/content/browser/frame_host/frame_tree_browsertest.cc
@@ -0,0 +1,158 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/frame_host/frame_tree.h"
+#include "content/browser/frame_host/frame_tree_node.h"
+#include "content/browser/renderer_host/render_view_host_impl.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/notification_types.h"
+#include "content/public/common/url_constants.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/test_navigation_observer.h"
+#include "content/public/test/test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "net/dns/mock_host_resolver.h"
+
+namespace content {
+
+class FrameTreeBrowserTest : public ContentBrowserTest {
+ public:
+ FrameTreeBrowserTest() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FrameTreeBrowserTest);
+};
+
+// Ensures FrameTree correctly reflects page structure during navigations.
+IN_PROC_BROWSER_TEST_F(FrameTreeBrowserTest, FrameTreeShape) {
+ host_resolver()->AddRule("*", "127.0.0.1");
+ ASSERT_TRUE(test_server()->Start());
+
+ GURL base_url = test_server()->GetURL("files/site_isolation/");
+ GURL::Replacements replace_host;
+ std::string host_str("A.com"); // Must stay in scope with replace_host.
+ replace_host.SetHostStr(host_str);
+ base_url = base_url.ReplaceComponents(replace_host);
+
+ // Load doc without iframes. Verify FrameTree just has root.
+ // Frame tree:
+ // Site-A Root
+ NavigateToURL(shell(), base_url.Resolve("blank.html"));
+ FrameTreeNode* root =
+ static_cast<WebContentsImpl*>(shell()->web_contents())->
+ GetFrameTree()->root();
+ EXPECT_EQ(0U, root->child_count());
+
+ // Add 2 same-site frames. Verify 3 nodes in tree with proper names.
+ // Frame tree:
+ // Site-A Root -- Site-A frame1
+ // \-- Site-A frame2
+ WindowedNotificationObserver observer1(
+ content::NOTIFICATION_LOAD_STOP,
+ content::Source<NavigationController>(
+ &shell()->web_contents()->GetController()));
+ NavigateToURL(shell(), base_url.Resolve("frames-X-X.html"));
+ observer1.Wait();
+ ASSERT_EQ(2U, root->child_count());
+ EXPECT_EQ(0U, root->child_at(0)->child_count());
+ EXPECT_EQ(0U, root->child_at(1)->child_count());
+}
+
+// TODO(ajwong): Talk with nasko and merge this functionality with
+// FrameTreeShape.
+IN_PROC_BROWSER_TEST_F(FrameTreeBrowserTest, FrameTreeShape2) {
+ ASSERT_TRUE(test_server()->Start());
+ NavigateToURL(shell(),
+ test_server()->GetURL("files/frame_tree/top.html"));
+
+ WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents());
+ FrameTreeNode* root = wc->GetFrameTree()->root();
+
+ // Check that the root node is properly created.
+ ASSERT_EQ(3UL, root->child_count());
+ EXPECT_EQ(std::string(), root->frame_name());
+
+ ASSERT_EQ(2UL, root->child_at(0)->child_count());
+ EXPECT_STREQ("1-1-name", root->child_at(0)->frame_name().c_str());
+
+ // Verify the deepest node exists and has the right name.
+ ASSERT_EQ(2UL, root->child_at(2)->child_count());
+ EXPECT_EQ(1UL, root->child_at(2)->child_at(1)->child_count());
+ EXPECT_EQ(0UL, root->child_at(2)->child_at(1)->child_at(0)->child_count());
+ EXPECT_STREQ("3-1-name",
+ root->child_at(2)->child_at(1)->child_at(0)->frame_name().c_str());
+
+ // Navigate to about:blank, which should leave only the root node of the frame
+ // tree in the browser process.
+ NavigateToURL(shell(), test_server()->GetURL("files/title1.html"));
+
+ root = wc->GetFrameTree()->root();
+ EXPECT_EQ(0UL, root->child_count());
+ EXPECT_EQ(std::string(), root->frame_name());
+}
+
+// Test that we can navigate away if the previous renderer doesn't clean up its
+// child frames.
+IN_PROC_BROWSER_TEST_F(FrameTreeBrowserTest, FrameTreeAfterCrash) {
+ ASSERT_TRUE(test_server()->Start());
+ NavigateToURL(shell(),
+ test_server()->GetURL("files/frame_tree/top.html"));
+
+ // Crash the renderer so that it doesn't send any FrameDetached messages.
+ RenderProcessHostWatcher crash_observer(
+ shell()->web_contents(),
+ RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
+ NavigateToURL(shell(), GURL(kChromeUICrashURL));
+ crash_observer.Wait();
+
+ // The frame tree should be cleared.
+ WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents());
+ FrameTreeNode* root = wc->GetFrameTree()->root();
+ EXPECT_EQ(0UL, root->child_count());
+
+ // Navigate to a new URL.
+ GURL url(test_server()->GetURL("files/title1.html"));
+ NavigateToURL(shell(), url);
+ EXPECT_EQ(0UL, root->child_count());
+ EXPECT_EQ(url, root->current_url());
+}
+
+// Test that we can navigate away if the previous renderer doesn't clean up its
+// child frames.
+IN_PROC_BROWSER_TEST_F(FrameTreeBrowserTest, NavigateWithLeftoverFrames) {
+ host_resolver()->AddRule("*", "127.0.0.1");
+ ASSERT_TRUE(test_server()->Start());
+
+ GURL base_url = test_server()->GetURL("files/site_isolation/");
+ GURL::Replacements replace_host;
+ std::string host_str("A.com"); // Must stay in scope with replace_host.
+ replace_host.SetHostStr(host_str);
+ base_url = base_url.ReplaceComponents(replace_host);
+
+ NavigateToURL(shell(),
+ test_server()->GetURL("files/frame_tree/top.html"));
+
+ // Hang the renderer so that it doesn't send any FrameDetached messages.
+ // (This navigation will never complete, so don't wait for it.)
+ shell()->LoadURL(GURL(kChromeUIHangURL));
+
+ // Check that the frame tree still has children.
+ WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents());
+ FrameTreeNode* root = wc->GetFrameTree()->root();
+ ASSERT_EQ(3UL, root->child_count());
+
+ // Navigate to a new URL. We use LoadURL because NavigateToURL will try to
+ // wait for the previous navigation to stop.
+ TestNavigationObserver tab_observer(wc, 1);
+ shell()->LoadURL(base_url.Resolve("blank.html"));
+ tab_observer.Wait();
+
+ // The frame tree should now be cleared.
+ EXPECT_EQ(0UL, root->child_count());
+}
+
+} // namespace content