Commit 82064acd authored by Andrey Lushnikov's avatar Andrey Lushnikov Committed by Commit Bot

headless: do not close WebContents if beforeunload was dismissed

Currently, headless can dismiss beforeunload dialogs, but the target
page will still proceed to close since default implementation in content/
disregards BeforeUnload results: https://source.chromium.org/chromium/chromium/src/+/master:content/public/browser/web_contents_delegate.cc;l=64?q=BeforeUnloadFired%20f:content&ss=chromium%2Fchromium%2Fsrc

This patch changes this.

Change-Id: I2c1a04dde390dbb90ac8c547187405fa513d0723
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2516217
Commit-Queue: Andrey Lushnikov <lushnikov@chromium.org>
Reviewed-by: default avatarAndrey Kosyakov <caseq@chromium.org>
Cr-Commit-Position: refs/heads/master@{#823751}
parent 7007308f
...@@ -89,6 +89,12 @@ class HeadlessWebContentsImpl::Delegate : public content::WebContentsDelegate { ...@@ -89,6 +89,12 @@ class HeadlessWebContentsImpl::Delegate : public content::WebContentsDelegate {
*visible_security_state.get(), security_style_explanations); *visible_security_state.get(), security_style_explanations);
} }
void BeforeUnloadFired(content::WebContents* web_contents,
bool proceed,
bool* proceed_to_fire_unload) override {
*proceed_to_fire_unload = proceed;
}
void ActivateContents(content::WebContents* contents) override { void ActivateContents(content::WebContents* contents) override {
contents->GetMainFrame()->GetRenderViewHost()->GetWidget()->Focus(); contents->GetMainFrame()->GetRenderViewHost()->GetWidget()->Focus();
} }
......
Tests beforeunload dialog.
beforeunload
beforeunload
\ No newline at end of file
// Copyright 2020 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.
(async function(testRunner) {
const {page, session, dp} = await testRunner.startBlank(
`Tests beforeunload dialog.`);
await dp.Page.enable();
dp.Page.navigate({url: testRunner.url('/resources/beforeunload.html')});
await dp.Page.onceLoadEventFired();
// Click to activate beforeunload handling.
await dp.Input.dispatchMouseEvent({
type: 'mousePressed',
button: 'left',
buttons: 0,
clickCount: 1,
x: 1,
y: 1,
});
await dp.Input.dispatchMouseEvent({
type: 'mouseReleased',
button: 'left',
buttons: 0,
clickCount: 1,
x: 1,
y: 1,
});
// Try closing first time.
dp.Page.close();
const dialog = await dp.Page.onceJavascriptDialogOpening();
testRunner.log(dialog.params.type);
dp.Page.handleJavaScriptDialog({ accept: false, });
await dp.Page.javascriptDialogClosed();
// Try closing second time. This will make sure that
// the page didn't close after the first beforeunload dialog
// was canceled.
dp.Page.close();
const dialog2 = await dp.Page.onceJavascriptDialogOpening();
testRunner.log(dialog2.params.type);
await dp.Page.handleJavaScriptDialog({ accept: true, }),
testRunner.completeTest();
})
<!DOCTYPE html>
<html>
<head>
</head>
<body>
</body>
<script>
window.onbeforeunload=function(e){
return 'foo';
}
</script>
</html>
...@@ -239,6 +239,8 @@ HEADLESS_PROTOCOL_TEST(VirtualTimeFetchKeepalive, ...@@ -239,6 +239,8 @@ HEADLESS_PROTOCOL_TEST(VirtualTimeFetchKeepalive,
HEADLESS_PROTOCOL_TEST(VirtualTimeDisposeWhileRunning, HEADLESS_PROTOCOL_TEST(VirtualTimeDisposeWhileRunning,
"emulation/virtual-time-dispose-while-running.js") "emulation/virtual-time-dispose-while-running.js")
HEADLESS_PROTOCOL_TEST(PageBeforeUnload, "page/page-before-unload.js")
// http://crbug.com/633321 // http://crbug.com/633321
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
#define MAYBE_VirtualTimeTimerOrder DISABLED_VirtualTimeTimerOrder #define MAYBE_VirtualTimeTimerOrder DISABLED_VirtualTimeTimerOrder
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment