summaryrefslogtreecommitdiffstats
path: root/docshell/test/browser/browser_bug1415918_beforeunload_options.js
diff options
context:
space:
mode:
Diffstat (limited to 'docshell/test/browser/browser_bug1415918_beforeunload_options.js')
-rw-r--r--docshell/test/browser/browser_bug1415918_beforeunload_options.js162
1 files changed, 162 insertions, 0 deletions
diff --git a/docshell/test/browser/browser_bug1415918_beforeunload_options.js b/docshell/test/browser/browser_bug1415918_beforeunload_options.js
new file mode 100644
index 0000000000..4aec24cda4
--- /dev/null
+++ b/docshell/test/browser/browser_bug1415918_beforeunload_options.js
@@ -0,0 +1,162 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const TEST_PATH = getRootDirectory(gTestPath).replace(
+ "chrome://mochitests/content",
+ // eslint-disable-next-line @microsoft/sdl/no-insecure-url
+ "http://example.com"
+);
+
+const { PromptTestUtils } = ChromeUtils.importESModule(
+ "resource://testing-common/PromptTestUtils.sys.mjs"
+);
+
+SimpleTest.requestFlakyTimeout("Needs to test a timeout");
+
+function delay(msec) {
+ // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
+ return new Promise(resolve => setTimeout(resolve, msec));
+}
+
+function allowNextNavigation(browser) {
+ return PromptTestUtils.handleNextPrompt(
+ browser,
+ { modalType: Services.prompt.MODAL_TYPE_CONTENT, promptType: "confirmEx" },
+ { buttonNumClick: 0 }
+ );
+}
+
+function cancelNextNavigation(browser) {
+ return PromptTestUtils.handleNextPrompt(
+ browser,
+ { modalType: Services.prompt.MODAL_TYPE_CONTENT, promptType: "confirmEx" },
+ { buttonNumClick: 1 }
+ );
+}
+
+add_task(async function test() {
+ await SpecialPowers.pushPrefEnv({
+ set: [["dom.require_user_interaction_for_beforeunload", false]],
+ });
+
+ const permitUnloadTimeout = Services.prefs.getIntPref(
+ "dom.beforeunload_timeout_ms"
+ );
+
+ let url = TEST_PATH + "dummy_page.html";
+ let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
+ let browser = tab.linkedBrowser;
+
+ await SpecialPowers.spawn(browser.browsingContext, [], () => {
+ content.addEventListener("beforeunload", event => {
+ event.preventDefault();
+ });
+ });
+
+ /*
+ * Check condition where beforeunload handlers request a prompt.
+ */
+
+ // Prompt is shown, user clicks OK.
+
+ let promptShownPromise = allowNextNavigation(browser);
+ ok(browser.permitUnload().permitUnload, "permit unload should be true");
+ await promptShownPromise;
+
+ // Prompt is shown, user clicks CANCEL.
+ promptShownPromise = cancelNextNavigation(browser);
+ ok(!browser.permitUnload().permitUnload, "permit unload should be false");
+ await promptShownPromise;
+
+ // Prompt is not shown, don't permit unload.
+ let promptShown = false;
+ let shownCallback = () => {
+ promptShown = true;
+ };
+
+ browser.addEventListener("DOMWillOpenModalDialog", shownCallback);
+ ok(
+ !browser.permitUnload("dontUnload").permitUnload,
+ "permit unload should be false"
+ );
+ ok(!promptShown, "prompt should not have been displayed");
+
+ // Prompt is not shown, permit unload.
+ promptShown = false;
+ ok(
+ browser.permitUnload("unload").permitUnload,
+ "permit unload should be true"
+ );
+ ok(!promptShown, "prompt should not have been displayed");
+ browser.removeEventListener("DOMWillOpenModalDialog", shownCallback);
+
+ promptShownPromise = PromptTestUtils.waitForPrompt(browser, {
+ modalType: Services.prompt.MODAL_TYPE_CONTENT,
+ promptType: "confirmEx",
+ });
+
+ let promptDismissed = false;
+ let closedCallback = () => {
+ promptDismissed = true;
+ };
+
+ browser.addEventListener("DOMModalDialogClosed", closedCallback);
+
+ let promise = browser.asyncPermitUnload();
+
+ let promiseResolved = false;
+ promise.then(() => {
+ promiseResolved = true;
+ });
+
+ let dialog = await promptShownPromise;
+ ok(!promiseResolved, "Should not have resolved promise yet");
+
+ await delay(permitUnloadTimeout * 1.5);
+
+ ok(!promptDismissed, "Should not have dismissed prompt yet");
+ ok(!promiseResolved, "Should not have resolved promise yet");
+
+ await PromptTestUtils.handlePrompt(dialog, { buttonNumClick: 1 });
+
+ let { permitUnload } = await promise;
+ ok(promptDismissed, "Should have dismissed prompt");
+ ok(!permitUnload, "Should not have permitted unload");
+
+ browser.removeEventListener("DOMModalDialogClosed", closedCallback);
+
+ promptShownPromise = allowNextNavigation(browser);
+
+ /*
+ * Check condition where no one requests a prompt. In all cases,
+ * permitUnload should be true, and all handlers fired.
+ */
+ url += "?1";
+ BrowserTestUtils.loadURIString(browser, url);
+ await BrowserTestUtils.browserLoaded(browser, false, url);
+ await promptShownPromise;
+
+ promptShown = false;
+ browser.addEventListener("DOMWillOpenModalDialog", shownCallback);
+
+ ok(browser.permitUnload().permitUnload, "permit unload should be true");
+ ok(!promptShown, "prompt should not have been displayed");
+
+ promptShown = false;
+ ok(
+ browser.permitUnload("dontUnload").permitUnload,
+ "permit unload should be true"
+ );
+ ok(!promptShown, "prompt should not have been displayed");
+
+ promptShown = false;
+ ok(
+ browser.permitUnload("unload").permitUnload,
+ "permit unload should be true"
+ );
+ ok(!promptShown, "prompt should not have been displayed");
+
+ browser.removeEventListener("DOMWillOpenModalDialog", shownCallback);
+
+ await BrowserTestUtils.removeTab(tab, { skipPermitUnload: true });
+});