summaryrefslogtreecommitdiffstats
path: root/chromium/content/browser/web_contents/web_contents_impl_browsertest.cc
diff options
context:
space:
mode:
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.cc262
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
+