browser_beforeunload_between_chrome_content.js (4865B)
1 const TEST_URL = "http://www.example.com/browser/dom/tests/browser/dummy.html"; 2 3 const { PromptTestUtils } = ChromeUtils.importESModule( 4 "resource://testing-common/PromptTestUtils.sys.mjs" 5 ); 6 7 function pageScript() { 8 window.addEventListener( 9 "beforeunload", 10 function (event) { 11 var str = "Leaving?"; 12 event.returnValue = str; 13 return str; 14 }, 15 true 16 ); 17 } 18 19 function injectBeforeUnload(browser) { 20 return ContentTask.spawn(browser, null, async function () { 21 content.window.addEventListener( 22 "beforeunload", 23 function (event) { 24 sendAsyncMessage("Test:OnBeforeUnloadReceived"); 25 var str = "Leaving?"; 26 event.returnValue = str; 27 return str; 28 }, 29 true 30 ); 31 }); 32 } 33 34 // Wait for onbeforeunload dialog, and dismiss it immediately. 35 function awaitAndCloseBeforeUnloadDialog(browser, doStayOnPage) { 36 return PromptTestUtils.handleNextPrompt( 37 browser, 38 { modalType: Services.prompt.MODAL_TYPE_CONTENT, promptType: "confirmEx" }, 39 { buttonNumClick: doStayOnPage ? 1 : 0 } 40 ); 41 } 42 43 SpecialPowers.pushPrefEnv({ 44 set: [["dom.require_user_interaction_for_beforeunload", false]], 45 }); 46 47 /** 48 * Test navigation from a content page to a chrome page. Also check that only 49 * one beforeunload event is fired. 50 */ 51 /* global messageManager */ 52 add_task(async function () { 53 let beforeUnloadCount = 0; 54 messageManager.addMessageListener("Test:OnBeforeUnloadReceived", function () { 55 beforeUnloadCount++; 56 }); 57 58 // Open a content page. 59 let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL); 60 let browser = tab.linkedBrowser; 61 62 ok(browser.isRemoteBrowser, "Browser should be remote."); 63 64 await injectBeforeUnload(browser); 65 // Navigate to a chrome page. 66 let dialogShown1 = awaitAndCloseBeforeUnloadDialog(browser, false); 67 BrowserTestUtils.startLoadingURIString(browser, "about:support"); 68 await Promise.all([dialogShown1, BrowserTestUtils.browserLoaded(browser)]); 69 70 is(beforeUnloadCount, 1, "Should have received one beforeunload event."); 71 ok(!browser.isRemoteBrowser, "Browser should not be remote."); 72 73 // Go back to content page. 74 ok(gBrowser.webNavigation.canGoBack, "Should be able to go back."); 75 gBrowser.goBack(); 76 await BrowserTestUtils.browserLoaded(browser); 77 await injectBeforeUnload(browser); 78 79 // Test that going forward triggers beforeunload prompt as well. 80 ok(gBrowser.webNavigation.canGoForward, "Should be able to go forward."); 81 let dialogShown2 = awaitAndCloseBeforeUnloadDialog(false); 82 gBrowser.goForward(); 83 await Promise.all([dialogShown2, BrowserTestUtils.browserLoaded(browser)]); 84 is(beforeUnloadCount, 2, "Should have received two beforeunload events."); 85 86 BrowserTestUtils.removeTab(tab); 87 }); 88 89 /** 90 * Test navigation from a chrome page to a content page. Also check that only 91 * one beforeunload event is fired. 92 */ 93 add_task(async function () { 94 let beforeUnloadCount = 0; 95 messageManager.addMessageListener("Test:OnBeforeUnloadReceived", function () { 96 beforeUnloadCount++; 97 }); 98 99 // Open a chrome page. 100 let tab = await BrowserTestUtils.openNewForegroundTab( 101 gBrowser, 102 "about:support" 103 ); 104 let browser = tab.linkedBrowser; 105 106 ok(!browser.isRemoteBrowser, "Browser should not be remote."); 107 await ContentTask.spawn(browser, null, async function () { 108 content.window.addEventListener( 109 "beforeunload", 110 function (event) { 111 sendAsyncMessage("Test:OnBeforeUnloadReceived"); 112 var str = "Leaving?"; 113 event.returnValue = str; 114 return str; 115 }, 116 true 117 ); 118 }); 119 120 // Navigate to a content page. 121 let dialogShown1 = awaitAndCloseBeforeUnloadDialog(false); 122 BrowserTestUtils.startLoadingURIString(browser, TEST_URL); 123 await Promise.all([dialogShown1, BrowserTestUtils.browserLoaded(browser)]); 124 is(beforeUnloadCount, 1, "Should have received one beforeunload event."); 125 ok(browser.isRemoteBrowser, "Browser should be remote."); 126 127 // Go back to chrome page. 128 ok(gBrowser.webNavigation.canGoBack, "Should be able to go back."); 129 gBrowser.goBack(); 130 await BrowserTestUtils.browserLoaded(browser); 131 await ContentTask.spawn(browser, null, async function () { 132 content.window.addEventListener( 133 "beforeunload", 134 function (event) { 135 sendAsyncMessage("Test:OnBeforeUnloadReceived"); 136 var str = "Leaving?"; 137 event.returnValue = str; 138 return str; 139 }, 140 true 141 ); 142 }); 143 144 // Test that going forward triggers beforeunload prompt as well. 145 ok(gBrowser.webNavigation.canGoForward, "Should be able to go forward."); 146 let dialogShown2 = awaitAndCloseBeforeUnloadDialog(false); 147 gBrowser.goForward(); 148 await Promise.all([dialogShown2, BrowserTestUtils.browserLoaded(browser)]); 149 is(beforeUnloadCount, 2, "Should have received two beforeunload events."); 150 151 BrowserTestUtils.removeTab(tab); 152 });