web_contents_impl_browsertest.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "base/values.h" 6#include "content/browser/renderer_host/render_view_host_impl.h" 7#include "content/browser/web_contents/web_contents_impl.h" 8#include "content/public/browser/load_notification_details.h" 9#include "content/public/browser/navigation_controller.h" 10#include "content/public/browser/notification_details.h" 11#include "content/public/browser/notification_observer.h" 12#include "content/public/browser/notification_types.h" 13#include "content/public/common/content_paths.h" 14#include "content/public/test/browser_test_utils.h" 15#include "content/public/test/test_utils.h" 16#include "content/shell/shell.h" 17#include "content/test/content_browser_test.h" 18#include "content/test/content_browser_test_utils.h" 19#include "net/test/embedded_test_server/embedded_test_server.h" 20 21namespace content { 22 23class WebContentsImplBrowserTest : public ContentBrowserTest { 24 public: 25 WebContentsImplBrowserTest() {} 26 27 private: 28 DISALLOW_COPY_AND_ASSIGN(WebContentsImplBrowserTest); 29}; 30 31// Keeps track of data from LoadNotificationDetails so we can later verify that 32// they are correct, after the LoadNotificationDetails object is deleted. 33class LoadStopNotificationObserver : public WindowedNotificationObserver { 34 public: 35 LoadStopNotificationObserver(NavigationController* controller) 36 : WindowedNotificationObserver(NOTIFICATION_LOAD_STOP, 37 Source<NavigationController>(controller)), 38 session_index_(-1), 39 controller_(NULL) { 40 } 41 virtual void Observe(int type, 42 const NotificationSource& source, 43 const NotificationDetails& details) OVERRIDE { 44 if (type == NOTIFICATION_LOAD_STOP) { 45 const Details<LoadNotificationDetails> load_details(details); 46 url_ = load_details->url; 47 session_index_ = load_details->session_index; 48 controller_ = load_details->controller; 49 } 50 WindowedNotificationObserver::Observe(type, source, details); 51 } 52 53 GURL url_; 54 int session_index_; 55 NavigationController* controller_; 56}; 57 58// Starts a new navigation as soon as the current one commits, but does not 59// wait for it to complete. This allows us to observe DidStopLoading while 60// a pending entry is present. 61class NavigateOnCommitObserver : public WindowedNotificationObserver { 62 public: 63 NavigateOnCommitObserver(Shell* shell, GURL url) 64 : WindowedNotificationObserver( 65 NOTIFICATION_NAV_ENTRY_COMMITTED, 66 Source<NavigationController>( 67 &shell->web_contents()->GetController())), 68 shell_(shell), 69 url_(url), 70 done_(false) { 71 } 72 virtual void Observe(int type, 73 const NotificationSource& source, 74 const NotificationDetails& details) OVERRIDE { 75 if (type == NOTIFICATION_NAV_ENTRY_COMMITTED && !done_) { 76 done_ = true; 77 shell_->LoadURL(url_); 78 } 79 WindowedNotificationObserver::Observe(type, source, details); 80 } 81 82 Shell* shell_; 83 GURL url_; 84 bool done_; 85}; 86 87// Test that DidStopLoading includes the correct URL in the details. 88IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, DidStopLoadingDetails) { 89 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 90 91 LoadStopNotificationObserver load_observer( 92 &shell()->web_contents()->GetController()); 93 NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")); 94 load_observer.Wait(); 95 96 EXPECT_EQ("/title1.html", load_observer.url_.path()); 97 EXPECT_EQ(0, load_observer.session_index_); 98 EXPECT_EQ(&shell()->web_contents()->GetController(), 99 load_observer.controller_); 100} 101 102// Test that DidStopLoading includes the correct URL in the details when a 103// pending entry is present. 104IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, 105 DidStopLoadingDetailsWithPending) { 106 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 107 108 // Listen for the first load to stop. 109 LoadStopNotificationObserver load_observer( 110 &shell()->web_contents()->GetController()); 111 // Start a new pending navigation as soon as the first load commits. 112 // We will hear a DidStopLoading from the first load as the new load 113 // is started. 114 NavigateOnCommitObserver commit_observer( 115 shell(), embedded_test_server()->GetURL("/title2.html")); 116 NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")); 117 commit_observer.Wait(); 118 load_observer.Wait(); 119 120 EXPECT_EQ("/title1.html", load_observer.url_.path()); 121 EXPECT_EQ(0, load_observer.session_index_); 122 EXPECT_EQ(&shell()->web_contents()->GetController(), 123 load_observer.controller_); 124} 125 126// Test that the browser receives the proper frame attach/detach messages from 127// the renderer and builds proper frame tree. 128IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, FrameTree) { 129 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 130 131 NavigateToURL(shell(), 132 embedded_test_server()->GetURL("/frame_tree/top.html")); 133 134 WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents()); 135 RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( 136 wc->GetRenderViewHost()); 137 FrameTreeNode* root = wc->GetFrameTreeRootForTesting(); 138 139 // Check that the root node is properly created with the frame id of the 140 // initial navigation. 141 EXPECT_EQ(3UL, root->child_count()); 142 EXPECT_EQ(std::string(), root->frame_name()); 143 EXPECT_EQ(rvh->main_frame_id(), root->frame_id()); 144 145 EXPECT_EQ(2UL, root->child_at(0)->child_count()); 146 EXPECT_STREQ("1-1-name", root->child_at(0)->frame_name().c_str()); 147 148 // Verify the deepest node exists and has the right name. 149 EXPECT_EQ(2UL, root->child_at(2)->child_count()); 150 EXPECT_EQ(1UL, root->child_at(2)->child_at(1)->child_count()); 151 EXPECT_EQ(0UL, root->child_at(2)->child_at(1)->child_at(0)->child_count()); 152 EXPECT_STREQ("3-1-id", 153 root->child_at(2)->child_at(1)->child_at(0)->frame_name().c_str()); 154 155 // Navigate to about:blank, which should leave only the root node of the frame 156 // tree in the browser process. 157 NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")); 158 159 root = wc->GetFrameTreeRootForTesting(); 160 EXPECT_EQ(0UL, root->child_count()); 161 EXPECT_EQ(std::string(), root->frame_name()); 162 EXPECT_EQ(rvh->main_frame_id(), root->frame_id()); 163} 164 165} // namespace content 166