forked from mirrors/gecko-dev
207 lines
6.6 KiB
JavaScript
207 lines
6.6 KiB
JavaScript
/* 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 = `<html><body><a href="/unlock">login</a></body></html>`;
|
|
const BAD_CERT_PAGE = "https://expired.example.com/";
|
|
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;
|
|
|
|
async function openCaptivePortalErrorTab() {
|
|
await portalDetected();
|
|
|
|
// Open a page with a cert error.
|
|
let browser;
|
|
let certErrorLoaded;
|
|
let errorTab = await BrowserTestUtils.openNewForegroundTab(
|
|
gBrowser,
|
|
() => {
|
|
let tab = BrowserTestUtils.addTab(gBrowser, BAD_CERT_PAGE);
|
|
gBrowser.selectedTab = tab;
|
|
browser = gBrowser.selectedBrowser;
|
|
certErrorLoaded = BrowserTestUtils.waitForErrorPage(browser);
|
|
return tab;
|
|
},
|
|
false
|
|
);
|
|
await certErrorLoaded;
|
|
info("A cert error page was opened");
|
|
await SpecialPowers.spawn(errorTab.linkedBrowser, [], async () => {
|
|
let doc = content.document;
|
|
let loginButton = doc.getElementById("openPortalLoginPageButton");
|
|
await ContentTaskUtils.waitForCondition(
|
|
() => loginButton && doc.body.className == "captiveportal",
|
|
"Captive portal error page UI is visible"
|
|
);
|
|
});
|
|
info("Captive portal error page UI is visible");
|
|
|
|
return errorTab;
|
|
}
|
|
|
|
async function openCaptivePortalLoginTab(errorTab) {
|
|
let portalTabPromise = BrowserTestUtils.waitForNewTab(
|
|
gBrowser,
|
|
LOGIN_URL,
|
|
true
|
|
);
|
|
|
|
await SpecialPowers.spawn(errorTab.linkedBrowser, [], async () => {
|
|
let doc = content.document;
|
|
let loginButton = doc.getElementById("openPortalLoginPageButton");
|
|
info("Click on the login button on the captive portal error page");
|
|
await EventUtils.synthesizeMouseAtCenter(loginButton, {}, content);
|
|
});
|
|
|
|
let portalTab = await portalTabPromise;
|
|
is(
|
|
gBrowser.selectedTab,
|
|
portalTab,
|
|
"Captive Portal login page is now open in a new foreground tab."
|
|
);
|
|
|
|
return portalTab;
|
|
}
|
|
|
|
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_task(async function setup() {
|
|
// 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() {
|
|
let errorTab = await openCaptivePortalErrorTab();
|
|
let tab = await openCaptivePortalLoginTab(errorTab);
|
|
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;
|
|
let errorTab = await openCaptivePortalErrorTab();
|
|
let tab = await openCaptivePortalLoginTab(errorTab);
|
|
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));
|
|
});
|