Source code

Revision control

Copy as Markdown

Other Tools

// Any copyright is dedicated to the Public Domain.
//
// This helper script exposes a runTests function that takes the name of a
// test script as its input argument and runs the test in three different
// contexts:
// 1. Regular Worker context
// 2. Service Worker context
// 3. Window context
// The function returns a promise which will get resolved once all tests
// finish. The testFile argument is the name of the test file to be run
// in the different contexts, and the optional order argument can be set
// to either "parallel" or "sequential" depending on how the caller wants
// the tests to be run. If this argument is not provided, the default is
// "both", which runs the tests in both modes.
// The caller of this function is responsible to call SimpleTest.finish
// when the returned promise is resolved.
function runTests(testFile, order) {
async function setupPrefs() {
// Bug 1746646: Make mochitests work with TCP enabled (cookieBehavior = 5)
// Acquire storage access permission here so that the Cache API is avaialable
return SpecialPowers.pushPrefEnv({
set: [
["dom.caches.testing.enabled", true],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true],
["dom.serviceWorkers.exemptFromPerDomainMax", true],
],
});
}
// adapted from dom/indexedDB/test/helpers.js
function clearStorage() {
var clearUnpartitionedStorage = new Promise(function (resolve) {
var qms = SpecialPowers.Services.qms;
var principal = SpecialPowers.wrap(document).nodePrincipal;
var request = qms.clearStoragesForPrincipal(principal);
var cb = SpecialPowers.wrapCallback(resolve);
request.callback = cb;
});
var clearPartitionedStorage = new Promise(function (resolve) {
var qms = SpecialPowers.Services.qms;
var principal = SpecialPowers.wrap(document).partitionedPrincipal;
var request = qms.clearStoragesForPrincipal(principal);
var cb = SpecialPowers.wrapCallback(resolve);
request.callback = cb;
});
return Promise.all([clearUnpartitionedStorage, clearPartitionedStorage]);
}
function loadScript(script) {
return new Promise(function (resolve, reject) {
var s = document.createElement("script");
s.src = script;
s.onerror = reject;
s.onload = resolve;
document.body.appendChild(s);
});
}
function importDrivers() {
/* import-globals-from worker_driver.js */
/* import-globals-from serviceworker_driver.js */
return Promise.all([
loadScript("worker_driver.js"),
loadScript("serviceworker_driver.js"),
]);
}
function runWorkerTest() {
return workerTestExec(testFile);
}
function runServiceWorkerTest() {
if (
navigator.serviceWorker == null &&
SpecialPowers.getBoolPref("dom.cache.privateBrowsing.enabled")
) {
return new Promise(function (resolve) {
resolve(true);
});
}
return serviceWorkerTestExec(testFile);
}
function runFrameTest() {
return new Promise(function (resolve) {
var iframe = document.createElement("iframe");
iframe.src = "frame.html";
iframe.onload = function () {
var doc = iframe.contentDocument;
var s = doc.createElement("script");
s.src = testFile;
window.addEventListener("message", function onMessage(event) {
if (event.data.context != "Window") {
return;
}
if (event.data.type == "finish") {
window.removeEventListener("message", onMessage);
resolve();
} else if (event.data.type == "status") {
ok(event.data.status, event.data.context + ": " + event.data.msg);
}
});
doc.body.appendChild(s);
};
document.body.appendChild(iframe);
});
}
SimpleTest.waitForExplicitFinish();
if (typeof order == "undefined") {
order = "sequential"; // sequential by default, see bug 1143222.
// TODO: Make this "both" again.
}
ok(
order == "parallel" || order == "sequential" || order == "both",
"order argument should be valid"
);
if (order == "both") {
info("Running tests in both modes; first: sequential");
return runTests(testFile, "sequential").then(function () {
info("Running tests in parallel mode");
return runTests(testFile, "parallel");
});
}
if (order == "sequential") {
return setupPrefs()
.then(importDrivers)
.then(runWorkerTest)
.then(clearStorage)
.then(runServiceWorkerTest)
.then(clearStorage)
.then(runFrameTest)
.then(clearStorage)
.catch(function (e) {
ok(false, "A promise was rejected during test execution: " + e);
});
}
return setupPrefs()
.then(importDrivers)
.then(() =>
Promise.all([runWorkerTest(), runServiceWorkerTest(), runFrameTest()])
)
.then(clearStorage)
.catch(function (e) {
ok(false, "A promise was rejected during test execution: " + e);
});
}