Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

"use strict";
/* import-globals-from browser_head.js */
Services.scriptloader.loadSubScript(
this
);
// ASRouter may hit "closed database" IDB errors when
// clearPrivateBrowsingData fires last-pb-context-exited while
// it is recording impressions in a PBM window.
const { PromiseTestUtils } = ChromeUtils.importESModule(
);
PromiseTestUtils.allowMatchingRejectionsGlobally(
/Can't start a transaction on a closed database/
);
const TEST_ORIGIN = "http://mochi.test:8888";
const PAGE_URL = `${TEST_ORIGIN}/${DIR_PATH}/empty_with_utils.html`;
const SW_SCRIPT = "empty.js";
let scopeCounter = 0;
function nextScope() {
return `empty.html?pbm_cleanup_${scopeCounter++}`;
}
function getPBMRegistrationCount() {
let count = 0;
let regs = SWM.getAllRegistrations();
for (let i = 0; i < regs.length; i++) {
let reg = regs.queryElementAt(i, Ci.nsIServiceWorkerRegistrationInfo);
if (reg.principal.originAttributes.privateBrowsingId === 1) {
count++;
}
}
return count;
}
add_setup(async function () {
// testing.enabled is needed to allow SW registration on non-secure
// (http://) origins used by the mochitest server.
await SpecialPowers.pushPrefEnv({
set: [["dom.serviceWorkers.testing.enabled", true]],
});
});
async function registerPBMServiceWorker(scope) {
let pbmWin = await BrowserTestUtils.openNewBrowserWindow({ private: true });
let tab = await BrowserTestUtils.openNewForegroundTab(
pbmWin.gBrowser,
PAGE_URL
);
await SpecialPowers.spawn(
tab.linkedBrowser,
[{ script: SW_SCRIPT, scope }],
async function ({ script, scope }) {
await content.wrappedJSObject.registerAndWaitForActive(script, scope);
}
);
BrowserTestUtils.removeTab(tab);
// Return the window so the caller can control when it closes.
return pbmWin;
}
add_task(async function test_pbm_sw_removed_by_clearPrivateBrowsingData() {
let scope = nextScope();
let pbmWin = await registerPBMServiceWorker(scope);
Assert.greaterOrEqual(
getPBMRegistrationCount(),
1,
"PBM service worker registered"
);
let flags = await new Promise(resolve => {
Services.clearData.clearPrivateBrowsingData({
onDataDeleted(aFailedFlags) {
resolve(aFailedFlags);
},
});
});
Assert.equal(flags, 0, "clearPrivateBrowsingData completed without failure");
Assert.equal(
getPBMRegistrationCount(),
0,
"PBM service worker removed after cleanup"
);
await BrowserTestUtils.closeWindow(pbmWin);
});
add_task(async function test_pbm_cleanup_preserves_normal_sw() {
let pbmScope = nextScope();
let normalScope = nextScope();
// Register a normal SW first.
let normalReg = await install_sw({
origin: TEST_ORIGIN,
script: SW_SCRIPT,
scope: normalScope,
});
ok(normalReg, "Normal service worker registered");
// Register a PBM SW.
let pbmWin = await registerPBMServiceWorker(pbmScope);
Assert.greaterOrEqual(
getPBMRegistrationCount(),
1,
"PBM service worker registered"
);
let flags = await new Promise(resolve => {
Services.clearData.clearPrivateBrowsingData({
onDataDeleted(aFailedFlags) {
resolve(aFailedFlags);
},
});
});
Assert.equal(flags, 0, "clearPrivateBrowsingData completed without failure");
Assert.equal(
getPBMRegistrationCount(),
0,
"PBM service worker removed after cleanup"
);
let normalCheck = swm_lookup_reg({
origin: TEST_ORIGIN,
script: SW_SCRIPT,
scope: normalScope,
});
ok(normalCheck, "Normal service worker still registered after PBM cleanup");
// Clean up.
await BrowserTestUtils.closeWindow(pbmWin);
let fullScope = `${TEST_ORIGIN}/${DIR_PATH}/${normalScope}`;
await new Promise(resolve => {
SWM.unregister(
getPrincipal(fullScope),
{ unregisterSucceeded: resolve, unregisterFailed: resolve },
fullScope
);
});
});
add_task(
async function test_multiple_pbm_sw_removed_by_clearPrivateBrowsingData() {
let scopes = [nextScope(), nextScope(), nextScope()];
let pbmWin = await BrowserTestUtils.openNewBrowserWindow({ private: true });
for (let scope of scopes) {
let tab = await BrowserTestUtils.openNewForegroundTab(
pbmWin.gBrowser,
PAGE_URL
);
await SpecialPowers.spawn(
tab.linkedBrowser,
[{ script: SW_SCRIPT, scope }],
async function ({ script, scope }) {
await content.wrappedJSObject.registerAndWaitForActive(script, scope);
}
);
BrowserTestUtils.removeTab(tab);
}
Assert.equal(
getPBMRegistrationCount(),
3,
"All three PBM service workers registered"
);
let flags = await new Promise(resolve => {
Services.clearData.clearPrivateBrowsingData({
onDataDeleted(aFailedFlags) {
resolve(aFailedFlags);
},
});
});
Assert.equal(
flags,
0,
"clearPrivateBrowsingData completed without failure"
);
Assert.equal(
getPBMRegistrationCount(),
0,
"All PBM service workers removed after cleanup"
);
await BrowserTestUtils.closeWindow(pbmWin);
}
);
add_task(async function test_pbm_sw_removed_by_last_pb_context_exited() {
let scope = nextScope();
let pbmWin = await registerPBMServiceWorker(scope);
Assert.greaterOrEqual(
getPBMRegistrationCount(),
1,
"PBM service worker registered"
);
Services.obs.notifyObservers(null, "last-pb-context-exited");
await BrowserTestUtils.waitForCondition(
() => getPBMRegistrationCount() === 0,
"PBM registrations removed after last-pb-context-exited"
);
await BrowserTestUtils.closeWindow(pbmWin);
});