summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/tabPrompts/browser_windowPrompt.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/base/content/test/tabPrompts/browser_windowPrompt.js')
-rw-r--r--browser/base/content/test/tabPrompts/browser_windowPrompt.js248
1 files changed, 248 insertions, 0 deletions
diff --git a/browser/base/content/test/tabPrompts/browser_windowPrompt.js b/browser/base/content/test/tabPrompts/browser_windowPrompt.js
new file mode 100644
index 0000000000..fa908d8073
--- /dev/null
+++ b/browser/base/content/test/tabPrompts/browser_windowPrompt.js
@@ -0,0 +1,248 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+/**
+ * Check that the in-window modal dialogs work correctly.
+ */
+add_task(async function test_check_window_modal_prompt_service() {
+ await SpecialPowers.pushPrefEnv({
+ set: [["prompts.windowPromptSubDialog", true]],
+ });
+ let dialogPromise = BrowserTestUtils.promiseAlertDialogOpen();
+ // Avoid blocking the test on the (sync) alert by sticking it in a timeout:
+ setTimeout(
+ () => Services.prompt.alert(window, "Some title", "some message"),
+ 0
+ );
+ let dialogWin = await dialogPromise;
+
+ // Check dialog content:
+ is(
+ dialogWin.document.getElementById("infoTitle").textContent,
+ "Some title",
+ "Title should be correct."
+ );
+ ok(
+ !dialogWin.document.getElementById("infoTitle").hidden,
+ "Title should be shown."
+ );
+ is(
+ dialogWin.document.getElementById("infoBody").textContent,
+ "some message",
+ "Body text should be correct."
+ );
+
+ // Check circumstances of opening.
+ ok(
+ dialogWin?.docShell?.chromeEventHandler,
+ "Should have embedded the dialog."
+ );
+ for (let menu of document.querySelectorAll("menubar > menu")) {
+ ok(menu.disabled, `Menu ${menu.id} should be disabled.`);
+ }
+
+ let container = dialogWin.docShell.chromeEventHandler.closest("dialog");
+ let closedPromise = BrowserTestUtils.waitForMutationCondition(
+ container,
+ { childList: true, attributes: true },
+ () => !container.hasChildNodes() && !container.open
+ );
+
+ EventUtils.sendKey("ESCAPE");
+ await closedPromise;
+
+ await BrowserTestUtils.waitForMutationCondition(
+ document.querySelector("menubar > menu"),
+ { attributes: true },
+ () => !document.querySelector("menubar > menu").disabled
+ );
+
+ // Check we cleaned up:
+ for (let menu of document.querySelectorAll("menubar > menu")) {
+ ok(!menu.disabled, `Menu ${menu.id} should not be disabled anymore.`);
+ }
+});
+
+/**
+ * Check that the dialog's own closing methods being invoked don't break things.
+ */
+add_task(async function test_check_window_modal_prompt_service() {
+ await SpecialPowers.pushPrefEnv({
+ set: [["prompts.windowPromptSubDialog", true]],
+ });
+ let dialogPromise = BrowserTestUtils.promiseAlertDialogOpen();
+ // Avoid blocking the test on the (sync) alert by sticking it in a timeout:
+ setTimeout(
+ () => Services.prompt.alert(window, "Some title", "some message"),
+ 0
+ );
+ let dialogWin = await dialogPromise;
+
+ // Check circumstances of opening.
+ ok(
+ dialogWin?.docShell?.chromeEventHandler,
+ "Should have embedded the dialog."
+ );
+
+ let container = dialogWin.docShell.chromeEventHandler.closest("dialog");
+ let closedPromise = BrowserTestUtils.waitForMutationCondition(
+ container,
+ { childList: true, attributes: true },
+ () => !container.hasChildNodes() && !container.open
+ );
+
+ // This can also be invoked by the user if the escape key is handled
+ // outside of our embedded dialog.
+ container.close();
+ await closedPromise;
+
+ // Check we cleaned up:
+ for (let menu of document.querySelectorAll("menubar > menu")) {
+ ok(!menu.disabled, `Menu ${menu.id} should not be disabled anymore.`);
+ }
+});
+
+add_task(async function test_check_multiple_prompts() {
+ await SpecialPowers.pushPrefEnv({
+ set: [["prompts.windowPromptSubDialog", true]],
+ });
+ let container = document.getElementById("window-modal-dialog");
+ let dialogPromise = BrowserTestUtils.promiseAlertDialogOpen();
+
+ let firstDialogClosedPromise = new Promise(resolve => {
+ // Avoid blocking the test on the (sync) alert by sticking it in a timeout:
+ setTimeout(() => {
+ Services.prompt.alert(window, "Some title", "some message");
+ resolve();
+ }, 0);
+ });
+ let dialogWin = await dialogPromise;
+
+ // Check circumstances of opening.
+ ok(
+ dialogWin?.docShell?.chromeEventHandler,
+ "Should have embedded the dialog."
+ );
+ is(container.childElementCount, 1, "Should only have 1 dialog in the DOM.");
+
+ let secondDialogClosedPromise = new Promise(resolve => {
+ // Avoid blocking the test on the (sync) alert by sticking it in a timeout:
+ setTimeout(() => {
+ Services.prompt.alert(window, "Another title", "another message");
+ resolve();
+ }, 0);
+ });
+
+ dialogPromise = BrowserTestUtils.promiseAlertDialogOpen();
+
+ info("Accepting dialog");
+ dialogWin.document.querySelector("dialog").acceptDialog();
+
+ let oldWin = dialogWin;
+
+ info("Second dialog should automatically come up.");
+ dialogWin = await dialogPromise;
+
+ isnot(oldWin, dialogWin, "Opened a new dialog.");
+ ok(container.open, "Dialog should be open.");
+
+ info("Now close the second dialog.");
+ dialogWin.document.querySelector("dialog").acceptDialog();
+
+ await firstDialogClosedPromise;
+ await secondDialogClosedPromise;
+
+ await BrowserTestUtils.waitForMutationCondition(
+ container,
+ { childList: true, attributes: true },
+ () => !container.hasChildNodes() && !container.open
+ );
+ // Check we cleaned up:
+ for (let menu of document.querySelectorAll("menubar > menu")) {
+ ok(!menu.disabled, `Menu ${menu.id} should not be disabled anymore.`);
+ }
+});
+
+/**
+ * Check that the in-window modal dialogs un-minimizes windows when necessary.
+ */
+add_task(async function test_check_minimize_response() {
+ // Window minimization doesn't necessarily work on Linux...
+ if (AppConstants.platform == "linux") {
+ return;
+ }
+ await SpecialPowers.pushPrefEnv({
+ set: [["prompts.windowPromptSubDialog", true]],
+ });
+
+ window.minimize();
+ is(window.windowState, window.STATE_MINIMIZED, "Should be minimized.");
+ let dialogPromise = BrowserTestUtils.promiseAlertDialogOpen();
+ // Use an async alert to avoid blocking.
+ Services.prompt.asyncAlert(
+ window.browsingContext,
+ Ci.nsIPrompt.MODAL_TYPE_INTERNAL_WINDOW,
+ "Some title",
+ "some message"
+ );
+ let dialogWin = await dialogPromise;
+
+ isnot(
+ window.windowState,
+ window.STATE_MINIMIZED,
+ "Should no longer be minimized."
+ );
+
+ // Check dialog content:
+ is(
+ dialogWin.document.getElementById("infoTitle").textContent,
+ "Some title",
+ "Title should be correct."
+ );
+
+ let container = dialogWin.docShell.chromeEventHandler.closest("dialog");
+ let closedPromise = BrowserTestUtils.waitForMutationCondition(
+ container,
+ { childList: true, attributes: true },
+ () => !container.hasChildNodes() && !container.open
+ );
+
+ EventUtils.sendKey("ESCAPE");
+ await closedPromise;
+
+ await BrowserTestUtils.waitForMutationCondition(
+ document.querySelector("menubar > menu"),
+ { attributes: true },
+ () => !document.querySelector("menubar > menu").disabled
+ );
+});
+
+/**
+ * Tests that we get a closed callback even when closing the prompt before the
+ * underlying SubDialog has fully opened.
+ */
+add_task(async function test_closed_callback() {
+ await SpecialPowers.pushPrefEnv({
+ set: [["prompts.windowPromptSubDialog", true]],
+ });
+
+ let promptClosedPromise = Services.prompt.asyncAlert(
+ window.browsingContext,
+ Services.prompt.MODAL_TYPE_INTERNAL_WINDOW,
+ "Hello",
+ "Hello, World!"
+ );
+
+ let dialog = gDialogBox._dialog;
+ ok(dialog, "gDialogBox should have a dialog");
+
+ // Directly close the dialog without waiting for it to initialize.
+ dialog.close();
+
+ info("Waiting for prompt close");
+ await promptClosedPromise;
+
+ ok(!gDialogBox._dialog, "gDialogBox should no longer have a dialog");
+});