Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(320)

Unified Diff: content/browser/web_contents/opened_by_dom_browsertest.cc

Issue 212703005: Preserve Page::openedByDOM state across process swaps. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/web_contents/opened_by_dom_browsertest.cc
diff --git a/content/browser/web_contents/opened_by_dom_browsertest.cc b/content/browser/web_contents/opened_by_dom_browsertest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1c2d94099ce1d94e0d8c3fa126a974360f523b6a
--- /dev/null
+++ b/content/browser/web_contents/opened_by_dom_browsertest.cc
@@ -0,0 +1,139 @@
+// 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 "base/command_line.h"
+#include "base/strings/stringprintf.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_delegate.h"
+#include "content/public/common/content_switches.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/shell/browser/shell.h"
+#include "net/dns/mock_host_resolver.h"
+#include "url/gurl.h"
+
+namespace content {
+
+namespace {
+
+// A dummy WebContentsDelegate which tracks whether CloseContents() has been
+// called. It refuses the actual close but keeps track of whether the renderer
+// requested it.
+class CloseTrackingDelegate : public WebContentsDelegate {
+ public:
+ CloseTrackingDelegate() : close_contents_called_(false) {}
+
+ bool close_contents_called() const { return close_contents_called_; }
+
+ virtual void CloseContents(WebContents* source) OVERRIDE {
+ close_contents_called_ = true;
+ }
+
+ private:
+ bool close_contents_called_;
+
+ DISALLOW_COPY_AND_ASSIGN(CloseTrackingDelegate);
+};
+
+} // namespace
+
+class OpenedByDOMTest : public ContentBrowserTest {
+ protected:
+ virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+ // Use --site-per-process to force process swaps on cross-site navigations.
+ command_line->AppendSwitch(switches::kSitePerProcess);
+ }
+
+ bool AttemptCloseFromJavaScript(WebContents* web_contents) {
+ CloseTrackingDelegate close_tracking_delegate;
+ WebContentsDelegate* old_delegate = web_contents->GetDelegate();
+ web_contents->SetDelegate(&close_tracking_delegate);
+
+ const char kCloseWindowScript[] =
+ // Close the window.
+ "window.close();"
+ // Report back after an event loop iteration; the close IPC isn't sent
+ // immediately.
+ "setTimeout(function() {"
+ "window.domAutomationController.send(0);"
+ "});";
+ int dummy;
+ CHECK(ExecuteScriptAndExtractInt(web_contents, kCloseWindowScript, &dummy));
+
+ web_contents->SetDelegate(old_delegate);
+ return close_tracking_delegate.close_contents_called();
+ }
+
+ Shell* OpenWindowFromJavaScript(Shell* shell, const GURL& url) {
+ // Wait for the popup to be created and for it to have navigated.
+ ShellAddedObserver new_shell_observer;
+ TestNavigationObserver nav_observer(NULL);
+ nav_observer.StartWatchingNewWebContents();
+ CHECK(ExecuteScript(
+ shell->web_contents(),
+ base::StringPrintf("window.open('%s')", url.spec().c_str())));
+ nav_observer.Wait();
+ return new_shell_observer.GetShell();
+ }
+};
+
+// Tests that window.close() does not work on a normal window that has navigated
+// a few times.
+IN_PROC_BROWSER_TEST_F(OpenedByDOMTest, NormalWindow) {
+ ASSERT_TRUE(test_server()->Start());
+
+ // window.close is allowed if the window was opened by DOM OR the back/forward
+ // list has only one element. Navigate a bit so the second condition is false.
+ GURL url1 = test_server()->GetURL("files/site_isolation/blank.html?1");
+ GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2");
+ NavigateToURL(shell(), url1);
+ NavigateToURL(shell(), url2);
+
+ // This window was not opened by DOM, so close does not reach the browser
+ // process.
+ EXPECT_FALSE(AttemptCloseFromJavaScript(shell()->web_contents()));
+}
+
+// Tests that window.close() works in a popup window that has navigated a few
+// times.
+IN_PROC_BROWSER_TEST_F(OpenedByDOMTest, Popup) {
+ ASSERT_TRUE(test_server()->Start());
+
+ GURL url1 = test_server()->GetURL("files/site_isolation/blank.html?1");
+ GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2");
+ GURL url3 = test_server()->GetURL("files/site_isolation/blank.html?3");
+ NavigateToURL(shell(), url1);
+
+ Shell* popup = OpenWindowFromJavaScript(shell(), url2);
+ NavigateToURL(popup, url3);
+ EXPECT_TRUE(AttemptCloseFromJavaScript(popup->web_contents()));
+}
+
+// Tests that window.close() works in a popup window that has navigated a few
+// times and swapped processes.
+IN_PROC_BROWSER_TEST_F(OpenedByDOMTest, CrossProcessPopup) {
+ host_resolver()->AddRule("*", "127.0.0.1");
+ ASSERT_TRUE(test_server()->Start());
+
+ GURL url1 = test_server()->GetURL("files/site_isolation/blank.html?1");
+
+ GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2");
+ GURL::Replacements replace_host;
+ std::string foo_com("foo.com");
+ replace_host.SetHostStr(foo_com);
+ url2 = url2.ReplaceComponents(replace_host);
+
+ GURL url3 = test_server()->GetURL("files/site_isolation/blank.html?3");
+ url3 = url3.ReplaceComponents(replace_host);
+
+ NavigateToURL(shell(), url1);
+
+ Shell* popup = OpenWindowFromJavaScript(shell(), url2);
+ NavigateToURL(popup, url3);
+ EXPECT_TRUE(AttemptCloseFromJavaScript(popup->web_contents()));
+}
+
+} // namespace content
« no previous file with comments | « content/browser/renderer_host/render_view_host_impl.cc ('k') | content/browser/web_contents/web_contents_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698