OLD | NEW |
---|---|
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 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
241 TestJavaScriptDialogManager dialog_manager; | 241 TestJavaScriptDialogManager dialog_manager; |
242 wc->SetDelegate(&dialog_manager); | 242 wc->SetDelegate(&dialog_manager); |
243 | 243 |
244 EXPECT_TRUE(NavigateToURL(shell(), GURL("about:blank"))); | 244 EXPECT_TRUE(NavigateToURL(shell(), GURL("about:blank"))); |
245 // Make an iframe with a beforeunload handler. | 245 // Make an iframe with a beforeunload handler. |
246 std::string script = | 246 std::string script = |
247 "var iframe = document.createElement('iframe');" | 247 "var iframe = document.createElement('iframe');" |
248 "document.body.appendChild(iframe);" | 248 "document.body.appendChild(iframe);" |
249 "iframe.contentWindow.onbeforeunload=function(e){return 'x'};"; | 249 "iframe.contentWindow.onbeforeunload=function(e){return 'x'};"; |
250 EXPECT_TRUE(content::ExecuteScript(wc, script)); | 250 EXPECT_TRUE(content::ExecuteScript(wc, script)); |
251 EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); | 251 EXPECT_TRUE(WaitForLoadStop(wc)); |
252 | |
253 // JavaScript onbeforeunload dialogs require a user gesture. | |
254 for (auto* frame : wc->GetAllFrames()) | |
255 frame->ExecuteJavaScriptWithUserGestureForTests(base::string16()); | |
252 | 256 |
253 // Force a process switch by going to a privileged page. The beforeunload | 257 // Force a process switch by going to a privileged page. The beforeunload |
254 // timer will be started on the top-level frame but will be paused while the | 258 // timer will be started on the top-level frame but will be paused while the |
255 // beforeunload dialog is shown by the subframe. | 259 // beforeunload dialog is shown by the subframe. |
256 GURL web_ui_page(std::string(kChromeUIScheme) + "://" + | 260 GURL web_ui_page(std::string(kChromeUIScheme) + "://" + |
257 std::string(kChromeUIGpuHost)); | 261 std::string(kChromeUIGpuHost)); |
258 shell()->LoadURL(web_ui_page); | 262 shell()->LoadURL(web_ui_page); |
259 dialog_manager.Wait(); | 263 dialog_manager.Wait(); |
260 | 264 |
261 RenderFrameHostImpl* main_frame = | 265 RenderFrameHostImpl* main_frame = |
(...skipping 12 matching lines...) Expand all Loading... | |
274 // There will be no beforeunload ACK, so if the beforeunload ACK timer isn't | 278 // There will be no beforeunload ACK, so if the beforeunload ACK timer isn't |
275 // functioning then the navigation will hang forever and this test will time | 279 // functioning then the navigation will hang forever and this test will time |
276 // out. If this waiting for the load stop works, this test won't time out. | 280 // out. If this waiting for the load stop works, this test won't time out. |
277 EXPECT_TRUE(WaitForLoadStop(wc)); | 281 EXPECT_TRUE(WaitForLoadStop(wc)); |
278 EXPECT_EQ(web_ui_page, wc->GetLastCommittedURL()); | 282 EXPECT_EQ(web_ui_page, wc->GetLastCommittedURL()); |
279 | 283 |
280 wc->SetDelegate(nullptr); | 284 wc->SetDelegate(nullptr); |
281 wc->SetJavaScriptDialogManagerForTesting(nullptr); | 285 wc->SetJavaScriptDialogManagerForTesting(nullptr); |
282 } | 286 } |
283 | 287 |
288 // Tests that a gesture is required in a frame before it can request a | |
289 // beforeunload dialog. | |
290 IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest, | |
291 BeforeUnloadDialogRequiresGesture) { | |
292 WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents()); | |
293 TestJavaScriptDialogManager dialog_manager; | |
294 wc->SetDelegate(&dialog_manager); | |
295 | |
296 EXPECT_TRUE(NavigateToURL( | |
297 shell(), GetTestUrl("render_frame_host", "beforeunload.html"))); | |
298 // Disable the hang monitor, otherwise there will be a race between the | |
299 // beforeunload dialog and the beforeunload hang timer. | |
300 wc->GetMainFrame()->DisableBeforeUnloadHangMonitorForTesting(); | |
Nico
2017/04/07 20:05:28
Huh, I guess it makes sense here.
Avi (use Gerrit)
2017/05/05 15:30:04
Done.
| |
301 | |
302 // Reload. There should be no beforeunload dialog because there was no gesture | |
303 // on the page. If there was, this WaitForLoadStop call will hang. | |
304 wc->GetController().Reload(ReloadType::NORMAL, false); | |
305 EXPECT_TRUE(WaitForLoadStop(wc)); | |
306 | |
307 // Give the page a user gesture and try leaving again. This time there | |
308 // should be a dialog. If there is no dialog, the call to Wait will hang. | |
309 wc->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests( | |
310 base::string16()); | |
311 shell()->LoadURL(GURL("about:blank")); | |
312 dialog_manager.Wait(); | |
313 | |
314 // Answer the dialog. | |
315 dialog_manager.callback().Run(false, base::string16()); | |
316 | |
317 wc->SetDelegate(nullptr); | |
318 wc->SetJavaScriptDialogManagerForTesting(nullptr); | |
319 } | |
320 | |
284 } // namespace content | 321 } // namespace content |
OLD | NEW |