diff options
Diffstat (limited to 'chromium/content/browser/web_contents/web_contents_impl_browsertest.cc')
-rw-r--r-- | chromium/content/browser/web_contents/web_contents_impl_browsertest.cc | 262 |
1 files changed, 233 insertions, 29 deletions
diff --git a/chromium/content/browser/web_contents/web_contents_impl_browsertest.cc b/chromium/content/browser/web_contents/web_contents_impl_browsertest.cc index b06a62884df..1f0586cd33d 100644 --- a/chromium/content/browser/web_contents/web_contents_impl_browsertest.cc +++ b/chromium/content/browser/web_contents/web_contents_impl_browsertest.cc @@ -2,9 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "content/browser/frame_host/navigation_entry_impl.h" #include "content/browser/web_contents/web_contents_impl.h" +#include "content/browser/web_contents/web_contents_view.h" #include "content/public/browser/load_notification_details.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/notification_details.h" @@ -13,13 +15,13 @@ #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents_observer.h" -#include "content/public/browser/web_contents_view.h" #include "content/public/common/content_paths.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_utils.h" #include "content/shell/browser/shell.h" -#include "content/test/content_browser_test.h" -#include "content/test/content_browser_test_utils.h" +#include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" namespace content { @@ -30,17 +32,17 @@ void ResizeWebContentsView(Shell* shell, const gfx::Size& size, // works on Win and ChromeOS but not Linux - we need to resize the shell // window on Linux because if we don't, the next layout of the unchanged shell // window will resize WebContentsView back to the previous size. - // The cleaner and shorter SizeContents is preferred as more platforms convert - // to Aura. -#if defined(TOOLKIT_GTK) || defined(OS_MACOSX) + // SizeContents is a hack and should not be relied on. +#if defined(OS_MACOSX) shell->SizeTo(size); // If |set_start_page| is true, start with blank page to make sure resize // takes effect. if (set_start_page) NavigateToURL(shell, GURL("about://blank")); #else - shell->web_contents()->GetView()->SizeContents(size); -#endif // defined(TOOLKIT_GTK) || defined(OS_MACOSX) + static_cast<WebContentsImpl*>(shell->web_contents())->GetView()-> + SizeContents(size); +#endif // defined(OS_MACOSX) } class WebContentsImplBrowserTest : public ContentBrowserTest { @@ -95,6 +97,7 @@ class NavigateOnCommitObserver : public WebContentsObserver { const LoadCommittedDetails& load_details) OVERRIDE { if (!done_) { done_ = true; + shell_->Stop(); shell_->LoadURL(url_); } } @@ -112,8 +115,8 @@ class RenderViewSizeDelegate : public WebContentsDelegate { // WebContentsDelegate: virtual gfx::Size GetSizeForNewRenderView( - const WebContents* web_contents) const OVERRIDE { - gfx::Size size(web_contents->GetView()->GetContainerSize()); + WebContents* web_contents) const OVERRIDE { + gfx::Size size(web_contents->GetContainerBounds().size()); size.Enlarge(size_insets_.width(), size_insets_.height()); return size; } @@ -149,6 +152,31 @@ class RenderViewSizeObserver : public WebContentsObserver { gfx::Size rwhv_create_size_; }; +class LoadingStateChangedDelegate : public WebContentsDelegate { + public: + LoadingStateChangedDelegate() + : loadingStateChangedCount_(0) + , loadingStateToDifferentDocumentCount_(0) { + } + + // WebContentsDelegate: + virtual void LoadingStateChanged(WebContents* contents, + bool to_different_document) OVERRIDE { + loadingStateChangedCount_++; + if (to_different_document) + loadingStateToDifferentDocumentCount_++; + } + + int loadingStateChangedCount() const { return loadingStateChangedCount_; } + int loadingStateToDifferentDocumentCount() const { + return loadingStateToDifferentDocumentCount_; + } + + private: + int loadingStateChangedCount_; + int loadingStateToDifferentDocumentCount_; +}; + // See: http://crbug.com/298193 #if defined(OS_WIN) #define MAYBE_DidStopLoadingDetails DISABLED_DidStopLoadingDetails @@ -185,6 +213,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, MAYBE_DidStopLoadingDetailsWithPending) { ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); + GURL url("data:text/html,<div>test</div>"); // Listen for the first load to stop. LoadStopNotificationObserver load_observer( @@ -194,10 +223,10 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, // is started. NavigateOnCommitObserver commit_observer( shell(), embedded_test_server()->GetURL("/title2.html")); - NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")); + NavigateToURL(shell(), url); load_observer.Wait(); - EXPECT_EQ("/title1.html", load_observer.url_.path()); + EXPECT_EQ(url, load_observer.url_); EXPECT_EQ(0, load_observer.session_index_); EXPECT_EQ(&shell()->web_contents()->GetController(), load_observer.controller_); @@ -230,11 +259,11 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, shell()->web_contents()->GetVisibleURL()); } -// TODO(sail): enable this for MAC when auto resizing of WebContentsViewCocoa is -// fixed. // TODO(shrikant): enable this for Windows when issue with // force-compositing-mode is resolved (http://crbug.com/281726). -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_ANDROID) +// Also crashes under ThreadSanitizer, http://crbug.com/356758. +#if defined(OS_WIN) || defined(OS_ANDROID) \ + || defined(THREAD_SANITIZER) #define MAYBE_GetSizeForNewRenderView DISABLED_GetSizeForNewRenderView #else #define MAYBE_GetSizeForNewRenderView GetSizeForNewRenderView @@ -256,16 +285,16 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, ASSERT_TRUE(shell()->web_contents()->GetDelegate() == delegate.get()); // When no size is set, RenderWidgetHostView adopts the size of - // WebContenntsView. + // WebContentsView. NavigateToURL(shell(), embedded_test_server()->GetURL("/title2.html")); - EXPECT_EQ(shell()->web_contents()->GetView()->GetContainerSize(), + EXPECT_EQ(shell()->web_contents()->GetContainerBounds().size(), shell()->web_contents()->GetRenderWidgetHostView()->GetViewBounds(). size()); // When a size is set, RenderWidgetHostView and WebContentsView honor this // size. gfx::Size size(300, 300); - gfx::Size size_insets(-10, -15); + gfx::Size size_insets(10, 15); ResizeWebContentsView(shell(), size, true); delegate->set_size_insets(size_insets); NavigateToURL(shell(), https_server.GetURL("/")); @@ -273,14 +302,23 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, EXPECT_EQ(size, shell()->web_contents()->GetRenderWidgetHostView()->GetViewBounds(). size()); - EXPECT_EQ(size, shell()->web_contents()->GetView()->GetContainerSize()); + // The web_contents size is set by the embedder, and should not depend on the + // rwhv size. The behavior is correct on OSX, but incorrect on other + // platforms. + gfx::Size exp_wcv_size(300, 300); +#if !defined(OS_MACOSX) + exp_wcv_size.Enlarge(size_insets.width(), size_insets.height()); +#endif + + EXPECT_EQ(exp_wcv_size, + shell()->web_contents()->GetContainerBounds().size()); // If WebContentsView is resized after RenderWidgetHostView is created but // before pending navigation entry is committed, both RenderWidgetHostView and // WebContentsView use the new size of WebContentsView. gfx::Size init_size(200, 200); gfx::Size new_size(100, 100); - size_insets = gfx::Size(-20, -30); + size_insets = gfx::Size(20, 30); ResizeWebContentsView(shell(), init_size, true); delegate->set_size_insets(size_insets); RenderViewSizeObserver observer(shell(), new_size); @@ -288,21 +326,25 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, // RenderWidgetHostView is created at specified size. init_size.Enlarge(size_insets.width(), size_insets.height()); EXPECT_EQ(init_size, observer.rwhv_create_size()); - // RenderViewSizeObserver resizes WebContentsView in - // DidStartNavigationToPendingEntry, so both WebContentsView and - // RenderWidgetHostView adopt this new size. + +// Once again, the behavior is correct on OSX. The embedder explicitly sets +// the size to (100,100) during navigation. Both the wcv and the rwhv should +// take on that size. +#if !defined(OS_MACOSX) new_size.Enlarge(size_insets.width(), size_insets.height()); - EXPECT_EQ(new_size, - shell()->web_contents()->GetRenderWidgetHostView()->GetViewBounds(). - size()); - EXPECT_EQ(new_size, shell()->web_contents()->GetView()->GetContainerSize()); +#endif + gfx::Size actual_size = shell()->web_contents()->GetRenderWidgetHostView()-> + GetViewBounds().size(); + + EXPECT_EQ(new_size, actual_size); + EXPECT_EQ(new_size, shell()->web_contents()->GetContainerBounds().size()); } IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, OpenURLSubframe) { - // Navigate with source_frame_id 3, FrameTreeNode ID 4. + // Navigate with FrameTreeNode ID 4. const GURL url("http://foo"); - OpenURLParams params(url, Referrer(), 3, 4, CURRENT_TAB, PAGE_TRANSITION_LINK, + OpenURLParams params(url, Referrer(), 4, CURRENT_TAB, PAGE_TRANSITION_LINK, true); shell()->web_contents()->OpenURL(params); @@ -313,5 +355,167 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, OpenURLSubframe) { controller->GetPendingEntry())->frame_tree_node_id()); } +// Observer class to track the creation of RenderFrameHost objects. It is used +// in subsequent tests. +class RenderFrameCreatedObserver : public WebContentsObserver { + public: + RenderFrameCreatedObserver(Shell* shell) + : WebContentsObserver(shell->web_contents()), + last_rfh_(NULL) { + } + + virtual void RenderFrameCreated(RenderFrameHost* render_frame_host) OVERRIDE { + last_rfh_ = render_frame_host; + } + + RenderFrameHost* last_rfh() const { return last_rfh_; } + + private: + RenderFrameHost* last_rfh_; + + DISALLOW_COPY_AND_ASSIGN(RenderFrameCreatedObserver); +}; + +// Test that creation of new RenderFrameHost objects sends the correct object +// to the WebContentObservers. See http://crbug.com/347339. +IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, + RenderFrameCreatedCorrectProcessForObservers) { + std::string foo_com("foo.com"); + GURL::Replacements replace_host; + net::HostPortPair foo_host_port; + GURL cross_site_url; + + // Setup the server to allow serving separate sites, so we can perform + // cross-process navigation. + host_resolver()->AddRule("*", "127.0.0.1"); + ASSERT_TRUE(test_server()->Start()); + + foo_host_port = test_server()->host_port_pair(); + foo_host_port.set_host(foo_com); + + GURL initial_url(test_server()->GetURL("/title1.html")); + + cross_site_url = test_server()->GetURL("/title2.html"); + replace_host.SetHostStr(foo_com); + cross_site_url = cross_site_url.ReplaceComponents(replace_host); + + // Navigate to the initial URL and capture the RenderFrameHost for later + // comparison. + NavigateToURL(shell(), initial_url); + RenderFrameHost* orig_rfh = shell()->web_contents()->GetMainFrame(); + + // Install the observer and navigate cross-site. + RenderFrameCreatedObserver observer(shell()); + NavigateToURL(shell(), cross_site_url); + + // The observer should've seen a RenderFrameCreated call for the new frame + // and not the old one. + EXPECT_NE(observer.last_rfh(), orig_rfh); + EXPECT_EQ(observer.last_rfh(), shell()->web_contents()->GetMainFrame()); +} + +IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, + LoadingStateChangedForSameDocumentNavigation) { + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); + scoped_ptr<LoadingStateChangedDelegate> delegate( + new LoadingStateChangedDelegate()); + shell()->web_contents()->SetDelegate(delegate.get()); + + LoadStopNotificationObserver load_observer( + &shell()->web_contents()->GetController()); + TitleWatcher title_watcher(shell()->web_contents(), + base::ASCIIToUTF16("pushState")); + NavigateToURL(shell(), embedded_test_server()->GetURL("/push_state.html")); + load_observer.Wait(); + base::string16 title = title_watcher.WaitAndGetTitle(); + ASSERT_EQ(title, base::ASCIIToUTF16("pushState")); + + // LoadingStateChanged should be called 4 times: start and stop for the + // initial load of push_state.html, and start and stop for the "navigation" + // triggered by history.pushState(). However, the start notification for the + // history.pushState() navigation should set to_different_document to false. + EXPECT_EQ("pushState", shell()->web_contents()->GetURL().ref()); + EXPECT_EQ(4, delegate->loadingStateChangedCount()); + EXPECT_EQ(3, delegate->loadingStateToDifferentDocumentCount()); +} + +IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, + RenderViewCreatedForChildWindow) { + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); + + NavigateToURL(shell(), + embedded_test_server()->GetURL("/title1.html")); + + WebContentsAddedObserver new_web_contents_observer; + ASSERT_TRUE(ExecuteScript(shell()->web_contents(), + "var a = document.createElement('a');" + "a.href='./title2.html';" + "a.target = '_blank';" + "document.body.appendChild(a);" + "a.click();")); + WebContents* new_web_contents = new_web_contents_observer.GetWebContents(); + WaitForLoadStop(new_web_contents); + EXPECT_TRUE(new_web_contents_observer.RenderViewCreatedCalled()); +} + +struct LoadProgressDelegateAndObserver : public WebContentsDelegate, + public WebContentsObserver { + LoadProgressDelegateAndObserver(Shell* shell) + : WebContentsObserver(shell->web_contents()), + did_start_loading(false), + did_stop_loading(false) { + web_contents()->SetDelegate(this); + } + + // WebContentsDelegate: + virtual void LoadProgressChanged(WebContents* source, + double progress) OVERRIDE { + EXPECT_TRUE(did_start_loading); + EXPECT_FALSE(did_stop_loading); + progresses.push_back(progress); + } + + // WebContentsObserver: + virtual void DidStartLoading(RenderViewHost* render_view_host) OVERRIDE { + EXPECT_FALSE(did_start_loading); + EXPECT_EQ(0U, progresses.size()); + EXPECT_FALSE(did_stop_loading); + did_start_loading = true; + } + + virtual void DidStopLoading(RenderViewHost* render_view_host) OVERRIDE { + EXPECT_TRUE(did_start_loading); + EXPECT_GE(progresses.size(), 1U); + EXPECT_FALSE(did_stop_loading); + did_stop_loading = true; + } + + bool did_start_loading; + std::vector<double> progresses; + bool did_stop_loading; +}; + +IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, LoadProgress) { + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); + scoped_ptr<LoadProgressDelegateAndObserver> delegate( + new LoadProgressDelegateAndObserver(shell())); + + NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")); + + const std::vector<double>& progresses = delegate->progresses; + // All updates should be in order ... + if (std::adjacent_find(progresses.begin(), + progresses.end(), + std::greater<double>()) != progresses.end()) { + ADD_FAILURE() << "Progress values should be in order: " + << ::testing::PrintToString(progresses); + } + + // ... and the last one should be 1.0, meaning complete. + ASSERT_GE(progresses.size(), 1U) + << "There should be at least one progress update"; + EXPECT_EQ(1.0, *progresses.rbegin()); +} } // namespace content + |