browser_continue_button_delay.js (3863B)
1 "use strict"; 2 3 // This test ensures the security delay (security.dialog_enable_delay) gets 4 // properly applied to the "Continue" button on the HTTPS-Only error page. It 5 // consists of the following checks: 6 // 1. Check that the button gets enabled at the right time after a new tab is 7 // loaded 8 // 2. Check that the button gets disabled and re-enabled with the correct 9 // timings on a focus loss due to a new tab being opened. 10 // 3. Check that the button gets enabled with the correct timings when the 11 // HTTPS-Only error page is loaded through the identity pane. 12 13 // We specifically want a insecure url here that will fail to upgrade 14 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 15 const TEST_URL = "http://untrusted.example.com"; 16 const TEST_PRINCIPAL = 17 Services.scriptSecurityManager.createContentPrincipalFromOrigin(TEST_URL); 18 19 function waitForEnabledButton() { 20 return new Promise(resolve => { 21 const button = content.document.getElementById("openInsecure"); 22 const observer = new content.MutationObserver(mutations => { 23 for (const mutation of mutations) { 24 if ( 25 mutation.type === "attributes" && 26 mutation.attributeName === "class" && 27 !mutation.target.classList.contains("disabled") 28 ) { 29 resolve(); 30 } 31 } 32 }); 33 observer.observe(button, { attributeFilter: ["class"] }); 34 ok( 35 button.classList.contains("disabled"), 36 "The 'Continue to HTTP Site' button should be disabled right after the error page is loaded/focused." 37 ); 38 }); 39 } 40 41 const specifiedDelay = Services.prefs.getIntPref( 42 "security.dialog_enable_delay", 43 1000 44 ); 45 46 async function waitForEnabledButtonAndCheckTiming() { 47 const startTime = Date.now(); 48 await SpecialPowers.spawn(gBrowser.selectedBrowser, [], waitForEnabledButton); 49 const endTime = Date.now(); 50 51 const observedDelay = endTime - startTime; 52 53 Assert.greater( 54 observedDelay, 55 specifiedDelay - 100, 56 `The observed delay (${observedDelay}ms) should be roughly the same or greater than the delay specified in "security.dialog_enable_delay" (${specifiedDelay}ms)` 57 ); 58 } 59 60 add_setup(async function () { 61 await SpecialPowers.pushPrefEnv({ 62 set: [["browser.urlbar.trustPanel.featureGate", false]], 63 }); 64 }); 65 66 add_task(async function () { 67 await SpecialPowers.pushPrefEnv({ 68 set: [["dom.security.https_only_mode", true]], 69 }); 70 71 info("Loading insecure page"); 72 let loaded = BrowserTestUtils.waitForErrorPage(gBrowser.selectedBrowser); 73 BrowserTestUtils.startLoadingURIString(gBrowser, TEST_URL); 74 await loaded; 75 await waitForEnabledButtonAndCheckTiming(); 76 77 info("Opening and closing a new tab"); 78 let newTab = await BrowserTestUtils.openNewForegroundTab({ 79 gBrowser, 80 }); 81 await BrowserTestUtils.removeTab(newTab); 82 await waitForEnabledButtonAndCheckTiming(); 83 84 info("Loading page with exception"); 85 await Services.perms.addFromPrincipal( 86 TEST_PRINCIPAL, 87 "https-only-load-insecure", 88 Ci.nsIHttpsOnlyModePermission.LOAD_INSECURE_ALLOW_SESSION 89 ); 90 loaded = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); 91 BrowserTestUtils.startLoadingURIString(gBrowser, TEST_URL); 92 await loaded; 93 94 info("Opening identity pane"); 95 document.getElementById("identity-icon-box").click(); 96 const identityPopup = document.getElementById("identity-popup"); 97 ok(!!identityPopup, "Identity pane should exist"); 98 await BrowserTestUtils.waitForPopupEvent(identityPopup, "shown"); 99 100 info("Removing exception in identity pane"); 101 const menulist = document.getElementById( 102 "identity-popup-security-httpsonlymode-menulist" 103 ); 104 ok(!!menulist, "Identity pane should contain HTTPS-Only menulist"); 105 loaded = BrowserTestUtils.waitForErrorPage(gBrowser.selectedBrowser); 106 menulist.getItemAtIndex(0).doCommand(); 107 await loaded; 108 await waitForEnabledButtonAndCheckTiming(); 109 });