1 /* Any copyright is dedicated to the Public Domain.
2 http://creativecommons.org/publicdomain/zero/1.0/ */
4 const TEST_PATH = getRootDirectory(gTestPath).replace(
5 "chrome://mochitests/content",
6 // eslint-disable-next-line @microsoft/sdl/no-insecure-url
10 const { PromptTestUtils } = ChromeUtils.importESModule(
11 "resource://testing-common/PromptTestUtils.sys.mjs"
14 SimpleTest.requestFlakyTimeout("Needs to test a timeout");
16 function delay(msec) {
17 // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
18 return new Promise(resolve => setTimeout(resolve, msec));
21 function allowNextNavigation(browser) {
22 return PromptTestUtils.handleNextPrompt(
24 { modalType: Services.prompt.MODAL_TYPE_CONTENT, promptType: "confirmEx" },
29 function cancelNextNavigation(browser) {
30 return PromptTestUtils.handleNextPrompt(
32 { modalType: Services.prompt.MODAL_TYPE_CONTENT, promptType: "confirmEx" },
37 add_task(async function test() {
38 await SpecialPowers.pushPrefEnv({
39 set: [["dom.require_user_interaction_for_beforeunload", false]],
42 const permitUnloadTimeout = Services.prefs.getIntPref(
43 "dom.beforeunload_timeout_ms"
46 let url = TEST_PATH + "dummy_page.html";
47 let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
48 let browser = tab.linkedBrowser;
50 await SpecialPowers.spawn(browser.browsingContext, [], () => {
51 content.addEventListener("beforeunload", event => {
52 event.preventDefault();
57 * Check condition where beforeunload handlers request a prompt.
60 // Prompt is shown, user clicks OK.
62 let promptShownPromise = allowNextNavigation(browser);
63 ok(browser.permitUnload().permitUnload, "permit unload should be true");
64 await promptShownPromise;
66 // Prompt is shown, user clicks CANCEL.
67 promptShownPromise = cancelNextNavigation(browser);
68 ok(!browser.permitUnload().permitUnload, "permit unload should be false");
69 await promptShownPromise;
71 // Prompt is not shown, don't permit unload.
72 let promptShown = false;
73 let shownCallback = () => {
77 browser.addEventListener("DOMWillOpenModalDialog", shownCallback);
79 !browser.permitUnload("dontUnload").permitUnload,
80 "permit unload should be false"
82 ok(!promptShown, "prompt should not have been displayed");
84 // Prompt is not shown, permit unload.
87 browser.permitUnload("unload").permitUnload,
88 "permit unload should be true"
90 ok(!promptShown, "prompt should not have been displayed");
91 browser.removeEventListener("DOMWillOpenModalDialog", shownCallback);
93 promptShownPromise = PromptTestUtils.waitForPrompt(browser, {
94 modalType: Services.prompt.MODAL_TYPE_CONTENT,
95 promptType: "confirmEx",
98 let promptDismissed = false;
99 let closedCallback = () => {
100 promptDismissed = true;
103 browser.addEventListener("DOMModalDialogClosed", closedCallback);
105 let promise = browser.asyncPermitUnload();
107 let promiseResolved = false;
109 promiseResolved = true;
112 let dialog = await promptShownPromise;
113 ok(!promiseResolved, "Should not have resolved promise yet");
115 await delay(permitUnloadTimeout * 1.5);
117 ok(!promptDismissed, "Should not have dismissed prompt yet");
118 ok(!promiseResolved, "Should not have resolved promise yet");
120 await PromptTestUtils.handlePrompt(dialog, { buttonNumClick: 1 });
122 let { permitUnload } = await promise;
123 ok(promptDismissed, "Should have dismissed prompt");
124 ok(!permitUnload, "Should not have permitted unload");
126 browser.removeEventListener("DOMModalDialogClosed", closedCallback);
128 promptShownPromise = allowNextNavigation(browser);
131 * Check condition where no one requests a prompt. In all cases,
132 * permitUnload should be true, and all handlers fired.
135 BrowserTestUtils.startLoadingURIString(browser, url);
136 await BrowserTestUtils.browserLoaded(browser, false, url);
137 await promptShownPromise;
140 browser.addEventListener("DOMWillOpenModalDialog", shownCallback);
142 ok(browser.permitUnload().permitUnload, "permit unload should be true");
143 ok(!promptShown, "prompt should not have been displayed");
147 browser.permitUnload("dontUnload").permitUnload,
148 "permit unload should be true"
150 ok(!promptShown, "prompt should not have been displayed");
154 browser.permitUnload("unload").permitUnload,
155 "permit unload should be true"
157 ok(!promptShown, "prompt should not have been displayed");
159 browser.removeEventListener("DOMWillOpenModalDialog", shownCallback);
161 await BrowserTestUtils.removeTab(tab, { skipPermitUnload: true });