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

Unified Diff: content/browser/frame_host/render_frame_host_impl_browsertest.cc

Issue 2801813005: Only show a beforeunload dialog if a frame has had a user gesture since its load. (Closed)
Patch Set: one last bit Created 3 years, 7 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
« no previous file with comments | « chrome/browser/unload_browsertest.cc ('k') | content/browser/web_contents/web_contents_impl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/frame_host/render_frame_host_impl_browsertest.cc
diff --git a/content/browser/frame_host/render_frame_host_impl_browsertest.cc b/content/browser/frame_host/render_frame_host_impl_browsertest.cc
index f975aa9981412c1962460d20e0290ca201c6878f..0200d46af4aadc3a7acde981a7c7b4ae20df07b7 100644
--- a/content/browser/frame_host/render_frame_host_impl_browsertest.cc
+++ b/content/browser/frame_host/render_frame_host_impl_browsertest.cc
@@ -247,7 +247,10 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
"document.body.appendChild(iframe);"
"iframe.contentWindow.onbeforeunload=function(e){return 'x'};";
EXPECT_TRUE(content::ExecuteScript(wc, script));
- EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+ EXPECT_TRUE(WaitForLoadStop(wc));
+ // JavaScript onbeforeunload dialogs require a user gesture.
+ for (auto* frame : wc->GetAllFrames())
+ frame->ExecuteJavaScriptWithUserGestureForTests(base::string16());
// Force a process switch by going to a privileged page. The beforeunload
// timer will be started on the top-level frame but will be paused while the
@@ -280,4 +283,43 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
wc->SetJavaScriptDialogManagerForTesting(nullptr);
}
+// Tests that a gesture is required in a frame before it can request a
+// beforeunload dialog.
+IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
+ BeforeUnloadDialogRequiresGesture) {
+ WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents());
+ TestJavaScriptDialogManager dialog_manager;
+ wc->SetDelegate(&dialog_manager);
+
+ EXPECT_TRUE(NavigateToURL(
+ shell(), GetTestUrl("render_frame_host", "beforeunload.html")));
+ // Disable the hang monitor, otherwise there will be a race between the
+ // beforeunload dialog and the beforeunload hang timer.
+ wc->GetMainFrame()->DisableBeforeUnloadHangMonitorForTesting();
+
+ // Reload. There should be no beforeunload dialog because there was no gesture
+ // on the page. If there was, this WaitForLoadStop call will hang.
+ wc->GetController().Reload(ReloadType::NORMAL, false);
+ EXPECT_TRUE(WaitForLoadStop(wc));
+
+ // Give the page a user gesture and try reloading again. This time there
+ // should be a dialog. If there is no dialog, the call to Wait will hang.
+ wc->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests(
+ base::string16());
+ wc->GetController().Reload(ReloadType::NORMAL, false);
+ dialog_manager.Wait();
+
+ // Answer the dialog.
+ dialog_manager.callback().Run(true, base::string16());
+ EXPECT_TRUE(WaitForLoadStop(wc));
+
+ // The reload should have cleared the user gesture bit, so upon leaving again
+ // there should be no beforeunload dialog.
+ shell()->LoadURL(GURL("about:blank"));
+ EXPECT_TRUE(WaitForLoadStop(wc));
+
+ wc->SetDelegate(nullptr);
+ wc->SetJavaScriptDialogManagerForTesting(nullptr);
+}
+
} // namespace content
« no previous file with comments | « chrome/browser/unload_browsertest.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