browser_captivePortal_trr_mode3.js (6380B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 let gServer; 7 let gServerURL; 8 let gRedirectedURL; 9 let gExpectedText; 10 let gNavigated = false; 11 let gExpectedURL; 12 13 const { HttpServer } = ChromeUtils.importESModule( 14 "resource://testing-common/httpd.sys.mjs" 15 ); 16 17 const gOverride = Cc["@mozilla.org/network/native-dns-override;1"].getService( 18 Ci.nsINativeDNSResolverOverride 19 ); 20 21 let gCaptivePortalState = "captive-replace"; 22 23 add_setup(async function () { 24 gOverride.addIPOverride("test1.example.com", "127.0.0.1"); 25 gOverride.addIPOverride("example.net", "127.0.0.1"); 26 gServer = new HttpServer(); 27 gServer.start(-1); 28 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 29 gServerURL = `http://test1.example.com:${gServer.identity.primaryPort}/`; 30 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 31 gRedirectedURL = `http://example.net:${gServer.identity.primaryPort}/redir`; 32 gServer.identity.add( 33 "http", 34 "test1.example.com", 35 gServer.identity.primaryPort 36 ); 37 gServer.identity.add("http", "example.net", gServer.identity.primaryPort); 38 gServer.registerPathHandler("/", (request, response) => { 39 if (gCaptivePortalState == "captive-replace") { 40 response.setStatusLine(request.httpVersion, 200, "OK"); 41 response.setHeader("Content-Type", "text/html"); 42 const BODY = `captive muahahah`; 43 response.bodyOutputStream.write(BODY, BODY.length); 44 return; 45 } 46 47 if (gCaptivePortalState == "captive-redirect") { 48 response.setStatusLine(request.httpVersion, 302, "Moved Temporarily"); 49 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 50 response.setHeader("Location", gRedirectedURL); 51 response.write("redirecting"); 52 } 53 }); 54 gServer.registerPathHandler("/redir", (request, response) => { 55 response.setStatusLine(request.httpVersion, 200, "OK"); 56 response.setHeader("Content-Type", "text/html"); 57 const BODY = `redirected`; 58 response.bodyOutputStream.write(BODY, BODY.length); 59 }); 60 registerCleanupFunction(async () => { 61 await gServer.stop(); 62 gOverride.clearOverrides(); 63 }); 64 65 await SpecialPowers.pushPrefEnv({ 66 set: [ 67 ["test.wait300msAfterTabSwitch", true], 68 ["captivedetect.canonicalURL", gServerURL], 69 ["captivedetect.canonicalContent", "stuff"], 70 ["network.trr.mode", Ci.nsIDNSService.MODE_TRRONLY], 71 ["network.proxy.no_proxies_on", "test1.example.com,example.net"], 72 ], 73 }); 74 }); 75 76 async function openAndCheck() { 77 // Open a second window in the background. Later, we'll check that 78 // when we click the button to open the captive portal tab, the tab 79 // only opens in the active window and not in the background one. 80 let secondWindow = await openWindowAndWaitForFocus(); 81 await SimpleTest.promiseFocus(window); 82 83 await portalDetected(); 84 85 // Check that we didn't open anything in the background window. 86 ensureNoPortalTab(secondWindow); 87 88 let tab = await openCaptivePortalErrorTab(); 89 let browser = tab.linkedBrowser; 90 let portalTabPromise = BrowserTestUtils.waitForNewTab(gBrowser, gExpectedURL); 91 92 await SpecialPowers.spawn(browser, [], async () => { 93 let doc = content.document; 94 let loginButton = doc.getElementById("openPortalLoginPageButton"); 95 await ContentTaskUtils.waitForCondition( 96 () => ContentTaskUtils.isVisible(loginButton), 97 "Captive portal error page UI is visible" 98 ); 99 100 if (!Services.focus.focusedElement == loginButton) { 101 await ContentTaskUtils.waitForEvent(loginButton, "focus"); 102 } 103 104 Assert.ok(true, "openPortalLoginPageButton has focus"); 105 info("Clicking the Open Login Page button"); 106 await EventUtils.synthesizeMouseAtCenter(loginButton, {}, content); 107 }); 108 109 let portalTab = await portalTabPromise; 110 await SpecialPowers.spawn( 111 portalTab.linkedBrowser, 112 [gExpectedText], 113 async text => { 114 Assert.equal(content.document.body.innerText, text); 115 } 116 ); 117 118 is( 119 gBrowser.selectedTab, 120 portalTab, 121 "Login page should be open in a new foreground tab." 122 ); 123 124 // Check that we didn't open anything in the background window. 125 ensureNoPortalTab(secondWindow); 126 127 // Make sure clicking the "Open Login Page" button again focuses the existing portal tab. 128 await BrowserTestUtils.switchTab(gBrowser, tab); 129 // Passing an empty function to BrowserTestUtils.switchTab lets us wait for an arbitrary 130 // tab switch. 131 portalTabPromise = BrowserTestUtils.switchTab(gBrowser, () => {}); 132 await SpecialPowers.spawn(browser, [], async () => { 133 info("Clicking the Open Login Page button."); 134 let loginButton = content.document.getElementById( 135 "openPortalLoginPageButton" 136 ); 137 await EventUtils.synthesizeMouseAtCenter(loginButton, {}, content); 138 }); 139 140 info("Opening captive portal login page"); 141 let portalTab2 = await portalTabPromise; 142 is(portalTab2, portalTab, "The existing portal tab should be focused."); 143 144 // Check that we didn't open anything in the background window. 145 ensureNoPortalTab(secondWindow); 146 147 let portalTabClosing = BrowserTestUtils.waitForTabClosing(portalTab); 148 let errorTabReloaded = BrowserTestUtils.waitForErrorPage(browser); 149 150 Services.obs.notifyObservers(null, "captive-portal-login-success"); 151 info("closing page"); 152 if (gNavigated) { 153 // Since it navigated, the tab won't be automatically closed. 154 await BrowserTestUtils.removeTab(portalTab); 155 } 156 157 await portalTabClosing; 158 159 info( 160 "Waiting for error tab to be reloaded after the captive portal was freed." 161 ); 162 await errorTabReloaded; 163 await SpecialPowers.spawn(browser, [], () => { 164 let doc = content.document; 165 ok( 166 !doc.body.classList.contains("captiveportal"), 167 "Captive portal error page UI is not visible." 168 ); 169 }); 170 171 await BrowserTestUtils.removeTab(tab); 172 await BrowserTestUtils.closeWindow(secondWindow); 173 } 174 175 add_task(async function checkNoTRRForTab() { 176 info("Check that the captive portal login tab does not use TRR"); 177 gExpectedText = `captive muahahah`; 178 gExpectedURL = gServerURL; 179 180 await openAndCheck(); 181 }); 182 183 add_task(async function checkNoTRRForTabWithRedirect() { 184 gCaptivePortalState = "captive-redirect"; 185 gExpectedText = "redirected"; 186 gExpectedURL = gRedirectedURL; 187 gNavigated = true; 188 info("Check that the captive portal login tab does not use TRR"); 189 190 await openAndCheck(); 191 });