browser_onbeforeunload_only_after_interaction_in_frame.js (2761B)
1 const { PromptTestUtils } = ChromeUtils.importESModule( 2 "resource://testing-common/PromptTestUtils.sys.mjs" 3 ); 4 5 function pageScript() { 6 window.addEventListener( 7 "beforeunload", 8 function (event) { 9 var str = "Some text that causes the beforeunload dialog to be shown"; 10 event.returnValue = str; 11 return str; 12 }, 13 true 14 ); 15 } 16 17 SpecialPowers.pushPrefEnv({ 18 set: [ 19 ["dom.require_user_interaction_for_beforeunload", true], 20 ["security.allow_eval_with_system_principal", true], 21 ], 22 }); 23 24 const FRAME_URL = 25 "data:text/html," + encodeURIComponent("<body>Just a frame</body>"); 26 27 const PAGE_URL = 28 "data:text/html," + 29 encodeURIComponent( 30 "<iframe src='" + 31 FRAME_URL + 32 "'></iframe><script>(" + 33 pageScript.toSource() + 34 ")();</script>" 35 ); 36 37 add_setup(async function () { 38 await SpecialPowers.pushPrefEnv({ 39 set: [["test.wait300msAfterTabSwitch", true]], 40 }); 41 }); 42 43 add_task(async function doClick() { 44 // The onbeforeunload dialog should appear. 45 let dialogPromise = PromptTestUtils.waitForPrompt(null, { 46 modalType: Services.prompt.MODAL_TYPE_CONTENT, 47 promptType: "confirmEx", 48 }); 49 50 let openPagePromise = openPage(true); 51 let dialog = await dialogPromise; 52 Assert.ok(true, "Showed the beforeunload dialog."); 53 54 await PromptTestUtils.handlePrompt(dialog, { buttonNumClick: 0 }); 55 await openPagePromise; 56 }); 57 58 add_task(async function noClick() { 59 // The onbeforeunload dialog should NOT appear. 60 await openPage(false); 61 info("If we time out here, then the dialog was shown..."); 62 }); 63 64 async function openPage(shouldClick) { 65 // Open about:blank in a new tab. 66 await BrowserTestUtils.withNewTab( 67 { gBrowser, url: "about:blank" }, 68 async function (browser) { 69 // Load the page. 70 BrowserTestUtils.startLoadingURIString(browser, PAGE_URL); 71 await BrowserTestUtils.browserLoaded(browser); 72 73 let frameBC = browser.browsingContext.children[0]; 74 if (shouldClick) { 75 await BrowserTestUtils.synthesizeMouse("body", 2, 2, {}, frameBC); 76 } 77 let hasInteractedWith = await SpecialPowers.spawn( 78 frameBC, 79 [], 80 function () { 81 return [ 82 content.document.hasBeenUserGestureActivated, 83 content.document.hasBeenUserGestureActivated, 84 ]; 85 } 86 ); 87 is( 88 shouldClick, 89 hasInteractedWith[0], 90 "Click should update parent interactivity state" 91 ); 92 is( 93 shouldClick, 94 hasInteractedWith[1], 95 "Click should update frame interactivity state" 96 ); 97 // And then navigate away. 98 BrowserTestUtils.startLoadingURIString(browser, "http://example.com/"); 99 await BrowserTestUtils.browserLoaded(browser); 100 } 101 ); 102 }