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

Side by Side 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 unified diff | 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/frame_host/render_frame_host_impl.h" 5 #include "content/browser/frame_host/render_frame_host_impl.h"
6 6
7 #include "base/macros.h" 7 #include "base/macros.h"
8 #include "content/browser/web_contents/web_contents_impl.h" 8 #include "content/browser/web_contents/web_contents_impl.h"
9 #include "content/common/frame_messages.h" 9 #include "content/common/frame_messages.h"
10 #include "content/public/browser/javascript_dialog_manager.h" 10 #include "content/public/browser/javascript_dialog_manager.h"
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 TestJavaScriptDialogManager dialog_manager; 240 TestJavaScriptDialogManager dialog_manager;
241 wc->SetDelegate(&dialog_manager); 241 wc->SetDelegate(&dialog_manager);
242 242
243 EXPECT_TRUE(NavigateToURL(shell(), GURL("about:blank"))); 243 EXPECT_TRUE(NavigateToURL(shell(), GURL("about:blank")));
244 // Make an iframe with a beforeunload handler. 244 // Make an iframe with a beforeunload handler.
245 std::string script = 245 std::string script =
246 "var iframe = document.createElement('iframe');" 246 "var iframe = document.createElement('iframe');"
247 "document.body.appendChild(iframe);" 247 "document.body.appendChild(iframe);"
248 "iframe.contentWindow.onbeforeunload=function(e){return 'x'};"; 248 "iframe.contentWindow.onbeforeunload=function(e){return 'x'};";
249 EXPECT_TRUE(content::ExecuteScript(wc, script)); 249 EXPECT_TRUE(content::ExecuteScript(wc, script));
250 EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); 250 EXPECT_TRUE(WaitForLoadStop(wc));
251 // JavaScript onbeforeunload dialogs require a user gesture.
252 for (auto* frame : wc->GetAllFrames())
253 frame->ExecuteJavaScriptWithUserGestureForTests(base::string16());
251 254
252 // Force a process switch by going to a privileged page. The beforeunload 255 // Force a process switch by going to a privileged page. The beforeunload
253 // timer will be started on the top-level frame but will be paused while the 256 // timer will be started on the top-level frame but will be paused while the
254 // beforeunload dialog is shown by the subframe. 257 // beforeunload dialog is shown by the subframe.
255 GURL web_ui_page(std::string(kChromeUIScheme) + "://" + 258 GURL web_ui_page(std::string(kChromeUIScheme) + "://" +
256 std::string(kChromeUIGpuHost)); 259 std::string(kChromeUIGpuHost));
257 shell()->LoadURL(web_ui_page); 260 shell()->LoadURL(web_ui_page);
258 dialog_manager.Wait(); 261 dialog_manager.Wait();
259 262
260 RenderFrameHostImpl* main_frame = 263 RenderFrameHostImpl* main_frame =
(...skipping 12 matching lines...) Expand all
273 // There will be no beforeunload ACK, so if the beforeunload ACK timer isn't 276 // There will be no beforeunload ACK, so if the beforeunload ACK timer isn't
274 // functioning then the navigation will hang forever and this test will time 277 // functioning then the navigation will hang forever and this test will time
275 // out. If this waiting for the load stop works, this test won't time out. 278 // out. If this waiting for the load stop works, this test won't time out.
276 EXPECT_TRUE(WaitForLoadStop(wc)); 279 EXPECT_TRUE(WaitForLoadStop(wc));
277 EXPECT_EQ(web_ui_page, wc->GetLastCommittedURL()); 280 EXPECT_EQ(web_ui_page, wc->GetLastCommittedURL());
278 281
279 wc->SetDelegate(nullptr); 282 wc->SetDelegate(nullptr);
280 wc->SetJavaScriptDialogManagerForTesting(nullptr); 283 wc->SetJavaScriptDialogManagerForTesting(nullptr);
281 } 284 }
282 285
286 // Tests that a gesture is required in a frame before it can request a
287 // beforeunload dialog.
288 IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
289 BeforeUnloadDialogRequiresGesture) {
290 WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents());
291 TestJavaScriptDialogManager dialog_manager;
292 wc->SetDelegate(&dialog_manager);
293
294 EXPECT_TRUE(NavigateToURL(
295 shell(), GetTestUrl("render_frame_host", "beforeunload.html")));
296 // Disable the hang monitor, otherwise there will be a race between the
297 // beforeunload dialog and the beforeunload hang timer.
298 wc->GetMainFrame()->DisableBeforeUnloadHangMonitorForTesting();
299
300 // Reload. There should be no beforeunload dialog because there was no gesture
301 // on the page. If there was, this WaitForLoadStop call will hang.
302 wc->GetController().Reload(ReloadType::NORMAL, false);
303 EXPECT_TRUE(WaitForLoadStop(wc));
304
305 // Give the page a user gesture and try reloading again. This time there
306 // should be a dialog. If there is no dialog, the call to Wait will hang.
307 wc->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests(
308 base::string16());
309 wc->GetController().Reload(ReloadType::NORMAL, false);
310 dialog_manager.Wait();
311
312 // Answer the dialog.
313 dialog_manager.callback().Run(true, base::string16());
314 EXPECT_TRUE(WaitForLoadStop(wc));
315
316 // The reload should have cleared the user gesture bit, so upon leaving again
317 // there should be no beforeunload dialog.
318 shell()->LoadURL(GURL("about:blank"));
319 EXPECT_TRUE(WaitForLoadStop(wc));
320
321 wc->SetDelegate(nullptr);
322 wc->SetJavaScriptDialogManagerForTesting(nullptr);
323 }
324
283 } // namespace content 325 } // namespace content
OLDNEW
« 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