browser_windowPrompt.js (7222B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 /** 7 * Check that the in-window modal dialogs work correctly. 8 */ 9 add_task(async function test_check_window_modal_prompt_service() { 10 let dialogPromise = BrowserTestUtils.promiseAlertDialogOpen(); 11 // Avoid blocking the test on the (sync) alert by sticking it in a timeout: 12 setTimeout( 13 () => Services.prompt.alert(window, "Some title", "some message"), 14 0 15 ); 16 let dialogWin = await dialogPromise; 17 18 // Check dialog content: 19 is( 20 dialogWin.document.getElementById("infoTitle").textContent, 21 "Some title", 22 "Title should be correct." 23 ); 24 ok( 25 !dialogWin.document.getElementById("infoTitle").hidden, 26 "Title should be shown." 27 ); 28 is( 29 dialogWin.document.getElementById("infoBody").textContent, 30 "some message", 31 "Body text should be correct." 32 ); 33 34 // Check circumstances of opening. 35 ok( 36 dialogWin?.docShell?.chromeEventHandler, 37 "Should have embedded the dialog." 38 ); 39 for (let menu of document.querySelectorAll("menubar > menu")) { 40 ok(menu.disabled, `Menu ${menu.id} should be disabled.`); 41 } 42 43 let container = dialogWin.docShell.chromeEventHandler.closest("dialog"); 44 let closedPromise = BrowserTestUtils.waitForMutationCondition( 45 container, 46 { childList: true, attributes: true }, 47 () => !container.hasChildNodes() && !container.open 48 ); 49 50 EventUtils.sendKey("ESCAPE"); 51 await closedPromise; 52 53 await BrowserTestUtils.waitForMutationCondition( 54 document.querySelector("menubar > menu"), 55 { attributes: true }, 56 () => !document.querySelector("menubar > menu").disabled 57 ); 58 59 // Check we cleaned up: 60 for (let menu of document.querySelectorAll("menubar > menu")) { 61 ok(!menu.disabled, `Menu ${menu.id} should not be disabled anymore.`); 62 } 63 }); 64 65 /** 66 * Check that the dialog's own closing methods being invoked don't break things. 67 */ 68 add_task(async function test_check_window_modal_prompt_service() { 69 let dialogPromise = BrowserTestUtils.promiseAlertDialogOpen(); 70 // Avoid blocking the test on the (sync) alert by sticking it in a timeout: 71 setTimeout( 72 () => Services.prompt.alert(window, "Some title", "some message"), 73 0 74 ); 75 let dialogWin = await dialogPromise; 76 77 // Check circumstances of opening. 78 ok( 79 dialogWin?.docShell?.chromeEventHandler, 80 "Should have embedded the dialog." 81 ); 82 83 let container = dialogWin.docShell.chromeEventHandler.closest("dialog"); 84 let closedPromise = BrowserTestUtils.waitForMutationCondition( 85 container, 86 { childList: true, attributes: true }, 87 () => !container.hasChildNodes() && !container.open 88 ); 89 90 // This can also be invoked by the user if the escape key is handled 91 // outside of our embedded dialog. 92 container.close(); 93 await closedPromise; 94 95 // Check we cleaned up: 96 for (let menu of document.querySelectorAll("menubar > menu")) { 97 ok(!menu.disabled, `Menu ${menu.id} should not be disabled anymore.`); 98 } 99 }); 100 101 add_task(async function test_check_multiple_prompts() { 102 let container = document.getElementById("window-modal-dialog"); 103 let dialogPromise = BrowserTestUtils.promiseAlertDialogOpen(); 104 105 let firstDialogClosedPromise = new Promise(resolve => { 106 // Avoid blocking the test on the (sync) alert by sticking it in a timeout: 107 setTimeout(() => { 108 Services.prompt.alert(window, "Some title", "some message"); 109 resolve(); 110 }, 0); 111 }); 112 let dialogWin = await dialogPromise; 113 114 // Check circumstances of opening. 115 ok( 116 dialogWin?.docShell?.chromeEventHandler, 117 "Should have embedded the dialog." 118 ); 119 is(container.childElementCount, 1, "Should only have 1 dialog in the DOM."); 120 121 let secondDialogClosedPromise = new Promise(resolve => { 122 // Avoid blocking the test on the (sync) alert by sticking it in a timeout: 123 setTimeout(() => { 124 Services.prompt.alert(window, "Another title", "another message"); 125 resolve(); 126 }, 0); 127 }); 128 129 dialogPromise = BrowserTestUtils.promiseAlertDialogOpen(); 130 131 info("Accepting dialog"); 132 dialogWin.document.querySelector("dialog").acceptDialog(); 133 134 let oldWin = dialogWin; 135 136 info("Second dialog should automatically come up."); 137 dialogWin = await dialogPromise; 138 139 isnot(oldWin, dialogWin, "Opened a new dialog."); 140 ok(container.open, "Dialog should be open."); 141 142 info("Now close the second dialog."); 143 dialogWin.document.querySelector("dialog").acceptDialog(); 144 145 await firstDialogClosedPromise; 146 await secondDialogClosedPromise; 147 148 await BrowserTestUtils.waitForMutationCondition( 149 container, 150 { childList: true, attributes: true }, 151 () => !container.hasChildNodes() && !container.open 152 ); 153 // Check we cleaned up: 154 for (let menu of document.querySelectorAll("menubar > menu")) { 155 ok(!menu.disabled, `Menu ${menu.id} should not be disabled anymore.`); 156 } 157 }); 158 159 /** 160 * Check that the in-window modal dialogs un-minimizes windows when necessary. 161 */ 162 add_task(async function test_check_minimize_response() { 163 // Window minimization doesn't necessarily work on Linux... 164 if (AppConstants.platform == "linux") { 165 return; 166 } 167 168 let promiseSizeModeChange = BrowserTestUtils.waitForEvent( 169 window, 170 "sizemodechange" 171 ); 172 window.minimize(); 173 await promiseSizeModeChange; 174 is(window.windowState, window.STATE_MINIMIZED, "Should be minimized."); 175 176 promiseSizeModeChange = BrowserTestUtils.waitForEvent( 177 window, 178 "sizemodechange" 179 ); 180 let dialogPromise = BrowserTestUtils.promiseAlertDialogOpen(); 181 // Use an async alert to avoid blocking. 182 Services.prompt.asyncAlert( 183 window.browsingContext, 184 Ci.nsIPrompt.MODAL_TYPE_INTERNAL_WINDOW, 185 "Some title", 186 "some message" 187 ); 188 let dialogWin = await dialogPromise; 189 await promiseSizeModeChange; 190 191 isnot( 192 window.windowState, 193 window.STATE_MINIMIZED, 194 "Should no longer be minimized." 195 ); 196 197 // Check dialog content: 198 is( 199 dialogWin.document.getElementById("infoTitle").textContent, 200 "Some title", 201 "Title should be correct." 202 ); 203 204 let container = dialogWin.docShell.chromeEventHandler.closest("dialog"); 205 let closedPromise = BrowserTestUtils.waitForMutationCondition( 206 container, 207 { childList: true, attributes: true }, 208 () => !container.hasChildNodes() && !container.open 209 ); 210 211 EventUtils.sendKey("ESCAPE"); 212 await closedPromise; 213 214 await BrowserTestUtils.waitForMutationCondition( 215 document.querySelector("menubar > menu"), 216 { attributes: true }, 217 () => !document.querySelector("menubar > menu").disabled 218 ); 219 }); 220 221 /** 222 * Tests that we get a closed callback even when closing the prompt before the 223 * underlying SubDialog has fully opened. 224 */ 225 add_task(async function test_closed_callback() { 226 let promptClosedPromise = Services.prompt.asyncAlert( 227 window.browsingContext, 228 Services.prompt.MODAL_TYPE_INTERNAL_WINDOW, 229 "Hello", 230 "Hello, World!" 231 ); 232 233 let dialog = gDialogBox._dialog; 234 ok(dialog, "gDialogBox should have a dialog"); 235 236 // Directly close the dialog without waiting for it to initialize. 237 dialog.close(); 238 239 info("Waiting for prompt close"); 240 await promptClosedPromise; 241 242 ok(!gDialogBox._dialog, "gDialogBox should no longer have a dialog"); 243 });