mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-23 00:47:31 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
788
services/sync/tps/extensions/mozmill/resource/modules/frame.js
Normal file
788
services/sync/tps/extensions/mozmill/resource/modules/frame.js
Normal file
|
|
@ -0,0 +1,788 @@
|
|||
/* 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/. */
|
||||
|
||||
var EXPORTED_SYMBOLS = ['Collector','Runner','events', 'runTestFile', 'log',
|
||||
'timers', 'persisted', 'shutdownApplication'];
|
||||
|
||||
var Cc = Components.classes;
|
||||
var Ci = Components.interfaces;
|
||||
var Cu = Components.utils;
|
||||
|
||||
const TIMEOUT_SHUTDOWN_HTTPD = 15000;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
Cu.import('resource://mozmill/stdlib/httpd.js');
|
||||
|
||||
var broker = {}; Cu.import('resource://mozmill/driver/msgbroker.js', broker);
|
||||
var assertions = {}; Cu.import('resource://mozmill/modules/assertions.js', assertions);
|
||||
var errors = {}; Cu.import('resource://mozmill/modules/errors.js', errors);
|
||||
var os = {}; Cu.import('resource://mozmill/stdlib/os.js', os);
|
||||
var strings = {}; Cu.import('resource://mozmill/stdlib/strings.js', strings);
|
||||
var arrays = {}; Cu.import('resource://mozmill/stdlib/arrays.js', arrays);
|
||||
var withs = {}; Cu.import('resource://mozmill/stdlib/withs.js', withs);
|
||||
var utils = {}; Cu.import('resource://mozmill/stdlib/utils.js', utils);
|
||||
|
||||
var securableModule = {};
|
||||
Cu.import('resource://mozmill/stdlib/securable-module.js', securableModule);
|
||||
|
||||
var uuidgen = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
|
||||
|
||||
var httpd = null;
|
||||
var persisted = {};
|
||||
|
||||
var assert = new assertions.Assert();
|
||||
var expect = new assertions.Expect();
|
||||
|
||||
var mozmill = undefined;
|
||||
var mozelement = undefined;
|
||||
var modules = undefined;
|
||||
|
||||
var timers = [];
|
||||
|
||||
|
||||
/**
|
||||
* Shutdown or restart the application
|
||||
*
|
||||
* @param {boolean} [aFlags=undefined]
|
||||
* Additional flags how to handle the shutdown or restart. The attributes
|
||||
* eRestarti386 and eRestartx86_64 have not been documented yet.
|
||||
* @see https://developer.mozilla.org/nsIAppStartup#Attributes
|
||||
*/
|
||||
function shutdownApplication(aFlags) {
|
||||
var flags = Ci.nsIAppStartup.eForceQuit;
|
||||
|
||||
if (aFlags) {
|
||||
flags |= aFlags;
|
||||
}
|
||||
|
||||
// Send a request to shutdown the application. That will allow us and other
|
||||
// components to finish up with any shutdown code. Please note that we don't
|
||||
// care if other components or add-ons want to prevent this via cancelQuit,
|
||||
// we really force the shutdown.
|
||||
let cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"].
|
||||
createInstance(Components.interfaces.nsISupportsPRBool);
|
||||
Services.obs.notifyObservers(cancelQuit, "quit-application-requested", null);
|
||||
|
||||
// Use a timer to trigger the application restart, which will allow us to
|
||||
// send an ACK packet via jsbridge if the method has been called via Python.
|
||||
var event = {
|
||||
notify: function(timer) {
|
||||
Services.startup.quit(flags);
|
||||
}
|
||||
}
|
||||
|
||||
var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
timer.initWithCallback(event, 100, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
}
|
||||
|
||||
function stateChangeBase(possibilties, restrictions, target, cmeta, v) {
|
||||
if (possibilties) {
|
||||
if (!arrays.inArray(possibilties, v)) {
|
||||
// TODO Error value not in this.poss
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (restrictions) {
|
||||
for (var i in restrictions) {
|
||||
var r = restrictions[i];
|
||||
if (!r(v)) {
|
||||
// TODO error value did not pass restriction
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fire jsbridge notification, logging notification, listener notifications
|
||||
events[target] = v;
|
||||
events.fireEvent(cmeta, target);
|
||||
}
|
||||
|
||||
|
||||
var events = {
|
||||
appQuit : false,
|
||||
currentModule : null,
|
||||
currentState : null,
|
||||
currentTest : null,
|
||||
shutdownRequested : false,
|
||||
userShutdown : null,
|
||||
userShutdownTimer : null,
|
||||
|
||||
listeners : {},
|
||||
globalListeners : []
|
||||
}
|
||||
|
||||
events.setState = function (v) {
|
||||
return stateChangeBase(['dependencies', 'setupModule', 'teardownModule',
|
||||
'test', 'setupTest', 'teardownTest', 'collection'],
|
||||
null, 'currentState', 'setState', v);
|
||||
}
|
||||
|
||||
events.toggleUserShutdown = function (obj){
|
||||
if (!this.userShutdown) {
|
||||
this.userShutdown = obj;
|
||||
|
||||
var event = {
|
||||
notify: function(timer) {
|
||||
events.toggleUserShutdown(obj);
|
||||
}
|
||||
}
|
||||
|
||||
this.userShutdownTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
this.userShutdownTimer.initWithCallback(event, obj.timeout, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
|
||||
} else {
|
||||
this.userShutdownTimer.cancel();
|
||||
|
||||
// If the application is not going to shutdown, the user shutdown failed and
|
||||
// we have to force a shutdown.
|
||||
if (!events.appQuit) {
|
||||
this.fail({'function':'events.toggleUserShutdown',
|
||||
'message':'Shutdown expected but none detected before timeout',
|
||||
'userShutdown': obj});
|
||||
|
||||
var flags = Ci.nsIAppStartup.eAttemptQuit;
|
||||
if (events.isRestartShutdown()) {
|
||||
flags |= Ci.nsIAppStartup.eRestart;
|
||||
}
|
||||
|
||||
shutdownApplication(flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
events.isUserShutdown = function () {
|
||||
return this.userShutdown ? this.userShutdown["user"] : false;
|
||||
}
|
||||
|
||||
events.isRestartShutdown = function () {
|
||||
return this.userShutdown.restart;
|
||||
}
|
||||
|
||||
events.startShutdown = function (obj) {
|
||||
events.fireEvent('shutdown', obj);
|
||||
|
||||
if (obj["user"]) {
|
||||
events.toggleUserShutdown(obj);
|
||||
} else {
|
||||
shutdownApplication(obj.flags);
|
||||
}
|
||||
}
|
||||
|
||||
events.setTest = function (test) {
|
||||
test.__start__ = Date.now();
|
||||
test.__passes__ = [];
|
||||
test.__fails__ = [];
|
||||
|
||||
events.currentTest = test;
|
||||
|
||||
var obj = {'filename': events.currentModule.__file__,
|
||||
'name': test.__name__}
|
||||
events.fireEvent('setTest', obj);
|
||||
}
|
||||
|
||||
events.endTest = function (test) {
|
||||
// use the current test unless specified
|
||||
if (test === undefined) {
|
||||
test = events.currentTest;
|
||||
}
|
||||
|
||||
// If no test is set it has already been reported. Beside that we don't want
|
||||
// to report it a second time.
|
||||
if (!test || test.status === 'done')
|
||||
return;
|
||||
|
||||
// report the end of a test
|
||||
test.__end__ = Date.now();
|
||||
test.status = 'done';
|
||||
|
||||
var obj = {'filename': events.currentModule.__file__,
|
||||
'passed': test.__passes__.length,
|
||||
'failed': test.__fails__.length,
|
||||
'passes': test.__passes__,
|
||||
'fails' : test.__fails__,
|
||||
'name' : test.__name__,
|
||||
'time_start': test.__start__,
|
||||
'time_end': test.__end__}
|
||||
|
||||
if (test.skipped) {
|
||||
obj['skipped'] = true;
|
||||
obj.skipped_reason = test.skipped_reason;
|
||||
}
|
||||
|
||||
if (test.meta) {
|
||||
obj.meta = test.meta;
|
||||
}
|
||||
|
||||
// Report the test result only if the test is a true test or if it is failing
|
||||
if (withs.startsWith(test.__name__, "test") || test.__fails__.length > 0) {
|
||||
events.fireEvent('endTest', obj);
|
||||
}
|
||||
}
|
||||
|
||||
events.setModule = function (aModule) {
|
||||
aModule.__start__ = Date.now();
|
||||
aModule.__status__ = 'running';
|
||||
|
||||
var result = stateChangeBase(null,
|
||||
[function (aModule) {return (aModule.__file__ != undefined)}],
|
||||
'currentModule', 'setModule', aModule);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
events.endModule = function (aModule) {
|
||||
// It should only reported once, so check if it already has been done
|
||||
if (aModule.__status__ === 'done')
|
||||
return;
|
||||
|
||||
aModule.__end__ = Date.now();
|
||||
aModule.__status__ = 'done';
|
||||
|
||||
var obj = {
|
||||
'filename': aModule.__file__,
|
||||
'time_start': aModule.__start__,
|
||||
'time_end': aModule.__end__
|
||||
}
|
||||
|
||||
events.fireEvent('endModule', obj);
|
||||
}
|
||||
|
||||
events.pass = function (obj) {
|
||||
// a low level event, such as a keystroke, succeeds
|
||||
if (events.currentTest) {
|
||||
events.currentTest.__passes__.push(obj);
|
||||
}
|
||||
|
||||
for (var timer of timers) {
|
||||
timer.actions.push(
|
||||
{"currentTest": events.currentModule.__file__ + "::" + events.currentTest.__name__,
|
||||
"obj": obj,
|
||||
"result": "pass"}
|
||||
);
|
||||
}
|
||||
|
||||
events.fireEvent('pass', obj);
|
||||
}
|
||||
|
||||
events.fail = function (obj) {
|
||||
var error = obj.exception;
|
||||
|
||||
if (error) {
|
||||
// Error objects aren't enumerable https://bugzilla.mozilla.org/show_bug.cgi?id=637207
|
||||
obj.exception = {
|
||||
name: error.name,
|
||||
message: error.message,
|
||||
lineNumber: error.lineNumber,
|
||||
fileName: error.fileName,
|
||||
stack: error.stack
|
||||
};
|
||||
}
|
||||
|
||||
// a low level event, such as a keystroke, fails
|
||||
if (events.currentTest) {
|
||||
events.currentTest.__fails__.push(obj);
|
||||
}
|
||||
|
||||
for (var time of timers) {
|
||||
timer.actions.push(
|
||||
{"currentTest": events.currentModule.__file__ + "::" + events.currentTest.__name__,
|
||||
"obj": obj,
|
||||
"result": "fail"}
|
||||
);
|
||||
}
|
||||
|
||||
events.fireEvent('fail', obj);
|
||||
}
|
||||
|
||||
events.skip = function (reason) {
|
||||
// this is used to report skips associated with setupModule and nothing else
|
||||
events.currentTest.skipped = true;
|
||||
events.currentTest.skipped_reason = reason;
|
||||
|
||||
for (var timer of timers) {
|
||||
timer.actions.push(
|
||||
{"currentTest": events.currentModule.__file__ + "::" + events.currentTest.__name__,
|
||||
"obj": reason,
|
||||
"result": "skip"}
|
||||
);
|
||||
}
|
||||
|
||||
events.fireEvent('skip', reason);
|
||||
}
|
||||
|
||||
events.fireEvent = function (name, obj) {
|
||||
if (events.appQuit) {
|
||||
// dump('* Event discarded: ' + name + ' ' + JSON.stringify(obj) + '\n');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.listeners[name]) {
|
||||
for (var i in this.listeners[name]) {
|
||||
this.listeners[name][i](obj);
|
||||
}
|
||||
}
|
||||
|
||||
for (var listener of this.globalListeners) {
|
||||
listener(name, obj);
|
||||
}
|
||||
}
|
||||
|
||||
events.addListener = function (name, listener) {
|
||||
if (this.listeners[name]) {
|
||||
this.listeners[name].push(listener);
|
||||
} else if (name == '') {
|
||||
this.globalListeners.push(listener)
|
||||
} else {
|
||||
this.listeners[name] = [listener];
|
||||
}
|
||||
}
|
||||
|
||||
events.removeListener = function (listener) {
|
||||
for (var listenerIndex in this.listeners) {
|
||||
var e = this.listeners[listenerIndex];
|
||||
|
||||
for (var i in e){
|
||||
if (e[i] == listener) {
|
||||
this.listeners[listenerIndex] = arrays.remove(e, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i in this.globalListeners) {
|
||||
if (this.globalListeners[i] == listener) {
|
||||
this.globalListeners = arrays.remove(this.globalListeners, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
events.persist = function () {
|
||||
try {
|
||||
events.fireEvent('persist', persisted);
|
||||
} catch (e) {
|
||||
events.fireEvent('error', "persist serialization failed.")
|
||||
}
|
||||
}
|
||||
|
||||
events.firePythonCallback = function (obj) {
|
||||
obj['test'] = events.currentModule.__file__;
|
||||
events.fireEvent('firePythonCallback', obj);
|
||||
}
|
||||
|
||||
events.screenshot = function (obj) {
|
||||
// Find the name of the test function
|
||||
for (var attr in events.currentModule) {
|
||||
if (events.currentModule[attr] == events.currentTest) {
|
||||
var testName = attr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
obj['test_file'] = events.currentModule.__file__;
|
||||
obj['test_name'] = testName;
|
||||
events.fireEvent('screenshot', obj);
|
||||
}
|
||||
|
||||
var log = function (obj) {
|
||||
events.fireEvent('log', obj);
|
||||
}
|
||||
|
||||
// Register the listeners
|
||||
broker.addObject({'endTest': events.endTest,
|
||||
'fail': events.fail,
|
||||
'firePythonCallback': events.firePythonCallback,
|
||||
'log': log,
|
||||
'pass': events.pass,
|
||||
'persist': events.persist,
|
||||
'screenshot': events.screenshot,
|
||||
'shutdown': events.startShutdown,
|
||||
});
|
||||
|
||||
try {
|
||||
Cu.import('resource://jsbridge/modules/Events.jsm');
|
||||
|
||||
events.addListener('', function (name, obj) {
|
||||
Events.fireEvent('mozmill.' + name, obj);
|
||||
});
|
||||
} catch (e) {
|
||||
Services.console.logStringMessage("Event module of JSBridge not available.");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Observer for notifications when the application is going to shutdown
|
||||
*/
|
||||
function AppQuitObserver() {
|
||||
this.runner = null;
|
||||
|
||||
Services.obs.addObserver(this, "quit-application-requested", false);
|
||||
}
|
||||
|
||||
AppQuitObserver.prototype = {
|
||||
observe: function (aSubject, aTopic, aData) {
|
||||
switch (aTopic) {
|
||||
case "quit-application-requested":
|
||||
Services.obs.removeObserver(this, "quit-application-requested");
|
||||
|
||||
// If we observe a quit notification make sure to send the
|
||||
// results of the current test. In those cases we don't reach
|
||||
// the equivalent code in runTestModule()
|
||||
events.pass({'message': 'AppQuitObserver: ' + JSON.stringify(aData),
|
||||
'userShutdown': events.userShutdown});
|
||||
|
||||
if (this.runner) {
|
||||
this.runner.end();
|
||||
}
|
||||
|
||||
if (httpd) {
|
||||
httpd.stop();
|
||||
}
|
||||
|
||||
events.appQuit = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var appQuitObserver = new AppQuitObserver();
|
||||
|
||||
/**
|
||||
* The collector handles HTTPd.js and initilizing the module
|
||||
*/
|
||||
function Collector() {
|
||||
this.test_modules_by_filename = {};
|
||||
this.testing = [];
|
||||
}
|
||||
|
||||
Collector.prototype.addHttpResource = function (aDirectory, aPath) {
|
||||
var fp = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
|
||||
fp.initWithPath(os.abspath(aDirectory, this.current_file));
|
||||
|
||||
return httpd.addHttpResource(fp, aPath);
|
||||
}
|
||||
|
||||
Collector.prototype.initTestModule = function (filename, testname) {
|
||||
var test_module = this.loadFile(filename, this);
|
||||
var has_restarted = !(testname == null);
|
||||
test_module.__tests__ = [];
|
||||
|
||||
for (var i in test_module) {
|
||||
if (typeof(test_module[i]) == "function") {
|
||||
test_module[i].__name__ = i;
|
||||
|
||||
// Only run setupModule if we are a single test OR if we are the first
|
||||
// test of a restart chain (don't run it prior to members in a restart
|
||||
// chain)
|
||||
if (i == "setupModule" && !has_restarted) {
|
||||
test_module.__setupModule__ = test_module[i];
|
||||
} else if (i == "setupTest") {
|
||||
test_module.__setupTest__ = test_module[i];
|
||||
} else if (i == "teardownTest") {
|
||||
test_module.__teardownTest__ = test_module[i];
|
||||
} else if (i == "teardownModule") {
|
||||
test_module.__teardownModule__ = test_module[i];
|
||||
} else if (withs.startsWith(i, "test")) {
|
||||
if (testname && (i != testname)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
testname = null;
|
||||
test_module.__tests__.push(test_module[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test_module.collector = this;
|
||||
test_module.status = 'loaded';
|
||||
|
||||
this.test_modules_by_filename[filename] = test_module;
|
||||
|
||||
return test_module;
|
||||
}
|
||||
|
||||
Collector.prototype.loadFile = function (path, collector) {
|
||||
var moduleLoader = new securableModule.Loader({
|
||||
rootPaths: ["resource://mozmill/modules/"],
|
||||
defaultPrincipal: "system",
|
||||
globals : { Cc: Cc,
|
||||
Ci: Ci,
|
||||
Cu: Cu,
|
||||
Cr: Components.results}
|
||||
});
|
||||
|
||||
// load a test module from a file and add some candy
|
||||
var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
|
||||
file.initWithPath(path);
|
||||
var uri = Services.io.newFileURI(file).spec;
|
||||
|
||||
this.loadTestResources();
|
||||
|
||||
var systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
|
||||
var module = new Components.utils.Sandbox(systemPrincipal);
|
||||
module.assert = assert;
|
||||
module.Cc = Cc;
|
||||
module.Ci = Ci;
|
||||
module.Cr = Components.results;
|
||||
module.Cu = Cu;
|
||||
module.collector = collector;
|
||||
module.driver = moduleLoader.require("driver");
|
||||
module.elementslib = mozelement;
|
||||
module.errors = errors;
|
||||
module.expect = expect;
|
||||
module.findElement = mozelement;
|
||||
module.log = log;
|
||||
module.mozmill = mozmill;
|
||||
module.persisted = persisted;
|
||||
|
||||
module.require = function (mod) {
|
||||
var loader = new securableModule.Loader({
|
||||
rootPaths: [Services.io.newFileURI(file.parent).spec,
|
||||
"resource://mozmill/modules/"],
|
||||
defaultPrincipal: "system",
|
||||
globals : { assert: assert,
|
||||
expect: expect,
|
||||
mozmill: mozmill,
|
||||
elementslib: mozelement, // This a quick hack to maintain backwards compatibility with 1.5.x
|
||||
findElement: mozelement,
|
||||
persisted: persisted,
|
||||
Cc: Cc,
|
||||
Ci: Ci,
|
||||
Cu: Cu,
|
||||
log: log }
|
||||
});
|
||||
|
||||
if (modules != undefined) {
|
||||
loader.modules = modules;
|
||||
}
|
||||
|
||||
var retval = loader.require(mod);
|
||||
modules = loader.modules;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (collector != undefined) {
|
||||
collector.current_file = file;
|
||||
collector.current_path = path;
|
||||
}
|
||||
|
||||
try {
|
||||
Services.scriptloader.loadSubScript(uri, module, "UTF-8");
|
||||
} catch (e) {
|
||||
var obj = {
|
||||
'filename': path,
|
||||
'passed': 0,
|
||||
'failed': 1,
|
||||
'passes': [],
|
||||
'fails' : [{'exception' : {
|
||||
message: e.message,
|
||||
filename: e.filename,
|
||||
lineNumber: e.lineNumber}}],
|
||||
'name' :'<TOP_LEVEL>'
|
||||
};
|
||||
|
||||
events.fail({'exception': e});
|
||||
events.fireEvent('endTest', obj);
|
||||
}
|
||||
|
||||
module.__file__ = path;
|
||||
module.__uri__ = uri;
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
Collector.prototype.loadTestResources = function () {
|
||||
// load resources we want in our tests
|
||||
if (mozmill === undefined) {
|
||||
mozmill = {};
|
||||
Cu.import("resource://mozmill/driver/mozmill.js", mozmill);
|
||||
}
|
||||
if (mozelement === undefined) {
|
||||
mozelement = {};
|
||||
Cu.import("resource://mozmill/driver/mozelement.js", mozelement);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function Httpd(aPort) {
|
||||
this.http_port = aPort;
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
var srv = new HttpServer();
|
||||
srv.registerContentType("sjs", "sjs");
|
||||
srv.identity.setPrimary("http", "localhost", this.http_port);
|
||||
srv.start(this.http_port);
|
||||
|
||||
this._httpd = srv;
|
||||
break;
|
||||
}
|
||||
catch (e) {
|
||||
// Failure most likely due to port conflict
|
||||
this.http_port++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Httpd.prototype.addHttpResource = function (aDir, aPath) {
|
||||
var path = aPath ? ("/" + aPath + "/") : "/";
|
||||
|
||||
try {
|
||||
this._httpd.registerDirectory(path, aDir);
|
||||
return 'http://localhost:' + this.http_port + path;
|
||||
}
|
||||
catch (e) {
|
||||
throw Error("Failure to register directory: " + aDir.path);
|
||||
}
|
||||
};
|
||||
|
||||
Httpd.prototype.stop = function () {
|
||||
if (!this._httpd) {
|
||||
return;
|
||||
}
|
||||
|
||||
var shutdown = false;
|
||||
this._httpd.stop(function () { shutdown = true; });
|
||||
|
||||
assert.waitFor(function () {
|
||||
return shutdown;
|
||||
}, "Local HTTP server has been stopped", TIMEOUT_SHUTDOWN_HTTPD);
|
||||
|
||||
this._httpd = null;
|
||||
};
|
||||
|
||||
function startHTTPd() {
|
||||
if (!httpd) {
|
||||
// Ensure that we start the HTTP server only once during a session
|
||||
httpd = new Httpd(43336);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function Runner() {
|
||||
this.collector = new Collector();
|
||||
this.ended = false;
|
||||
|
||||
var m = {}; Cu.import('resource://mozmill/driver/mozmill.js', m);
|
||||
this.platform = m.platform;
|
||||
|
||||
events.fireEvent('startRunner', true);
|
||||
}
|
||||
|
||||
Runner.prototype.end = function () {
|
||||
if (!this.ended) {
|
||||
this.ended = true;
|
||||
|
||||
appQuitObserver.runner = null;
|
||||
|
||||
events.endTest();
|
||||
events.endModule(events.currentModule);
|
||||
events.fireEvent('endRunner', true);
|
||||
events.persist();
|
||||
}
|
||||
};
|
||||
|
||||
Runner.prototype.runTestFile = function (filename, name) {
|
||||
var module = this.collector.initTestModule(filename, name);
|
||||
this.runTestModule(module);
|
||||
};
|
||||
|
||||
Runner.prototype.runTestModule = function (module) {
|
||||
appQuitObserver.runner = this;
|
||||
events.setModule(module);
|
||||
|
||||
// If setupModule passes, run all the tests. Otherwise mark them as skipped.
|
||||
if (this.execFunction(module.__setupModule__, module)) {
|
||||
for (var test of module.__tests__) {
|
||||
if (events.shutdownRequested) {
|
||||
break;
|
||||
}
|
||||
|
||||
// If setupTest passes, run the test. Otherwise mark it as skipped.
|
||||
if (this.execFunction(module.__setupTest__, module)) {
|
||||
this.execFunction(test);
|
||||
} else {
|
||||
this.skipFunction(test, module.__setupTest__.__name__ + " failed");
|
||||
}
|
||||
|
||||
this.execFunction(module.__teardownTest__, module);
|
||||
}
|
||||
|
||||
} else {
|
||||
for (var test of module.__tests__) {
|
||||
this.skipFunction(test, module.__setupModule__.__name__ + " failed");
|
||||
}
|
||||
}
|
||||
|
||||
this.execFunction(module.__teardownModule__, module);
|
||||
events.endModule(module);
|
||||
};
|
||||
|
||||
Runner.prototype.execFunction = function (func, arg) {
|
||||
if (typeof func !== "function" || events.shutdownRequested) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var isTest = withs.startsWith(func.__name__, "test");
|
||||
|
||||
events.setState(isTest ? "test" : func.__name);
|
||||
events.setTest(func);
|
||||
|
||||
// skip excluded platforms
|
||||
if (func.EXCLUDED_PLATFORMS != undefined) {
|
||||
if (arrays.inArray(func.EXCLUDED_PLATFORMS, this.platform)) {
|
||||
events.skip("Platform exclusion");
|
||||
events.endTest(func);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// skip function if requested
|
||||
if (func.__force_skip__ != undefined) {
|
||||
events.skip(func.__force_skip__);
|
||||
events.endTest(func);
|
||||
return false;
|
||||
}
|
||||
|
||||
// execute the test function
|
||||
try {
|
||||
func(arg);
|
||||
} catch (e) {
|
||||
if (e instanceof errors.ApplicationQuitError) {
|
||||
events.shutdownRequested = true;
|
||||
} else {
|
||||
events.fail({'exception': e, 'test': func})
|
||||
}
|
||||
}
|
||||
|
||||
// If a user shutdown has been requested and the function already returned,
|
||||
// we can assume that a shutdown will not happen anymore. We should force a
|
||||
// shutdown then, to prevent the next test from being executed.
|
||||
if (events.isUserShutdown()) {
|
||||
events.shutdownRequested = true;
|
||||
events.toggleUserShutdown(events.userShutdown);
|
||||
}
|
||||
|
||||
events.endTest(func);
|
||||
return events.currentTest.__fails__.length == 0;
|
||||
};
|
||||
|
||||
function runTestFile(filename, name) {
|
||||
var runner = new Runner();
|
||||
runner.runTestFile(filename, name);
|
||||
runner.end();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Runner.prototype.skipFunction = function (func, message) {
|
||||
events.setTest(func);
|
||||
events.skip(message);
|
||||
events.endTest(func);
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue