browser_beforeunload_permit_http.js (7857B)
1 "use strict"; 2 3 const { PromptTestUtils } = ChromeUtils.importESModule( 4 "resource://testing-common/PromptTestUtils.sys.mjs" 5 ); 6 7 const TEST_PATH_HTTP = getRootDirectory(gTestPath).replace( 8 "chrome://mochitests/content", 9 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 10 "http://nocert.example.com/" 11 ); 12 /* 13 * Description of Tests: 14 * 15 * Test load page and reload: 16 * 1. Enable HTTPS-First and the pref to trigger beforeunload by user interaction 17 * 2. Open an HTTP site. HTTPS-First will try to upgrade it to https - but since it has no cert that try will fail 18 * 3. Then simulated user interaction and reload the page with a reload flag. 19 * 4. That should lead to a beforeUnload prompt that asks for users permission to perform reload. HTTPS-First should not try to upgrade the reload again 20 * 21 * Test Navigation: 22 * 1. Enable HTTPS-First and the pref to trigger beforeunload by user interaction 23 * 2. Open an http site. HTTPS-First will try to upgrade it to https - but since it has no cert for https that try will fail 24 * 3. Then simulated user interaction and navigate to another http page. Again HTTPS-First will try to upgrade to HTTPS 25 * 4. This attempted navigation leads to a prompt which askes for permission to leave page - accept it 26 * 5. Since the site is not using a valid HTTPS cert HTTPS-First will downgrade the request back to HTTP 27 * 6. User should NOT get asked again for permission to unload 28 * 29 * Test Session History Navigation: 30 * 1. Enable HTTPS-First and the pref to trigger beforeunload by user interaction 31 * 2. Open an http site. HTTPS-First will try to upgrade it to https - but since it has no cert for https that try will fail 32 * 3. Then navigate to another http page and simulated a user interaction. 33 * 4. Trigger a session history navigation by clicking the "back button". 34 * 5. This attempted navigation leads to a prompt which askes for permission to leave page - accept it 35 */ 36 add_setup(async function () { 37 await SpecialPowers.pushPrefEnv({ 38 set: [ 39 ["test.wait300msAfterTabSwitch", true], 40 ["dom.security.https_first", true], 41 ["dom.require_user_interaction_for_beforeunload", true], 42 ], 43 }); 44 }); 45 const TESTS = [ 46 { 47 name: "Normal Reload (No flag)", 48 reloadFlag: Ci.nsIWebNavigation.LOAD_FLAGS_NONE, 49 }, 50 { 51 name: "Bypass Cache Reload", 52 reloadFlag: Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE, 53 }, 54 { 55 name: "Bypass Proxy Reload", 56 reloadFlag: Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_PROXY, 57 }, 58 { 59 name: "Bypass Cache and Proxy Reload", 60 reloadFlag: 61 Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE | 62 Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_PROXY, 63 }, 64 ]; 65 66 add_task(async function testReloadFlags() { 67 for (let index = 0; index < TESTS.length; index++) { 68 const testCase = TESTS[index]; 69 // The onbeforeunload dialog should appear 70 let dialogPromise = PromptTestUtils.waitForPrompt(null, { 71 modalType: Services.prompt.MODAL_TYPE_CONTENT, 72 promptType: "confirmEx", 73 }); 74 let reloadPromise = loadPageAndReload(testCase); 75 let dialog = await dialogPromise; 76 Assert.ok(true, "Showed the beforeunload dialog."); 77 await PromptTestUtils.handlePrompt(dialog, { buttonNumClick: 0 }); 78 await reloadPromise; 79 } 80 }); 81 82 add_task(async function testNavigation() { 83 // The onbeforeunload dialog should appear 84 let dialogPromise = PromptTestUtils.waitForPrompt(null, { 85 modalType: Services.prompt.MODAL_TYPE_CONTENT, 86 promptType: "confirmEx", 87 }); 88 89 let openPagePromise = openPage(); 90 let dialog = await dialogPromise; 91 Assert.ok(true, "Showed the beforeunload dialog."); 92 await PromptTestUtils.handlePrompt(dialog, { buttonNumClick: 0 }); 93 await openPagePromise; 94 }); 95 96 add_task(async function testSessionHistoryNavigation() { 97 // The onbeforeunload dialog should appear 98 let dialogPromise = PromptTestUtils.waitForPrompt(null, { 99 modalType: Services.prompt.MODAL_TYPE_CONTENT, 100 promptType: "confirmEx", 101 }); 102 103 let openPagePromise = loadPagesAndUseBackButton(); 104 let dialog = await dialogPromise; 105 Assert.ok(true, "Showed the beforeunload dialog."); 106 await PromptTestUtils.handlePrompt(dialog, { buttonNumClick: 0 }); 107 await openPagePromise; 108 }); 109 110 async function openPage() { 111 // Open about:blank in a new tab 112 await BrowserTestUtils.withNewTab( 113 { gBrowser, url: "about:blank" }, 114 async function (browser) { 115 // Load http page 116 BrowserTestUtils.startLoadingURIString( 117 browser, 118 `${TEST_PATH_HTTP}file_beforeunload_permit_http.html` 119 ); 120 await BrowserTestUtils.browserLoaded(browser); 121 // Interact with page such that unload permit will be necessary 122 await BrowserTestUtils.synthesizeMouse("body", 2, 2, {}, browser); 123 let hasInteractedWith = await SpecialPowers.spawn( 124 browser, 125 [""], 126 function () { 127 return content.document.hasBeenUserGestureActivated; 128 } 129 ); 130 131 is(true, hasInteractedWith, "Simulated successfully user interaction"); 132 // And then navigate away to another site which proves that user won't be asked twice to permit a reload (otherwise the test get timed out) 133 BrowserTestUtils.startLoadingURIString( 134 browser, 135 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 136 "http://self-signed.example.com/" 137 ); 138 await BrowserTestUtils.browserLoaded(browser); 139 Assert.ok(true, "Navigated successfully."); 140 } 141 ); 142 } 143 144 async function loadPageAndReload(testCase) { 145 // Load initial site 146 // Open about:blank in a new tab 147 await BrowserTestUtils.withNewTab( 148 { gBrowser, url: "about:blank" }, 149 async function (browser) { 150 BrowserTestUtils.startLoadingURIString( 151 browser, 152 `${TEST_PATH_HTTP}file_beforeunload_permit_http.html` 153 ); 154 await BrowserTestUtils.browserLoaded(browser); 155 // Interact with page such that unload permit will be necessary 156 await BrowserTestUtils.synthesizeMouse("body", 2, 2, {}, browser); 157 158 let hasInteractedWith = await SpecialPowers.spawn( 159 browser, 160 [""], 161 function () { 162 return content.document.hasBeenUserGestureActivated; 163 } 164 ); 165 is(true, hasInteractedWith, "Simulated successfully user interaction"); 166 BrowserCommands.reloadWithFlags(testCase.reloadFlag); 167 await BrowserTestUtils.browserLoaded(browser); 168 is(true, true, `reload with flag ${testCase.name} was successful`); 169 } 170 ); 171 } 172 173 async function loadPagesAndUseBackButton() { 174 // Load initial site 175 // Open about:blank in a new tab 176 await BrowserTestUtils.withNewTab( 177 { gBrowser, url: "about:blank" }, 178 async function (browser) { 179 BrowserTestUtils.startLoadingURIString( 180 browser, 181 `${TEST_PATH_HTTP}file_beforeunload_permit_http.html` 182 ); 183 await BrowserTestUtils.browserLoaded(browser); 184 185 BrowserTestUtils.startLoadingURIString( 186 browser, 187 `${TEST_PATH_HTTP}file_beforeunload_permit_http.html?getASessionHistoryEntry` 188 ); 189 await BrowserTestUtils.browserLoaded(browser); 190 // Interact with page such that unload permit will be necessary 191 await BrowserTestUtils.synthesizeMouse("body", 2, 2, {}, browser); 192 193 let hasInteractedWith = await SpecialPowers.spawn( 194 browser, 195 [""], 196 function () { 197 return content.document.hasBeenUserGestureActivated; 198 } 199 ); 200 is(true, hasInteractedWith, "Simulated successfully user interaction"); 201 // Go back one site by clicking the back button 202 info("Clicking back button"); 203 let backButton = document.getElementById("back-button"); 204 backButton.click(); 205 await BrowserTestUtils.waitForLocationChange( 206 gBrowser, 207 `${TEST_PATH_HTTP}file_beforeunload_permit_http.html` 208 ); 209 is(true, true, `Got back successful`); 210 } 211 ); 212 }