/** * Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ // The path to the top level directory. const depth = "../../../../"; var testGenerator; var testHarnessGenerator; var workerScriptPaths = []; loadScript("dom/quota/test/common/mochitest.js"); function loadScript(path) { const url = new URL(depth + path, window.location.href); SpecialPowers.Services.scriptloader.loadSubScript(url.href, this); } function loadWorkerScript(path) { const url = new URL(depth + path, window.location.href); workerScriptPaths.push(url.href); } function* testHarnessSteps() { function nextTestHarnessStep(val) { testHarnessGenerator.next(val); } info("Enabling storage testing"); enableStorageTesting().then(nextTestHarnessStep); yield undefined; info("Pushing preferences"); SpecialPowers.pushPrefEnv( { set: [["dom.storageManager.prompt.testing", true]], }, nextTestHarnessStep ); yield undefined; info("Clearing old databases"); clearAllDatabases(nextTestHarnessStep); yield undefined; info("Running test in given scopes"); if (workerScriptPaths.length) { info("Running test in a worker"); let workerScriptBlob = new Blob(["(" + workerScript.toString() + ")();"], { type: "text/javascript", }); let workerScriptURL = URL.createObjectURL(workerScriptBlob); let worker = new Worker(workerScriptURL); worker.onerror = function (event) { ok(false, "Worker had an error: " + event.message); worker.terminate(); nextTestHarnessStep(); }; worker.onmessage = function (event) { let message = event.data; switch (message.op) { case "ok": ok(message.condition, message.name + " - " + message.diag); break; case "todo": todo(message.condition, message.name, message.diag); break; case "info": info(message.msg); break; case "ready": worker.postMessage({ op: "load", files: workerScriptPaths }); break; case "loaded": worker.postMessage({ op: "start" }); break; case "done": ok(true, "Worker finished"); nextTestHarnessStep(); break; case "clearAllDatabases": clearAllDatabases(function () { worker.postMessage({ op: "clearAllDatabasesDone" }); }); break; default: ok( false, "Received a bad message from worker: " + JSON.stringify(message) ); nextTestHarnessStep(); } }; URL.revokeObjectURL(workerScriptURL); yield undefined; worker.terminate(); worker = null; clearAllDatabases(nextTestHarnessStep); yield undefined; } info("Running test in main thread"); // Now run the test script in the main thread. if (testSteps.constructor.name === "AsyncFunction") { SimpleTest.registerCleanupFunction(async function () { await requestFinished(clearAllDatabases()); }); add_task(testSteps); } else { testGenerator = testSteps(); testGenerator.next(); yield undefined; } } if (!window.runTest) { window.runTest = function () { SimpleTest.waitForExplicitFinish(); testHarnessGenerator = testHarnessSteps(); testHarnessGenerator.next(); }; } function finishTest() { SimpleTest.executeSoon(function () { clearAllDatabases(function () { SimpleTest.finish(); }); }); } function grabArgAndContinueHandler(arg) { testGenerator.next(arg); } function continueToNextStep() { SimpleTest.executeSoon(function () { testGenerator.next(); }); } function continueToNextStepSync() { testGenerator.next(); } function workerScript() { "use strict"; self.testGenerator = null; self.repr = function (_thing_) { if (typeof _thing_ == "undefined") { return "undefined"; } let str; try { str = _thing_ + ""; } catch (e) { return "[" + typeof _thing_ + "]"; } if (typeof _thing_ == "function") { str = str.replace(/^\s+/, ""); let idx = str.indexOf("{"); if (idx != -1) { str = str.substr(0, idx) + "{...}"; } } return str; }; self.ok = function (_condition_, _name_, _diag_) { self.postMessage({ op: "ok", condition: !!_condition_, name: _name_, diag: _diag_, }); }; self.is = function (_a_, _b_, _name_) { let pass = _a_ == _b_; let diag = pass ? "" : "got " + repr(_a_) + ", expected " + repr(_b_); ok(pass, _name_, diag); }; self.isnot = function (_a_, _b_, _name_) { let pass = _a_ != _b_; let diag = pass ? "" : "didn't expect " + repr(_a_) + ", but got it"; ok(pass, _name_, diag); }; self.todo = function (_condition_, _name_, _diag_) { self.postMessage({ op: "todo", condition: !!_condition_, name: _name_, diag: _diag_, }); }; self.info = function (_msg_) { self.postMessage({ op: "info", msg: _msg_ }); }; self.executeSoon = function (_fun_) { var channel = new MessageChannel(); channel.port1.postMessage(""); channel.port2.onmessage = function (event) { _fun_(); }; }; self.finishTest = function () { self.postMessage({ op: "done" }); }; self.grabArgAndContinueHandler = function (_arg_) { testGenerator.next(_arg_); }; self.continueToNextStep = function () { executeSoon(function () { testGenerator.next(); }); }; self.continueToNextStepSync = function () { testGenerator.next(); }; self._clearAllDatabasesCallback = undefined; self.clearAllDatabases = function (_callback_) { self._clearAllDatabasesCallback = _callback_; self.postMessage({ op: "clearAllDatabases" }); }; self.onerror = function (_message_, _file_, _line_) { ok( false, "Worker: uncaught exception [" + _file_ + ":" + _line_ + "]: '" + _message_ + "'" ); self.finishTest(); self.close(); return true; }; self.onmessage = function (_event_) { let message = _event_.data; switch (message.op) { case "load": info("Worker: loading " + JSON.stringify(message.files)); self.importScripts(message.files); self.postMessage({ op: "loaded" }); break; case "start": executeSoon(function () { info("Worker: starting tests"); testGenerator = testSteps(); testGenerator.next(); }); break; case "clearAllDatabasesDone": info("Worker: all databases are cleared"); if (self._clearAllDatabasesCallback) { self._clearAllDatabasesCallback(); } break; default: throw new Error( "Received a bad message from parent: " + JSON.stringify(message) ); } }; self.postMessage({ op: "ready" }); }