/* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js"); const LOGIN_LINK = `login`; const LOGIN_URL = "http://localhost:8080/login"; const CANONICAL_SUCCESS_URL = "http://localhost:8080/success"; const CPS = Cc["@mozilla.org/network/captive-portal-service;1"].getService( Ci.nsICaptivePortalService ); let server; let loginPageShown = false; function redirectHandler(request, response) { if (loginPageShown) { return; } response.setStatusLine(request.httpVersion, 302, "captive"); response.setHeader("Content-Type", "text/html"); response.setHeader("Location", LOGIN_URL); } function loginHandler(request, response) { response.setHeader("Content-Type", "text/html"); response.bodyOutputStream.write(LOGIN_LINK, LOGIN_LINK.length); loginPageShown = true; } function unlockHandler(request, response) { response.setStatusLine(request.httpVersion, 302, "login complete"); response.setHeader("Content-Type", "text/html"); response.setHeader("Location", CANONICAL_SUCCESS_URL); } add_setup(async function() { // Set up a mock server for handling captive portal redirect. server = new HttpServer(); server.registerPathHandler("/success", redirectHandler); server.registerPathHandler("/login", loginHandler); server.registerPathHandler("/unlock", unlockHandler); server.start(8080); info("Mock server is now set up for captive portal redirect"); await SpecialPowers.pushPrefEnv({ set: [ ["captivedetect.canonicalURL", CANONICAL_SUCCESS_URL], ["captivedetect.canonicalContent", CANONICAL_CONTENT], ], }); }); // This test checks if the captive portal tab is removed after the // sucess/abort events are fired, assuming the tab has already redirected // to the canonical URL before they are fired. add_task(async function checkCaptivePortalTabCloseOnCanonicalURL_one() { await portalDetected(); let errorTab = await openCaptivePortalErrorTab(); let tab = await openCaptivePortalLoginTab(errorTab, LOGIN_URL); let browser = tab.linkedBrowser; let redirectedToCanonicalURL = BrowserTestUtils.browserLoaded( browser, false, CANONICAL_SUCCESS_URL ); let errorPageReloaded = BrowserTestUtils.waitForErrorPage( errorTab.linkedBrowser ); await SpecialPowers.spawn(browser, [], async () => { let doc = content.document; let loginButton = doc.querySelector("a"); await ContentTaskUtils.waitForCondition( () => loginButton, "Login button on the captive portal tab is visible" ); info("Clicking the login button on the captive portal tab page"); await EventUtils.synthesizeMouseAtCenter(loginButton, {}, content); }); await redirectedToCanonicalURL; info( "Re-direct to canonical URL in the captive portal tab was succcessful after login" ); let tabClosed = BrowserTestUtils.waitForTabClosing(tab); Services.obs.notifyObservers(null, "captive-portal-login-success"); await tabClosed; info( "Captive portal tab was closed on re-direct to canonical URL after login as expected" ); await errorPageReloaded; info("Captive portal error page was reloaded"); gBrowser.removeTab(errorTab); }); // This test checks if the captive portal tab is removed on location change // i.e. when it is re-directed to the canonical URL long after success/abort // event handlers are executed. add_task(async function checkCaptivePortalTabCloseOnCanonicalURL_two() { loginPageShown = false; await portalDetected(); let errorTab = await openCaptivePortalErrorTab(); let tab = await openCaptivePortalLoginTab(errorTab, LOGIN_URL); let browser = tab.linkedBrowser; let redirectedToCanonicalURL = BrowserTestUtils.waitForLocationChange( gBrowser, CANONICAL_SUCCESS_URL ); let errorPageReloaded = BrowserTestUtils.waitForErrorPage( errorTab.linkedBrowser ); Services.obs.notifyObservers(null, "captive-portal-login-success"); await TestUtils.waitForCondition( () => CPS.state == CPS.UNLOCKED_PORTAL, "Captive portal is released" ); let tabClosed = BrowserTestUtils.waitForTabClosing(tab); await SpecialPowers.spawn(browser, [], async () => { let doc = content.document; let loginButton = doc.querySelector("a"); await ContentTaskUtils.waitForCondition( () => loginButton, "Login button on the captive portal tab is visible" ); info("Clicking the login button on the captive portal tab page"); await EventUtils.synthesizeMouseAtCenter(loginButton, {}, content); }); await redirectedToCanonicalURL; info( "Re-direct to canonical URL in the captive portal tab was succcessful after login" ); await tabClosed; info( "Captive portal tab was closed on re-direct to canonical URL after login as expected" ); await errorPageReloaded; info("Captive portal error page was reloaded"); gBrowser.removeTab(errorTab); // Stop the server. await new Promise(r => server.stop(r)); });