174 lines
4.8 KiB
JavaScript
174 lines
4.8 KiB
JavaScript
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
|
/* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
"use strict";
|
|
|
|
function ChromeTask_ChromeScript() {
|
|
/* eslint-env mozilla/chrome-script */
|
|
|
|
"use strict";
|
|
|
|
const { Assert: AssertCls } = ChromeUtils.importESModule(
|
|
"resource://testing-common/Assert.sys.mjs"
|
|
);
|
|
|
|
addMessageListener("chrome-task:spawn", async function (aData) {
|
|
let id = aData.id;
|
|
let source = aData.runnable || "()=>{}";
|
|
|
|
function getStack(aStack) {
|
|
let frames = [];
|
|
for (let frame = aStack; frame; frame = frame.caller) {
|
|
frames.push(frame.filename + ":" + frame.name + ":" + frame.lineNumber);
|
|
}
|
|
return frames.join("\n");
|
|
}
|
|
|
|
/* eslint-disable no-unused-vars */
|
|
var Assert = new AssertCls((err, message, stack) => {
|
|
sendAsyncMessage("chrome-task:test-result", {
|
|
id,
|
|
condition: !err,
|
|
name: err ? err.message : message,
|
|
stack: getStack(err ? err.stack : stack),
|
|
});
|
|
});
|
|
|
|
var ok = Assert.ok.bind(Assert);
|
|
var is = Assert.equal.bind(Assert);
|
|
var isnot = Assert.notEqual.bind(Assert);
|
|
|
|
function todo(expr, name) {
|
|
sendAsyncMessage("chrome-task:test-todo", { id, expr, name });
|
|
}
|
|
|
|
function todo_is(a, b, name) {
|
|
sendAsyncMessage("chrome-task:test-todo_is", { id, a, b, name });
|
|
}
|
|
|
|
function info(name) {
|
|
sendAsyncMessage("chrome-task:test-info", { id, name });
|
|
}
|
|
/* eslint-enable no-unused-vars */
|
|
|
|
try {
|
|
let runnablestr = `
|
|
(() => {
|
|
return (${source});
|
|
})();`;
|
|
|
|
// eslint-disable-next-line no-eval
|
|
let runnable = eval(runnablestr);
|
|
let result = await runnable.call(this, aData.arg);
|
|
sendAsyncMessage("chrome-task:complete", {
|
|
id,
|
|
result,
|
|
});
|
|
} catch (ex) {
|
|
sendAsyncMessage("chrome-task:complete", {
|
|
id,
|
|
error: ex.toString(),
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* This object provides the public module functions.
|
|
*/
|
|
var ChromeTask = {
|
|
/**
|
|
* the ChromeScript if it has already been loaded.
|
|
*/
|
|
_chromeScript: null,
|
|
|
|
/**
|
|
* Mapping from message id to associated promise.
|
|
*/
|
|
_promises: new Map(),
|
|
|
|
/**
|
|
* Incrementing integer to generate unique message id.
|
|
*/
|
|
_messageID: 1,
|
|
|
|
/**
|
|
* Creates and starts a new task in the chrome process.
|
|
*
|
|
* @param arg A single serializable argument that will be passed to the
|
|
* task when executed on the content process.
|
|
* @param task
|
|
* - A generator or function which will be serialized and sent to
|
|
* the remote browser to be executed. Unlike Task.spawn, this
|
|
* argument may not be an iterator as it will be serialized and
|
|
* sent to the remote browser.
|
|
* @return A promise object where you can register completion callbacks to be
|
|
* called when the task terminates.
|
|
* @resolves With the final returned value of the task if it executes
|
|
* successfully.
|
|
* @rejects An error message if execution fails.
|
|
*/
|
|
spawn: function ChromeTask_spawn(arg, task) {
|
|
// Load the frame script if needed.
|
|
let handle = ChromeTask._chromeScript;
|
|
if (!handle) {
|
|
handle = SpecialPowers.loadChromeScript(ChromeTask_ChromeScript);
|
|
handle.addMessageListener("chrome-task:complete", ChromeTask.onComplete);
|
|
handle.addMessageListener("chrome-task:test-result", ChromeTask.onResult);
|
|
handle.addMessageListener("chrome-task:test-info", ChromeTask.onInfo);
|
|
handle.addMessageListener("chrome-task:test-todo", ChromeTask.onTodo);
|
|
handle.addMessageListener(
|
|
"chrome-task:test-todo_is",
|
|
ChromeTask.onTodoIs
|
|
);
|
|
ChromeTask._chromeScript = handle;
|
|
}
|
|
|
|
let deferred = {};
|
|
deferred.promise = new Promise((resolve, reject) => {
|
|
deferred.resolve = resolve;
|
|
deferred.reject = reject;
|
|
});
|
|
|
|
let id = ChromeTask._messageID++;
|
|
ChromeTask._promises.set(id, deferred);
|
|
|
|
handle.sendAsyncMessage("chrome-task:spawn", {
|
|
id,
|
|
runnable: task.toString(),
|
|
arg,
|
|
});
|
|
|
|
return deferred.promise;
|
|
},
|
|
|
|
onComplete(aData) {
|
|
let deferred = ChromeTask._promises.get(aData.id);
|
|
ChromeTask._promises.delete(aData.id);
|
|
|
|
if (aData.error) {
|
|
deferred.reject(aData.error);
|
|
} else {
|
|
deferred.resolve(aData.result);
|
|
}
|
|
},
|
|
|
|
onResult(aData) {
|
|
SimpleTest.record(aData.condition, aData.name);
|
|
},
|
|
|
|
onInfo(aData) {
|
|
SimpleTest.info(aData.name);
|
|
},
|
|
|
|
onTodo(aData) {
|
|
SimpleTest.todo(aData.expr, aData.name);
|
|
},
|
|
|
|
onTodoIs(aData) {
|
|
SimpleTest.todo_is(aData.a, aData.b, aData.name);
|
|
},
|
|
};
|