Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
220
gaia/tests/jsmarionette/runner/marionette-js-runner/lib/ui.js
Executable file
220
gaia/tests/jsmarionette/runner/marionette-js-runner/lib/ui.js
Executable file
|
|
@ -0,0 +1,220 @@
|
|||
'use strict';
|
||||
/**
|
||||
Custom marionette-runner interface for mocha.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Suite = require('mocha/lib/suite');
|
||||
var HostManager = require('./runtime/hostmanager').HostManager;
|
||||
var RPC = require('./rpc');
|
||||
var Test = require('mocha/lib/test');
|
||||
var escapeRe = require('escape-string-regexp');
|
||||
|
||||
function MarionetteTest(title, hostManager, fn) {
|
||||
this.hostManager = hostManager;
|
||||
Test.call(this, title, fn);
|
||||
}
|
||||
|
||||
MarionetteTest.prototype = {
|
||||
__proto__: Test.prototype,
|
||||
|
||||
run: function(fn) {
|
||||
return Test.prototype.run.call(this, function(err) {
|
||||
if (err) {
|
||||
// In the case of an error we attempt to run host/client specific error
|
||||
// handles where possible so first we attempt to see if there is a host
|
||||
// that matches a client...
|
||||
if (!this.ctx.hosts.length && this.ctx.hosts.length || !err.client) {
|
||||
return fn(err);
|
||||
}
|
||||
|
||||
var hosts = this.ctx.hosts;
|
||||
|
||||
// attempt to find the correct host...
|
||||
var host;
|
||||
for (var i = 0; i < hosts.length; i++) {
|
||||
if (
|
||||
// In the case of direct match then we found it...
|
||||
hosts[i].client === err.client ||
|
||||
// The client's scope method creates prototype chains so if it is in
|
||||
// the same chain it is also a match...
|
||||
hosts[i].client.isPrototypeOf(err.client)
|
||||
) {
|
||||
host = hosts[i];
|
||||
|
||||
host.session.checkError(host.profileConfig, err)
|
||||
.then(fn)
|
||||
.catch(fn);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
fn();
|
||||
}.bind(this));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@param {Object} suite root suite for mocha.
|
||||
*/
|
||||
module.exports = function(suite) {
|
||||
// initialize the RPC bridge...
|
||||
var rpc = new RPC(process.send.bind(process));
|
||||
process.on('message', rpc.handle());
|
||||
|
||||
var suites = [suite];
|
||||
var manager = new HostManager();
|
||||
|
||||
// setup global hooks
|
||||
suite.beforeAll('marionette-mocha global init', function() {
|
||||
this.hosts = [];
|
||||
this.runner = rpc.client('runner', ['createHost', 'createProfile']);
|
||||
});
|
||||
|
||||
suite.on('pre-require', function(context, file, mocha) {
|
||||
/**
|
||||
* Execute before each test case.
|
||||
*/
|
||||
context.setup = function(name, fn) {
|
||||
suites[0].beforeEach(name, fn);
|
||||
};
|
||||
|
||||
/**
|
||||
* Execute after each test case.
|
||||
*/
|
||||
context.teardown = function(name, fn) {
|
||||
suites[0].afterEach(name, fn);
|
||||
};
|
||||
|
||||
/**
|
||||
* Execute before the suite.
|
||||
*/
|
||||
context.suiteSetup = function(name, fn) {
|
||||
suites[0].beforeAll(name, fn);
|
||||
};
|
||||
|
||||
/**
|
||||
* Execute after the suite.
|
||||
*/
|
||||
context.suiteTeardown = function(name, fn) {
|
||||
suites[0].afterAll(name, fn);
|
||||
};
|
||||
|
||||
/**
|
||||
* Describe a "suite" with the given `title`
|
||||
* and callback `fn` containing nested suites
|
||||
* and/or tests.
|
||||
*/
|
||||
context.suite = function(title, fn) {
|
||||
var suite = Suite.create(suites[0], title);
|
||||
suite.file = file;
|
||||
suites.unshift(suite);
|
||||
fn.call(suite);
|
||||
suites.shift();
|
||||
return suite;
|
||||
};
|
||||
|
||||
context.marionette = context.suite;
|
||||
|
||||
/**
|
||||
* global state modifies for marionette
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
// Setup global state manager for the marionette runtime.
|
||||
manager.desiredCapabilities = decode('DESIRED_CAPABILITIES');
|
||||
manager.verbose = decode('VERBOSE') === '1';
|
||||
manager.deviceType = decode('DEVICE_TYPE');
|
||||
context.marionette._manager = manager;
|
||||
context.marionette.client = manager.createHost.bind(manager);
|
||||
context.marionette.plugin = manager.addPlugin.bind(manager);
|
||||
|
||||
/**
|
||||
* Pending suite.
|
||||
*/
|
||||
context.suite.skip = function(title, fn) {
|
||||
var suite = Suite.create(suites[0], title);
|
||||
suite.pending = true;
|
||||
suites.unshift(suite);
|
||||
fn.call(suite);
|
||||
suites.shift();
|
||||
};
|
||||
|
||||
/**
|
||||
* Exclusive test-case.
|
||||
*/
|
||||
context.suite.only = function(title, fn) {
|
||||
var suite = context.suite(title, fn);
|
||||
mocha.grep(suite.fullTitle());
|
||||
};
|
||||
|
||||
/**
|
||||
* Describe a specification or test-case
|
||||
* with the given `title`, `options` list device to run on,
|
||||
* and callback `fn` acting as a thunk.
|
||||
*/
|
||||
context.test = function(title, options, fn) {
|
||||
// Second argument is optional, put default device if it doesn't exist.
|
||||
if (typeof options !== 'object') {
|
||||
if (typeof options === 'function') {
|
||||
fn = options;
|
||||
}
|
||||
|
||||
// Run only phone tests by default.
|
||||
options = { devices: ['phone'] };
|
||||
}
|
||||
|
||||
if (options &&
|
||||
options.devices &&
|
||||
options.devices.indexOf(manager.deviceType) === -1) {
|
||||
// Ignore test.
|
||||
return;
|
||||
}
|
||||
|
||||
var suite = suites[0];
|
||||
if (suite.pending) fn = null;
|
||||
var test = new MarionetteTest(title, manager, fn);
|
||||
test.file = file;
|
||||
suite.addTest(test);
|
||||
return test;
|
||||
};
|
||||
|
||||
/**
|
||||
* Exclusive test-case.
|
||||
*/
|
||||
context.test.only = function(title, fn) {
|
||||
var test = context.test(title, fn);
|
||||
var reString = '^' + escapeRe(test.fullTitle()) + '$';
|
||||
mocha.grep(new RegExp(reString));
|
||||
};
|
||||
|
||||
/**
|
||||
* Pending test case.
|
||||
*/
|
||||
context.test.skip = function(title) {
|
||||
context.test(title);
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
function decode(name) {
|
||||
var encoded = process.env[name];
|
||||
if (!encoded) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var result;
|
||||
try {
|
||||
result = JSON.parse(new Buffer(encoded, 'base64').toString());
|
||||
} catch (error) {
|
||||
console.error('Could not parse', name, encoded);
|
||||
result = null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
Loading…
Reference in a new issue