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
103
gaia/tests/jsmarionette/client/marionette-client/test/helper.js
Executable file
103
gaia/tests/jsmarionette/client/marionette-client/test/helper.js
Executable file
|
|
@ -0,0 +1,103 @@
|
|||
'use strict';
|
||||
var assert = require('chai').assert;
|
||||
|
||||
var helper = global.helper = {};
|
||||
global.assert = assert;
|
||||
|
||||
var deepEqual = assert.deepEqual.bind(assert);
|
||||
assert.deepEqual = function(one, other, msg) {
|
||||
// Hack so that we pass when comparing
|
||||
// { '0': foo } with [foo]
|
||||
deepEqual(argsToArrays(one), argsToArrays(other), msg);
|
||||
};
|
||||
|
||||
function argsToArrays(obj) {
|
||||
if (typeof obj !== 'object') {
|
||||
return obj;
|
||||
}
|
||||
|
||||
var proto;
|
||||
try {
|
||||
proto = Object.getPrototypeOf(obj);
|
||||
if (proto && Object.keys(proto).length) {
|
||||
// This is something fancy...
|
||||
return obj;
|
||||
}
|
||||
} catch (err) {
|
||||
// uh wtf
|
||||
return obj;
|
||||
}
|
||||
|
||||
if (!Array.isArray(obj) && isArrayLike(obj)) {
|
||||
obj = Array.prototype.slice.call(obj);
|
||||
}
|
||||
|
||||
for (var key in obj) {
|
||||
obj[key] = argsToArrays(obj[key]);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
function isArrayLike(obj) {
|
||||
return Object.keys(obj).every(function(value) {
|
||||
var representation = parseInt(value);
|
||||
return typeof representation === 'number' && !isNaN(representation);
|
||||
});
|
||||
}
|
||||
|
||||
helper.requireLib = function(path) {
|
||||
return require('../lib/' + path);
|
||||
};
|
||||
|
||||
helper.nsFind = function(obj, string) {
|
||||
var result = obj;
|
||||
var parts = string.split('.');
|
||||
var part;
|
||||
while ((part = parts.shift())) {
|
||||
if (!result[part]) {
|
||||
throw new Error('Cannot find ' + string + ' in object ');
|
||||
}
|
||||
|
||||
result = result[part];
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
helper.require = function(path, component, cb) {
|
||||
if (typeof(component) === 'function') {
|
||||
//new module pattern
|
||||
cb = component;
|
||||
component = path;
|
||||
|
||||
if (/^support/.test(path)) {
|
||||
path = '/test/' + path;
|
||||
} else {
|
||||
path = '/lib/marionette/' + path;
|
||||
}
|
||||
} else {
|
||||
//old system
|
||||
path = '/lib/' + path;
|
||||
}
|
||||
|
||||
cb(require('..' + path));
|
||||
};
|
||||
|
||||
helper.require('responder', function(obj) {});
|
||||
|
||||
helper.require('example-commands', function(obj) {
|
||||
global.exampleCmds = obj;
|
||||
});
|
||||
|
||||
helper.require('support/device-interaction', function(obj) {
|
||||
global.DeviceInteraction = obj;
|
||||
});
|
||||
|
||||
helper.require('support/socket', function(obj) {
|
||||
global.FakeSocket = obj;
|
||||
});
|
||||
|
||||
helper.require('support/mock-driver', function(obj) {
|
||||
global.MockDriver = obj;
|
||||
});
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/* global DeviceInteraction, exampleCmds, helper */
|
||||
'use strict';
|
||||
require('../helper');
|
||||
|
||||
suite('scope', function() {
|
||||
var client = marionette.client(),
|
||||
Actions,
|
||||
device,
|
||||
subject;
|
||||
|
||||
helper.require('actions', function(obj) {
|
||||
Actions = obj;
|
||||
});
|
||||
|
||||
device = new DeviceInteraction(exampleCmds, function() {
|
||||
return subject;
|
||||
});
|
||||
|
||||
suite('actions', function() {
|
||||
setup(function() {
|
||||
subject = new Actions(client);
|
||||
});
|
||||
|
||||
test('can move the page', function() {
|
||||
var bodyElement;
|
||||
|
||||
client.goUrl('http://yahoo.com');
|
||||
client.waitFor(function() {
|
||||
client.findElement('body', function(error, element) {
|
||||
if (error) {
|
||||
console.log('cannot find');
|
||||
return;
|
||||
}
|
||||
bodyElement = element;
|
||||
});
|
||||
|
||||
if (bodyElement !== undefined) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
subject.
|
||||
press(bodyElement, 100, 100).
|
||||
moveByOffset(0, 10).
|
||||
perform();
|
||||
|
||||
// TODO: Bug 965385 - Use `Actions#wait` in integration tests
|
||||
// Model this pause with an invocation of `Actions#wait` once "Bug 962645
|
||||
// - Action chains only handle one press->release chain" is resolved.
|
||||
client.executeAsyncScript(function() {
|
||||
setTimeout(marionetteScriptFinished, 50);
|
||||
});
|
||||
|
||||
subject.
|
||||
release().
|
||||
perform();
|
||||
|
||||
// TODO: Bug 965385 - Use `Actions#wait` in integration tests
|
||||
// Model this pause with an invocation of `Actions#wait` once "Bug 962645
|
||||
// - Action chains only handle one press->release chain" is resolved.
|
||||
client.executeAsyncScript(function() {
|
||||
setTimeout(marionetteScriptFinished, 50);
|
||||
});
|
||||
|
||||
subject.
|
||||
flick(bodyElement, 0, 0, 0, 200).
|
||||
perform();
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/* global marionette, setup */
|
||||
|
||||
'use strict';
|
||||
|
||||
var querystring = require('querystring');
|
||||
|
||||
suite('client methods', function() {
|
||||
var client = marionette.client();
|
||||
|
||||
setup(function() {
|
||||
client.goUrl('data:text/html,' + querystring.escape(
|
||||
'<div id="host"></div>'));
|
||||
client.executeScript(function() {
|
||||
var host = document.getElementById('host');
|
||||
var root = host.createShadowRoot();
|
||||
var button = document.createElement('button');
|
||||
button.id = 'button';
|
||||
button.textContent = 'Foo';
|
||||
root.appendChild(button);
|
||||
});
|
||||
});
|
||||
|
||||
test('#switchToShadowRoot', function() {
|
||||
var host = client.findElement('#host');
|
||||
client.switchToShadowRoot(host);
|
||||
var button = client.findElement('#button');
|
||||
button.click();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
/* global assert */
|
||||
'use strict';
|
||||
require('../../helper');
|
||||
|
||||
suite('drivers/tcp-sync', function() {
|
||||
var client = marionette.client();
|
||||
|
||||
test('can execute sync commands', function() {
|
||||
client.goUrl('http://yahoo.com');
|
||||
client.goUrl('http://google.com');
|
||||
client.goUrl('http://yahoo.com');
|
||||
var location = client.executeScript(function() {
|
||||
return window.location.href;
|
||||
});
|
||||
assert.ok(location.indexOf('yahoo.com') !== -1);
|
||||
});
|
||||
|
||||
});
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/* global assert */
|
||||
'use strict';
|
||||
var querystring = require('querystring');
|
||||
|
||||
require('../helper');
|
||||
|
||||
suite('element methods', function() {
|
||||
var client = marionette.client();
|
||||
|
||||
setup(function() {
|
||||
client.goUrl('data:text/html,' + querystring.escape(
|
||||
'<div id="el" style="width: 50px; height: 50px">cheese</div>'));
|
||||
});
|
||||
|
||||
test('#displayed', function() {
|
||||
var element = client.findElement('html');
|
||||
assert.strictEqual(element.displayed(), true);
|
||||
});
|
||||
|
||||
test('#scriptWith', function() {
|
||||
var element = client.findElement('html');
|
||||
var evaled = element.scriptWith(function(el, arg) {
|
||||
return el.tagName + ' ' + arg;
|
||||
}, ['FTW!']);
|
||||
|
||||
assert.equal(evaled, 'HTML FTW!');
|
||||
});
|
||||
|
||||
test('#findElement', function() {
|
||||
var el = client.findElement('html');
|
||||
assert.instanceOf(el, client.Element);
|
||||
});
|
||||
|
||||
test('#findElements', function() {
|
||||
var els = client.findElements('html');
|
||||
assert.isArray(els);
|
||||
els.forEach(function(el) { assert.instanceOf(el, client.Element); });
|
||||
});
|
||||
|
||||
test('#findElement - missing', function() {
|
||||
var err;
|
||||
try {
|
||||
client.findElement('#fooobaramazingmissing');
|
||||
} catch (e) {
|
||||
err = e;
|
||||
}
|
||||
|
||||
if (!err) throw new Error('missing element did not trigger an error');
|
||||
assert.equal(err.type, 'NoSuchElement');
|
||||
});
|
||||
|
||||
test('#cssProperty', function() {
|
||||
var body = client.findElement('body');
|
||||
var font = body.cssProperty('font-size');
|
||||
assert.ok(font, 'returns a css property value');
|
||||
});
|
||||
|
||||
test('#size', function () {
|
||||
var element = client.findElement('#el');
|
||||
var size = element.size();
|
||||
assert.property(size, 'width');
|
||||
assert.property(size, 'height');
|
||||
assert.equal(size.width, 50);
|
||||
assert.equal(size.height, 50);
|
||||
});
|
||||
|
||||
test('#location', function () {
|
||||
var element = client.findElement('#el');
|
||||
var location = element.location();
|
||||
assert.property(location, 'x');
|
||||
assert.property(location, 'y');
|
||||
});
|
||||
|
||||
test('#rect', function () {
|
||||
var element = client.findElement('#el');
|
||||
var rect = element.rect();
|
||||
assert.property(rect, 'x');
|
||||
assert.property(rect, 'y');
|
||||
assert.property(rect, 'width');
|
||||
assert.property(rect, 'height');
|
||||
assert.equal(rect.width, 50);
|
||||
assert.equal(rect.height, 50);
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/* global assert, helper */
|
||||
'use strict';
|
||||
require('../helper');
|
||||
|
||||
suite('error handling', function() {
|
||||
var MarionetteError;
|
||||
helper.require('error', function(obj) {
|
||||
MarionetteError = obj;
|
||||
});
|
||||
|
||||
var client = marionette.client();
|
||||
|
||||
test('catch error', function() {
|
||||
try {
|
||||
client.executeScript(function() {
|
||||
throw new Error('e');
|
||||
});
|
||||
} catch (e) {
|
||||
e.client.screenshot();
|
||||
}
|
||||
});
|
||||
|
||||
test('throws no such element error', function() {
|
||||
try {
|
||||
client.findElement('cheese');
|
||||
assert.fail('expected no such element error to be thrown');
|
||||
} catch (e) {
|
||||
assert.include(e.toString(), 'NoSuchElement');
|
||||
assert.property(e, 'type');
|
||||
assert.equal(e.type, 'NoSuchElement');
|
||||
}
|
||||
});
|
||||
|
||||
test('throws javascript error', function() {
|
||||
try {
|
||||
client.executeScript(function() { throw Error('rochefort'); });
|
||||
} catch (e) {
|
||||
assert.include(e.toString(), 'JavaScriptError');
|
||||
assert.property(e, 'type');
|
||||
assert.equal(e.type, 'JavaScriptError');
|
||||
}
|
||||
});
|
||||
});
|
||||
18
gaia/tests/jsmarionette/client/marionette-client/test/integration/helper.js
Executable file
18
gaia/tests/jsmarionette/client/marionette-client/test/integration/helper.js
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
'use strict';
|
||||
module.exports.skipInitialError = function (client) {
|
||||
setup(function(done) {
|
||||
client.executeAsyncScript(function() {
|
||||
setTimeout(marionetteScriptFinished, 10);
|
||||
}, function(err) {
|
||||
// hacked work around for gaia exception at startup.
|
||||
if (
|
||||
err &&
|
||||
err.message &&
|
||||
err.message.indexOf('Expected IccHelper') !== -1
|
||||
) {
|
||||
return done();
|
||||
}
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/* global assert */
|
||||
'use strict';
|
||||
require('../helper');
|
||||
|
||||
suite('scope', function() {
|
||||
var client = marionette.client(),
|
||||
helper = require('./helper'),
|
||||
timeoutA,
|
||||
timeoutB;
|
||||
|
||||
helper.skipInitialError(client);
|
||||
|
||||
setup(function() {
|
||||
timeoutA = client.scope({ scriptTimeout: 1000 });
|
||||
timeoutB = client.scope({ scriptTimeout: 250 });
|
||||
});
|
||||
|
||||
test('should handle scope switching', function() {
|
||||
function sleep() {
|
||||
setTimeout(function() {
|
||||
marionetteScriptFinished();
|
||||
}, 600);
|
||||
}
|
||||
|
||||
timeoutA.executeAsyncScript(sleep);
|
||||
|
||||
var err;
|
||||
try {
|
||||
timeoutB.executeAsyncScript(sleep);
|
||||
} catch (e) {
|
||||
err = e;
|
||||
}
|
||||
// sleep throws error on shorter timeout
|
||||
assert.ok(err);
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
/* global assert */
|
||||
'use strict';
|
||||
require('../helper');
|
||||
|
||||
suite('scope', function() {
|
||||
var client = marionette.client(),
|
||||
helper = require('./helper');
|
||||
|
||||
helper.skipInitialError(client);
|
||||
|
||||
suite('sync waitFor', function() {
|
||||
test('should not yield in sync code', function() {
|
||||
var tries = 0;
|
||||
var succeed = 10;
|
||||
|
||||
// short signature
|
||||
client.waitFor(function() {
|
||||
return (++tries === succeed);
|
||||
});
|
||||
|
||||
assert.strictEqual(tries, 10);
|
||||
});
|
||||
|
||||
test('should eventually timeout', function() {
|
||||
var timeout = 450;
|
||||
var start = Date.now();
|
||||
var err;
|
||||
try {
|
||||
client.waitFor(function() {
|
||||
return false;
|
||||
}, { timeout: timeout });
|
||||
} catch (e) {
|
||||
err = e;
|
||||
}
|
||||
|
||||
assert.ok(err);
|
||||
assert.operator(Date.now() - start, '>=', timeout);
|
||||
});
|
||||
|
||||
test('should do the mocha sync', function() {
|
||||
var tries = 0, success = 3;
|
||||
client.waitFor(function fn(waitForComplete) {
|
||||
tries += 1;
|
||||
if (tries === success) {
|
||||
waitForComplete(null, true);
|
||||
}
|
||||
|
||||
setTimeout(fn.bind(this, waitForComplete), 10);
|
||||
});
|
||||
|
||||
assert.strictEqual(tries, success);
|
||||
});
|
||||
|
||||
test('should do the mocha fail sync', function(done) {
|
||||
var err = new Error('failure!');
|
||||
try {
|
||||
client.waitFor(function(waitForComplete) {
|
||||
waitForComplete(err);
|
||||
});
|
||||
} catch (e) {
|
||||
assert.strictEqual(e, err);
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
suite('callback style wait for calls', function() {
|
||||
test('should throw an error when given', function() {
|
||||
var err = new Error('failure!');
|
||||
var isSync = false;
|
||||
try {
|
||||
client.waitFor(function(waitForComplete) {
|
||||
waitForComplete(err);
|
||||
}, function(e) {
|
||||
assert.strictEqual(e, err);
|
||||
isSync = true;
|
||||
});
|
||||
} catch(e) {
|
||||
assert.equal(e, err);
|
||||
}
|
||||
assert.ok(isSync, 'callback style is sync');
|
||||
});
|
||||
|
||||
test('should fire when async condition is met', function() {
|
||||
var tries = 0;
|
||||
var success = 3;
|
||||
client.waitFor(function() {
|
||||
return ++tries === success;
|
||||
}, function() {
|
||||
assert.strictEqual(tries, 3);
|
||||
});
|
||||
assert.equal(tries, 3, 'is sync');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1 @@
|
|||
--profile-base profile.js
|
||||
225
gaia/tests/jsmarionette/client/marionette-client/test/marionette/actions-test.js
Executable file
225
gaia/tests/jsmarionette/client/marionette-client/test/marionette/actions-test.js
Executable file
|
|
@ -0,0 +1,225 @@
|
|||
/* global DeviceInteraction, MockDriver, exampleCmds, assert, helper */
|
||||
'use strict';
|
||||
suite('marionette/actions', function() {
|
||||
var driver, subject, client, device,
|
||||
Actions, Client;
|
||||
|
||||
helper.require('actions', function(obj) {
|
||||
Actions = obj;
|
||||
});
|
||||
|
||||
helper.require('client', function(obj) {
|
||||
Client = obj;
|
||||
});
|
||||
|
||||
device = new DeviceInteraction(exampleCmds, function() {
|
||||
return subject;
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
driver = new MockDriver();
|
||||
client = new Client(driver);
|
||||
subject = new Actions(client);
|
||||
});
|
||||
|
||||
suite('initialization', function() {
|
||||
test('should set client', function() {
|
||||
assert.strictEqual(subject.client, client);
|
||||
});
|
||||
});
|
||||
|
||||
suite('.press', function() {
|
||||
var element, x, y;
|
||||
|
||||
setup(function() {
|
||||
element = { id: '{fake-uuid-root}' };
|
||||
x = 0;
|
||||
y = 0;
|
||||
subject.press(element, x, y);
|
||||
});
|
||||
|
||||
test('should have a press action in the chain', function() {
|
||||
var pressAction = [['press', element.id, x, y]];
|
||||
assert.deepEqual(subject.actionChain, pressAction);
|
||||
});
|
||||
});
|
||||
|
||||
suite('.release', function() {
|
||||
setup(function() {
|
||||
subject.release();
|
||||
});
|
||||
|
||||
test('should have a release action in the chain', function() {
|
||||
var releaseAction = [['release']];
|
||||
assert.deepEqual(subject.actionChain, releaseAction);
|
||||
});
|
||||
});
|
||||
|
||||
suite('.move', function() {
|
||||
var element;
|
||||
|
||||
setup(function() {
|
||||
element = { id: '{fake-uuid-root}' };
|
||||
subject.move(element);
|
||||
});
|
||||
|
||||
test('should have a move action in the chain', function() {
|
||||
var moveAction = [['move', element.id]];
|
||||
assert.deepEqual(subject.actionChain, moveAction);
|
||||
});
|
||||
});
|
||||
|
||||
suite('.moveByOffset', function() {
|
||||
var x, y;
|
||||
|
||||
setup(function() {
|
||||
x = 1;
|
||||
y = 1;
|
||||
subject.moveByOffset(x, y);
|
||||
});
|
||||
|
||||
test('should have a move by offset action in the chain', function() {
|
||||
var moveByOffsetAction = [['moveByOffset', x, y]];
|
||||
assert.deepEqual(subject.actionChain, moveByOffsetAction);
|
||||
});
|
||||
});
|
||||
|
||||
suite('.wait', function() {
|
||||
var time;
|
||||
|
||||
setup(function() {
|
||||
time = 1;
|
||||
subject.wait(time);
|
||||
});
|
||||
|
||||
test('should have a wait action in the chain', function() {
|
||||
var waitAction = [['wait', time]];
|
||||
assert.deepEqual(subject.actionChain, waitAction);
|
||||
});
|
||||
});
|
||||
|
||||
suite('.cancel', function() {
|
||||
setup(function() {
|
||||
subject.cancel();
|
||||
});
|
||||
|
||||
test('should have a cancel action in the chain', function() {
|
||||
var cancelAction = [['cancel']];
|
||||
assert.deepEqual(subject.actionChain, cancelAction);
|
||||
});
|
||||
});
|
||||
|
||||
suite('.tap', function() {
|
||||
var element, x, y;
|
||||
|
||||
setup(function() {
|
||||
element = { id: '{fake-uuid-root}' };
|
||||
x = 0;
|
||||
y = 0;
|
||||
subject.tap(element, x, y);
|
||||
});
|
||||
|
||||
test('should have a tap action in the chain', function() {
|
||||
var tapAction = [
|
||||
['press', element.id, x, y],
|
||||
['release']
|
||||
];
|
||||
|
||||
assert.deepEqual(subject.actionChain, tapAction);
|
||||
});
|
||||
});
|
||||
|
||||
suite('.doubleTap', function() {
|
||||
var element, x, y;
|
||||
|
||||
setup(function() {
|
||||
element = { id: '{fake-uuid-root}' };
|
||||
x = 0;
|
||||
y = 0;
|
||||
subject.doubleTap(element, x, y);
|
||||
});
|
||||
|
||||
test('should have a double tap action in the chain', function() {
|
||||
var doubleTapAction = [
|
||||
['press', element.id, x, y],
|
||||
['release'],
|
||||
['press', element.id, x, y],
|
||||
['release']
|
||||
];
|
||||
|
||||
assert.deepEqual(subject.actionChain, doubleTapAction);
|
||||
});
|
||||
});
|
||||
|
||||
suite('.flick', function() {
|
||||
var element, x1, y1, x2, y2;
|
||||
|
||||
setup(function() {
|
||||
element = { id: '{fake-uuid-root}' };
|
||||
x1 = 0;
|
||||
y1 = 0;
|
||||
x2 = 100;
|
||||
y2 = 100;
|
||||
});
|
||||
|
||||
function shouldHaveFlickAction() {
|
||||
var firstAction = ['press', element.id, x1, y1];
|
||||
var lastAction = ['release'];
|
||||
var lastActionIndex = subject.actionChain.length - 1;
|
||||
|
||||
assert.deepEqual(subject.actionChain[0], firstAction);
|
||||
for (var i = 1; i < lastActionIndex; i += 2) {
|
||||
assert.strictEqual(subject.actionChain[i][0], 'moveByOffset');
|
||||
assert.strictEqual(subject.actionChain[i + 1][0], 'wait');
|
||||
}
|
||||
assert.deepEqual(subject.actionChain[lastActionIndex], lastAction);
|
||||
}
|
||||
|
||||
test('should have a flick action in the chain', function() {
|
||||
subject.flick(element, x1, y1, x2, y2);
|
||||
shouldHaveFlickAction();
|
||||
});
|
||||
|
||||
test('should have a flick action in the chain ' +
|
||||
'when the duration param is 300', function() {
|
||||
var duration = 300;
|
||||
subject.flick(element, x1, y1, x2, y2, duration);
|
||||
shouldHaveFlickAction();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
suite('.longPress', function() {
|
||||
var element, time;
|
||||
|
||||
setup(function() {
|
||||
element = { id: '{fake-uuid-root}' };
|
||||
time = 1;
|
||||
subject.longPress(element, time);
|
||||
});
|
||||
|
||||
test('should have a long press action in the chain', function() {
|
||||
var longPressAction = [
|
||||
['press', element.id],
|
||||
['wait', time],
|
||||
['release']
|
||||
];
|
||||
|
||||
assert.deepEqual(subject.actionChain, longPressAction);
|
||||
});
|
||||
});
|
||||
|
||||
suite('.perform', function() {
|
||||
device.
|
||||
issues('perform').
|
||||
shouldSend({
|
||||
name: 'actionChain',
|
||||
parameters: {
|
||||
chain: [],
|
||||
nextId: null
|
||||
}
|
||||
}).
|
||||
serverResponds('value').
|
||||
callbackReceives('value');
|
||||
});
|
||||
});
|
||||
1552
gaia/tests/jsmarionette/client/marionette-client/test/marionette/client-test.js
Executable file
1552
gaia/tests/jsmarionette/client/marionette-client/test/marionette/client-test.js
Executable file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,213 @@
|
|||
/* global assert, helper */
|
||||
'use strict';
|
||||
suite('marionette/command-stream', function() {
|
||||
|
||||
var subject, socket,
|
||||
Responder,
|
||||
CommandStream;
|
||||
|
||||
helper.require('responder', function(obj) {
|
||||
Responder = obj;
|
||||
});
|
||||
|
||||
helper.require('command-stream', function(obj) {
|
||||
CommandStream = obj;
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
socket = new Responder();
|
||||
subject = new CommandStream(socket);
|
||||
});
|
||||
|
||||
suite('initialization', function() {
|
||||
test('should save socket', function() {
|
||||
assert.strictEqual(subject.socket, socket);
|
||||
});
|
||||
|
||||
test('should be an event emitter', function() {
|
||||
assert.instanceOf(subject.on, Function);
|
||||
});
|
||||
});
|
||||
|
||||
suite('socket event: data', function() {
|
||||
|
||||
var calledWith, data;
|
||||
|
||||
setup(function() {
|
||||
data = {};
|
||||
|
||||
subject.on('command', function() {
|
||||
calledWith = Array.prototype.slice.call(arguments);
|
||||
});
|
||||
|
||||
subject.socket.emit('data', new Buffer(subject.stringify(data)));
|
||||
});
|
||||
|
||||
test('should call add', function() {
|
||||
assert.deepEqual(calledWith, [data]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
suite('.stringify', function() {
|
||||
var command = {works: true},
|
||||
result;
|
||||
|
||||
function shouldStringify() {
|
||||
test('should return json (n:json)', function() {
|
||||
var string = JSON.stringify(command);
|
||||
assert.strictEqual(result, String(string.length) + ':' + string);
|
||||
});
|
||||
}
|
||||
|
||||
suite('when given an object', function() {
|
||||
setup(function() {
|
||||
result = subject.stringify(command);
|
||||
});
|
||||
|
||||
shouldStringify();
|
||||
});
|
||||
|
||||
suite('when given a string', function() {
|
||||
setup(function() {
|
||||
command = 'some random string';
|
||||
result = subject.stringify(command);
|
||||
});
|
||||
|
||||
shouldStringify();
|
||||
});
|
||||
});
|
||||
|
||||
suite('.send', function() {
|
||||
|
||||
var calledWith = [], data = {uniq: true};
|
||||
|
||||
function sendsToSocket(fnName) {
|
||||
setup(function() {
|
||||
subject.socket[fnName] = function() {
|
||||
calledWith = Array.prototype.slice.call(arguments);
|
||||
};
|
||||
subject.send(data);
|
||||
});
|
||||
|
||||
test('should write to socket', function() {
|
||||
assert.strictEqual(calledWith[0], subject.stringify(data));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
suite('when using socket.send', function() {
|
||||
sendsToSocket('send');
|
||||
});
|
||||
|
||||
suite('when using socket.write', function() {
|
||||
sendsToSocket('write');
|
||||
|
||||
test('should write in utf8', function() {
|
||||
assert.strictEqual(calledWith[1], 'utf8');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
suite('.add', function() {
|
||||
|
||||
var commands = [],
|
||||
chunks = {},
|
||||
commandList = {
|
||||
success: {'from': 'someX'},
|
||||
fail: {'from': 'zya'}
|
||||
};
|
||||
|
||||
|
||||
function add(string, log) {
|
||||
var buffer = new Buffer(string);
|
||||
subject.add(buffer);
|
||||
}
|
||||
|
||||
function emitsCommand(name, index) {
|
||||
|
||||
index = index || 0;
|
||||
name = name || 'success';
|
||||
|
||||
test('should emit ' + name + ' command at #' + index + '', function() {
|
||||
assert.deepEqual(commands[index], commandList[name]);
|
||||
});
|
||||
}
|
||||
|
||||
function hasCommands(number) {
|
||||
test('should have ' + String(number) + ' of commands', function() {
|
||||
assert.strictEqual(commands.length, number);
|
||||
});
|
||||
}
|
||||
|
||||
setup(function() {
|
||||
commands = [];
|
||||
Object.keys(commandList).forEach(function(key) {
|
||||
chunks[key] = subject.stringify(commandList[key]);
|
||||
});
|
||||
|
||||
subject.on(subject.commandEvent, function(response) {
|
||||
commands.push(response);
|
||||
});
|
||||
});
|
||||
|
||||
suite('when given the entire command', function() {
|
||||
setup(function() {
|
||||
add(chunks.success);
|
||||
});
|
||||
|
||||
emitsCommand('success', 0);
|
||||
hasCommands(1);
|
||||
});
|
||||
|
||||
suite('when given single command in multiple chunks', function() {
|
||||
|
||||
setup(function() {
|
||||
add(chunks.success.slice(0, 1));
|
||||
add(chunks.success.slice(1, 2));
|
||||
add(chunks.success.slice(2));
|
||||
});
|
||||
|
||||
emitsCommand('success', 0);
|
||||
hasCommands(1);
|
||||
|
||||
});
|
||||
|
||||
suite('when given multiple commands in two chunks', function() {
|
||||
setup(function() {
|
||||
var chunk = chunks.success + chunks.fail,
|
||||
piece1,
|
||||
piece2,
|
||||
half = Math.floor(chunk.length / 2);
|
||||
|
||||
piece1 = chunk.slice(0, half);
|
||||
piece2 = chunk.slice(half);
|
||||
//sanity check
|
||||
assert.strictEqual(piece1 + piece2, chunk);
|
||||
|
||||
add(piece1);
|
||||
add(piece2);
|
||||
});
|
||||
|
||||
emitsCommand('success', 0);
|
||||
emitsCommand('fail', 1);
|
||||
hasCommands(2);
|
||||
|
||||
});
|
||||
|
||||
suite('when given both commands in one chunk', function() {
|
||||
setup(function() {
|
||||
add(chunks.fail + chunks.success);
|
||||
});
|
||||
|
||||
emitsCommand('fail', 0);
|
||||
emitsCommand('success', 1);
|
||||
hasCommands(2);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
|
@ -0,0 +1,358 @@
|
|||
/* global assert, exampleCmds, helper */
|
||||
'use strict';
|
||||
suite('marionette/drivers/abstract', function() {
|
||||
var subject,
|
||||
Backend,
|
||||
sent = [];
|
||||
|
||||
helper.require('drivers/abstract', function(obj) {
|
||||
Backend = obj;
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
subject = new Backend();
|
||||
|
||||
sent = [];
|
||||
|
||||
subject._sendCommand = function() {
|
||||
sent.push(arguments);
|
||||
};
|
||||
});
|
||||
|
||||
suite('initialization', function() {
|
||||
|
||||
test('should setup ._sendQueue', function() {
|
||||
assert.deepEqual(subject._sendQueue, []);
|
||||
});
|
||||
|
||||
test('should not be ready', function() {
|
||||
assert.strictEqual(subject.ready, false);
|
||||
});
|
||||
|
||||
test('should setup ._responseQueue', function() {
|
||||
assert.instanceOf(subject._responseQueue, Array);
|
||||
});
|
||||
|
||||
test('should have timeout set to 10000', function() {
|
||||
assert.strictEqual(subject.timeout, 10000);
|
||||
});
|
||||
|
||||
test('should be _waiting', function() {
|
||||
assert.strictEqual(subject._waiting, true);
|
||||
});
|
||||
});
|
||||
|
||||
suite('event: device response', function() {
|
||||
|
||||
var callback,
|
||||
callbackResponse,
|
||||
response;
|
||||
|
||||
setup(function() {
|
||||
callbackResponse = null;
|
||||
response = {
|
||||
id: 10,
|
||||
response: {
|
||||
from: 'marionette',
|
||||
value: 'hit'
|
||||
}
|
||||
};
|
||||
|
||||
//emulate connect
|
||||
subject.connectionId = 10;
|
||||
subject.ready = true;
|
||||
subject._waiting = false;
|
||||
|
||||
callback = function() {
|
||||
callbackResponse = arguments;
|
||||
};
|
||||
|
||||
subject.send(exampleCmds.newSession(), callback);
|
||||
assert.strictEqual(subject._waiting, true);
|
||||
});
|
||||
|
||||
suite('when response is for different device', function() {
|
||||
setup(function() {
|
||||
subject.connectionId = 101;
|
||||
subject._onDeviceResponse(response);
|
||||
});
|
||||
|
||||
test('should trigger response callbacks', function() {
|
||||
assert.strictEqual(callbackResponse, null);
|
||||
});
|
||||
});
|
||||
|
||||
suite('when response is for device id', function() {
|
||||
var calledNext;
|
||||
|
||||
setup(function() {
|
||||
calledNext = false;
|
||||
subject._nextCommand = function() {
|
||||
calledNext = true;
|
||||
Backend.prototype._nextCommand.apply(this, arguments);
|
||||
};
|
||||
subject._onDeviceResponse(response);
|
||||
});
|
||||
|
||||
test('should trigger response callbacks', function() {
|
||||
assert.deepEqual(callbackResponse[0], response.response);
|
||||
});
|
||||
|
||||
test('should clear response queue', function() {
|
||||
assert.strictEqual(subject._responseQueue.length, 0);
|
||||
});
|
||||
|
||||
test('should not be waiting', function() {
|
||||
assert.strictEqual(subject._waiting, false);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
suite('.close', function() {
|
||||
|
||||
var calledClose;
|
||||
|
||||
setup(function() {
|
||||
calledClose = false;
|
||||
subject.ready = true;
|
||||
subject._responseQueue = [function() {}];
|
||||
subject._close = function() {
|
||||
calledClose = true;
|
||||
};
|
||||
subject.close();
|
||||
});
|
||||
|
||||
test('should call _close', function() {
|
||||
assert.strictEqual(calledClose, true);
|
||||
});
|
||||
|
||||
test('should not be ready', function() {
|
||||
assert.strictEqual(subject.ready, false);
|
||||
});
|
||||
|
||||
test('should clean up _responseQueue', function() {
|
||||
assert.strictEqual(subject._responseQueue.length, 0);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
suite('.connect with protocol 1', function() {
|
||||
var cmd, calledChild;
|
||||
|
||||
setup(function(done) {
|
||||
cmd = exampleCmds.connectProto1();
|
||||
calledChild = false;
|
||||
|
||||
subject._connect = function() {
|
||||
subject.connectionId = 10;
|
||||
calledChild = true;
|
||||
//this will cause connect to callback to fire
|
||||
subject._onDeviceResponse({
|
||||
id: 10,
|
||||
response: cmd
|
||||
});
|
||||
};
|
||||
|
||||
assert.strictEqual(subject._waiting, true);
|
||||
|
||||
subject.connect(function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('should set .marionetteProtocol', function() {
|
||||
assert.property(subject, 'marionetteProtocol');
|
||||
assert.strictEqual(subject.marionetteProtocol, 1 /* fallback */);
|
||||
});
|
||||
|
||||
test('should set .applicationType', function() {
|
||||
assert.property(subject, 'applicationType');
|
||||
assert.strictEqual(subject.applicationType, cmd.applicationType);
|
||||
});
|
||||
|
||||
test('should set .traits', function() {
|
||||
assert.property(subject, 'traits');
|
||||
assert.strictEqual(subject.traits, cmd.traits);
|
||||
});
|
||||
|
||||
test('should call _connect', function() {
|
||||
assert.strictEqual(calledChild, true);
|
||||
});
|
||||
|
||||
test('should not be waiting', function() {
|
||||
assert.strictEqual(subject._waiting, false);
|
||||
});
|
||||
|
||||
test('should be ready', function() {
|
||||
assert.strictEqual(subject.ready, true);
|
||||
});
|
||||
});
|
||||
|
||||
suite('.connect with protocol 2', function() {
|
||||
var cmd, calledChild;
|
||||
|
||||
setup(function(done) {
|
||||
cmd = exampleCmds.connectProto2();
|
||||
calledChild = false;
|
||||
|
||||
subject._connect = function() {
|
||||
subject.connectionId = 10;
|
||||
calledChild = true;
|
||||
//this will cause connect to callback to fire
|
||||
subject._onDeviceResponse({
|
||||
id: 10,
|
||||
response: cmd
|
||||
});
|
||||
};
|
||||
|
||||
assert.strictEqual(subject._waiting, true);
|
||||
|
||||
subject.connect(function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('should set .marionetteProtocol', function() {
|
||||
assert.property(subject, 'marionetteProtocol');
|
||||
assert.strictEqual(subject.marionetteProtocol, cmd.marionetteProtocol);
|
||||
});
|
||||
|
||||
test('should set .applicationType', function() {
|
||||
assert.property(subject, 'applicationType');
|
||||
assert.strictEqual(subject.applicationType, cmd.applicationType);
|
||||
});
|
||||
|
||||
test('should call _connect', function() {
|
||||
assert.strictEqual(calledChild, true);
|
||||
});
|
||||
|
||||
test('should not be waiting', function() {
|
||||
assert.strictEqual(subject._waiting, false);
|
||||
});
|
||||
|
||||
test('should be ready', function() {
|
||||
assert.strictEqual(subject.ready, true);
|
||||
});
|
||||
});
|
||||
|
||||
suite('._nextCommand', function() {
|
||||
var cmd1, cmd2;
|
||||
|
||||
setup(function() {
|
||||
cmd1 = exampleCmds.newSession();
|
||||
cmd2 = exampleCmds.newSession({isOther: true});
|
||||
subject._sendQueue[0] = cmd1;
|
||||
subject._sendQueue[1] = cmd2;
|
||||
});
|
||||
|
||||
suite('when waiting', function() {
|
||||
setup(function() {
|
||||
subject._waiting = true;
|
||||
subject._nextCommand();
|
||||
});
|
||||
|
||||
test('should not send command to server', function() {
|
||||
assert.strictEqual(sent.length, 0);
|
||||
});
|
||||
});
|
||||
|
||||
suite('when not waiting', function() {
|
||||
setup(function() {
|
||||
subject._waiting = false;
|
||||
subject._nextCommand();
|
||||
});
|
||||
|
||||
test('should be waiting', function() {
|
||||
assert.strictEqual(subject._waiting, true);
|
||||
});
|
||||
|
||||
test('should send command to server', function() {
|
||||
assert.deepEqual(sent[0][0], cmd1);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
suite('when there are no comamnds and we are not waiting', function() {
|
||||
setup(function() {
|
||||
//emulate connect
|
||||
subject._waiting = false;
|
||||
|
||||
subject._responseQueue = [];
|
||||
subject._sendQueue = [];
|
||||
subject._nextCommand();
|
||||
});
|
||||
|
||||
test('should not be waiting', function() {
|
||||
assert.strictEqual(subject._waiting, false);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
suite('.send', function() {
|
||||
var cmd, cb = function() {};
|
||||
|
||||
setup(function() {
|
||||
cmd = exampleCmds.newSession();
|
||||
});
|
||||
|
||||
suite('when device is not ready', function() {
|
||||
test('should throw an error', function() {
|
||||
assert.throws(function() {
|
||||
subject.send({ type: 'newSession' });
|
||||
}, /not ready/);
|
||||
});
|
||||
});
|
||||
|
||||
suite('when not waiting for a response', function() {
|
||||
setup(function() {
|
||||
//emulate connect
|
||||
subject.ready = true;
|
||||
subject._waiting = false;
|
||||
|
||||
subject.send(cmd, cb);
|
||||
});
|
||||
|
||||
test('should send command', function() {
|
||||
assert.strictEqual(sent.length, 1);
|
||||
});
|
||||
|
||||
test('should be waiting', function() {
|
||||
assert.strictEqual(subject._waiting, true);
|
||||
});
|
||||
});
|
||||
|
||||
suite('when waiting for a response', function() {
|
||||
|
||||
var nextCalled;
|
||||
|
||||
setup(function() {
|
||||
subject.ready = true;
|
||||
subject._waiting = true;
|
||||
|
||||
nextCalled = false;
|
||||
subject._nextCommand = function() {
|
||||
nextCalled = true;
|
||||
};
|
||||
|
||||
subject.send(cmd, cb);
|
||||
});
|
||||
|
||||
test('should call next', function() {
|
||||
assert.strictEqual(nextCalled, true);
|
||||
});
|
||||
|
||||
test('should add send command to queue', function() {
|
||||
assert.strictEqual(subject._sendQueue[0], cmd);
|
||||
});
|
||||
|
||||
test('should add calback to response queue', function() {
|
||||
assert.strictEqual(subject._responseQueue[0], cb);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
'use strict';
|
||||
var debug = require('debug')('marionette:tcp-sync-test-server');
|
||||
var net = require('net');
|
||||
|
||||
var response = '54:{"applicationType": "gecko", "marionetteProtocol": 2}';
|
||||
|
||||
var server = net.createServer(function(connection) { //'connection' listener
|
||||
debug('server connected');
|
||||
connection.on('end', function() {
|
||||
debug('server disconnected');
|
||||
});
|
||||
connection.on('error', function(e) {
|
||||
debug('error', e);
|
||||
});
|
||||
connection.write(response);
|
||||
connection.pipe(connection);
|
||||
});
|
||||
|
||||
|
||||
function runServer(port) {
|
||||
server.listen(port, function() { //'listening' listener
|
||||
debug('server bound');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (require.main === module) {
|
||||
try {
|
||||
runServer(1234);
|
||||
}
|
||||
catch(e) {
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
'use strict';
|
||||
var fork = require('child_process').fork;
|
||||
|
||||
suite('marionette/drivers/tcp-sync', function() {
|
||||
|
||||
var child = null;
|
||||
|
||||
teardown(function() {
|
||||
if (child) {
|
||||
child.kill();
|
||||
child = null;
|
||||
}
|
||||
});
|
||||
|
||||
test('can wait for marionette socket', function(done) {
|
||||
|
||||
this.timeout(5000);
|
||||
|
||||
var TcpSync =
|
||||
require(__dirname + '/../../../lib/marionette/drivers/tcp-sync');
|
||||
var tcpSync = new TcpSync({port: 1234, host: 'localhost'});
|
||||
|
||||
tcpSync.waitForSocket( {timeout: 3000} , function() {
|
||||
done();
|
||||
});
|
||||
|
||||
setTimeout(function () {
|
||||
fork(__dirname + '/tcp-sync-test-server.js');
|
||||
}, 1000);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
/* global assert, helper */
|
||||
'use strict';
|
||||
suite('marionette/drivers/tcp', function() {
|
||||
|
||||
if (typeof(window) !== 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
var Abstract,
|
||||
Driver = require('../../../lib/marionette/drivers/tcp'),
|
||||
FakeSocket = require('../../support/socket');
|
||||
|
||||
helper.require(
|
||||
'marionette/drivers/abstract',
|
||||
'Marionette.Drivers.Abstract', function(obj) {
|
||||
Abstract = obj;
|
||||
}
|
||||
);
|
||||
|
||||
function issueFirstResponse() {
|
||||
subject._onDeviceResponse({
|
||||
id: subject.connectionId,
|
||||
response: {}
|
||||
});
|
||||
}
|
||||
|
||||
var subject,
|
||||
RealSocket,
|
||||
sockets = [];
|
||||
|
||||
var socketRetry = require('socket-retry-connect');
|
||||
var realWaitForSocket;
|
||||
|
||||
setup(function() {
|
||||
realWaitForSocket = socketRetry.waitForSocket;
|
||||
|
||||
RealSocket = Driver.Socket;
|
||||
Driver.Socket = FakeSocket;
|
||||
FakeSocket.sockets = sockets;
|
||||
|
||||
socketRetry.waitForSocket = function(options, callback) {
|
||||
var socket = new FakeSocket(options.port);
|
||||
callback(null, socket);
|
||||
};
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
socketRetry.waitForSocket = realWaitForSocket;
|
||||
Driver.Socket = RealSocket;
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
subject = new Driver();
|
||||
});
|
||||
|
||||
test('should accept port and host', function() {
|
||||
var subject = new Driver({
|
||||
port: 8888,
|
||||
host: 'foobar'
|
||||
});
|
||||
|
||||
assert.strictEqual(subject.port, 8888);
|
||||
assert.strictEqual(subject.host, 'foobar');
|
||||
});
|
||||
|
||||
suite('._sendCommand', function() {
|
||||
var sent = [];
|
||||
|
||||
setup(function(done) {
|
||||
subject.connect(function() {
|
||||
subject.client.send = function() {
|
||||
sent.push(arguments);
|
||||
};
|
||||
subject.client.send({
|
||||
type: 'foo',
|
||||
});
|
||||
done();
|
||||
});
|
||||
|
||||
// issue first response so connect will fire
|
||||
issueFirstResponse();
|
||||
});
|
||||
|
||||
test('should send request to socket', function() {
|
||||
assert.deepEqual(sent, [
|
||||
[{type: 'foo'}]
|
||||
]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// TODO(gaye): What is going on here / what is emtest()?
|
||||
suite.skip('client event: command', function() {
|
||||
var sent = [];
|
||||
|
||||
setup(function() {
|
||||
sent.length = 0;
|
||||
subject._onDeviceResponse = function() {
|
||||
sent.push(arguments);
|
||||
};
|
||||
subject._connect();
|
||||
subject.client.emtest('command', { type: 'foo' });
|
||||
});
|
||||
|
||||
test('should call onDeviceResponse', function() {
|
||||
assert.deepEqual(sent, [
|
||||
[{ id: 0, response: {type: 'foo'} }]
|
||||
]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
suite('._connect', function() {
|
||||
suite('retrying', function() {
|
||||
var net = require('net');
|
||||
var port = 60066;
|
||||
|
||||
setup(function() {
|
||||
Driver.Socket = RealSocket;
|
||||
socketRetry.waitForSocket = realWaitForSocket;
|
||||
subject = new Driver({ port: port });
|
||||
});
|
||||
|
||||
test('should eventually connect', function(done) {
|
||||
subject._connect();
|
||||
setTimeout(function() {
|
||||
var server = net.createServer(function(socket) {
|
||||
server.close();
|
||||
done();
|
||||
}).listen(port);
|
||||
}, 50);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
suite('._close', function() {
|
||||
setup(function(done) {
|
||||
subject.connect(function() {
|
||||
subject.close();
|
||||
done();
|
||||
});
|
||||
issueFirstResponse();
|
||||
});
|
||||
|
||||
test('should close socket', function() {
|
||||
assert.strictEqual(subject.socket.destroyed, true);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
283
gaia/tests/jsmarionette/client/marionette-client/test/marionette/element-test.js
Executable file
283
gaia/tests/jsmarionette/client/marionette-client/test/marionette/element-test.js
Executable file
|
|
@ -0,0 +1,283 @@
|
|||
/* global DeviceInteraction, MockDriver, assert, exampleCmds, helper */
|
||||
'use strict';
|
||||
// this is hack to ensure device interactions are loaded
|
||||
|
||||
suite('marionette/element', function() {
|
||||
var driver, subject, client, id, device,
|
||||
Element, Client;
|
||||
|
||||
helper.require('element', function(obj) {
|
||||
Element = obj;
|
||||
});
|
||||
|
||||
helper.require('client', function(obj) {
|
||||
Client = obj;
|
||||
});
|
||||
|
||||
id = '{fake-uuid-root}';
|
||||
|
||||
function simpleCommand(method, type, response, key) {
|
||||
suite('.' + method, function() {
|
||||
device.
|
||||
issues(method).
|
||||
shouldSend({
|
||||
name: type,
|
||||
parameters: {
|
||||
id: id
|
||||
}
|
||||
}).
|
||||
serverResponds(response).
|
||||
callbackReceives(key);
|
||||
});
|
||||
}
|
||||
|
||||
device = new DeviceInteraction(exampleCmds, function() {
|
||||
return subject;
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
driver = new MockDriver();
|
||||
client = new Client(driver);
|
||||
subject = new Element(id, client);
|
||||
});
|
||||
|
||||
suite('initialization', function() {
|
||||
test('should set id', function() {
|
||||
assert.strictEqual(subject.id, id);
|
||||
});
|
||||
|
||||
test('should set client', function() {
|
||||
assert.strictEqual(subject.client, client);
|
||||
});
|
||||
});
|
||||
|
||||
suite('._sendCommand', function() {
|
||||
device.
|
||||
issues('_sendCommand', {name: 'test'}).
|
||||
shouldSend({name: 'test', parameters: {id: id}}).
|
||||
serverResponds('value').
|
||||
callbackReceives('value');
|
||||
});
|
||||
|
||||
suite('.findElement', function() {
|
||||
device.
|
||||
issues('findElement', '#id').
|
||||
shouldSend({
|
||||
name: 'findElement',
|
||||
parameters: {
|
||||
value: '#id',
|
||||
element: id,
|
||||
using: 'css selector'
|
||||
}
|
||||
}).
|
||||
serverResponds('findElementResponse');
|
||||
|
||||
test('should send callback a single element', function() {
|
||||
var value = device.commandCallback.value;
|
||||
var resultId = exampleCmds.findElementResponse().value;
|
||||
assert.instanceOf(value, Element);
|
||||
assert.strictEqual(value.id, resultId);
|
||||
});
|
||||
});
|
||||
|
||||
suite('.findElements', function() {
|
||||
device.
|
||||
issues('findElements', '#id').
|
||||
shouldSend({
|
||||
name: 'findElements',
|
||||
parameters: {
|
||||
value: '#id',
|
||||
element: id,
|
||||
using: 'css selector'
|
||||
}
|
||||
}).
|
||||
serverResponds('findElementsResponse');
|
||||
|
||||
test('should send callback an element instance', function() {
|
||||
var map = device.commandCallback.value.map(function(el) {
|
||||
return el.id;
|
||||
});
|
||||
assert.deepEqual(map, exampleCmds.findElementsResponse().value);
|
||||
});
|
||||
});
|
||||
|
||||
suite('.scriptWith', function() {
|
||||
var calledWith,
|
||||
fn = function() {},
|
||||
cb = function() {};
|
||||
|
||||
setup(function() {
|
||||
subject.client.executeScript = function() {
|
||||
calledWith = arguments;
|
||||
};
|
||||
});
|
||||
|
||||
test('should call client.executeScript with ' +
|
||||
'element as argument', function() {
|
||||
subject.scriptWith(fn);
|
||||
|
||||
assert.strictEqual(calledWith[0], fn);
|
||||
assert.deepEqual(calledWith[1], [
|
||||
subject
|
||||
]);
|
||||
assert.strictEqual(calledWith[2], undefined);
|
||||
});
|
||||
|
||||
|
||||
test('should call client.executeScript with element ' +
|
||||
' + callback', function(){
|
||||
subject.scriptWith(fn, cb);
|
||||
|
||||
assert.strictEqual(calledWith[0], fn);
|
||||
assert.deepEqual(calledWith[1], [
|
||||
subject
|
||||
]);
|
||||
assert.strictEqual(calledWith[2], cb);
|
||||
});
|
||||
|
||||
test('should call client.executeScript with element ' +
|
||||
' + args + callback', function(){
|
||||
subject.scriptWith(fn, ['foo', 'bar'], cb);
|
||||
|
||||
assert.strictEqual(calledWith[0], fn);
|
||||
assert.deepEqual(calledWith[1], [
|
||||
subject, 'foo', 'bar'
|
||||
]);
|
||||
assert.strictEqual(calledWith[2], cb);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
suite('.equals', function() {
|
||||
var equals;
|
||||
var notEquals;
|
||||
setup(function() {
|
||||
equals = new Element(id, client);
|
||||
notEquals = new Element('___I_AM_TITAN', client);
|
||||
});
|
||||
|
||||
test('equals', function() {
|
||||
assert.isTrue(subject.equals(equals));
|
||||
});
|
||||
|
||||
test('not equal', function() {
|
||||
assert.isFalse(subject.equals(notEquals));
|
||||
});
|
||||
});
|
||||
|
||||
suite('.getAttribute', function() {
|
||||
var attr = 'name';
|
||||
|
||||
device.
|
||||
issues('getAttribute', attr).
|
||||
shouldSend({
|
||||
name: 'getElementAttribute',
|
||||
parameters: {
|
||||
name: attr,
|
||||
id: id
|
||||
}
|
||||
}).
|
||||
serverResponds('value').
|
||||
callbackReceives('value');
|
||||
});
|
||||
|
||||
suite('.sendKeys', function() {
|
||||
suite('when given a array', function() {
|
||||
var input = ['f', 'o', 'o'];
|
||||
device.
|
||||
issues('sendKeys', input).
|
||||
shouldSend({
|
||||
name: 'sendKeysToElement',
|
||||
parameters: {
|
||||
value: input,
|
||||
id: id
|
||||
}
|
||||
}).
|
||||
serverResponds('ok').
|
||||
callbackReceives();
|
||||
});
|
||||
|
||||
suite('when given a string', function() {
|
||||
var msg = 'foo';
|
||||
device.
|
||||
issues('sendKeys', msg).
|
||||
shouldSend({
|
||||
name: 'sendKeysToElement',
|
||||
parameters: {
|
||||
value: [msg],
|
||||
id: id
|
||||
}
|
||||
}).
|
||||
serverResponds('ok').
|
||||
callbackReceives();
|
||||
});
|
||||
});
|
||||
|
||||
suite('.cssProperty', function() {
|
||||
var property = 'margin';
|
||||
|
||||
device.
|
||||
issues('cssProperty', property).
|
||||
shouldSend({
|
||||
name: 'getElementValueOfCssProperty',
|
||||
parameters: {
|
||||
propertyName: property,
|
||||
id: id
|
||||
}
|
||||
}).
|
||||
serverResponds('value').
|
||||
callbackReceives('value');
|
||||
});
|
||||
|
||||
suite('.tap', function() {
|
||||
suite('when given the x and y offsets', function() {
|
||||
var x = 10;
|
||||
var y = 15;
|
||||
|
||||
device.
|
||||
issues('tap', x, y).
|
||||
shouldSend({
|
||||
name: 'singleTap',
|
||||
parameters: {
|
||||
x: x,
|
||||
y: y,
|
||||
id: id
|
||||
}
|
||||
}).
|
||||
serverResponds('value').
|
||||
callbackReceives('value');
|
||||
});
|
||||
|
||||
suite('when given the x offset only', function() {
|
||||
var x = 10;
|
||||
|
||||
device.
|
||||
issues('tap', x).
|
||||
shouldSend({
|
||||
name: 'singleTap',
|
||||
parameters: {
|
||||
x: x,
|
||||
id: id
|
||||
}
|
||||
}).
|
||||
serverResponds('value').
|
||||
callbackReceives('value');
|
||||
});
|
||||
|
||||
suite('when no x and y offsets', function() {
|
||||
simpleCommand('tap', 'singleTap', 'value');
|
||||
});
|
||||
});
|
||||
|
||||
simpleCommand('tagName', 'getElementTagName', 'value', 'value');
|
||||
simpleCommand('click', 'clickElement', 'ok');
|
||||
simpleCommand('text', 'getElementText', 'value', 'value');
|
||||
simpleCommand('clear', 'clearElement', 'ok');
|
||||
simpleCommand('selected', 'isElementSelected', 'value', 'value');
|
||||
simpleCommand('enabled', 'isElementEnabled', 'value', 'value');
|
||||
simpleCommand('displayed', 'isElementDisplayed', 'value', 'value');
|
||||
simpleCommand('size', 'getElementRect', 'value', 'value');
|
||||
simpleCommand('location', 'getElementRect', 'value', 'value');
|
||||
simpleCommand('rect', 'getElementRect', 'value', 'value');
|
||||
|
||||
});
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/* global assert, helper */
|
||||
'use strict';
|
||||
suite('marionette/error', function() {
|
||||
|
||||
var MarionetteError;
|
||||
|
||||
helper.require('error', function(obj) {
|
||||
MarionetteError = obj;
|
||||
});
|
||||
|
||||
test('should expose .ERRORS', function() {
|
||||
assert.property(MarionetteError, 'ERRORS');
|
||||
});
|
||||
|
||||
suite('#error', function() {
|
||||
test('should populate message', function() {
|
||||
var err = new MarionetteError({}, {message: 'msg'});
|
||||
assert.property(err, 'message');
|
||||
assert.include(err.message, 'msg');
|
||||
});
|
||||
|
||||
test('should populate stacktrace', function() {
|
||||
var trace = 'brie';
|
||||
var err = new MarionetteError({}, {stacktrace: trace});
|
||||
assert.property(err, 'stack');
|
||||
assert.include(err.message, trace);
|
||||
assert.include(err.stack, trace);
|
||||
});
|
||||
|
||||
test('should populate type', function() {
|
||||
var err = new MarionetteError({}, {});
|
||||
assert.property(err, 'type');
|
||||
});
|
||||
|
||||
test('should recognise known error code', function() {
|
||||
var err = new MarionetteError({}, {error: 'no such element'});
|
||||
assert.property(err, 'type');
|
||||
assert.equal(err.type, 'NoSuchElement');
|
||||
});
|
||||
|
||||
test('should fall back to GenericError for unknown error code', function() {
|
||||
var err = new MarionetteError({}, {error: 'brunost'});
|
||||
assert.property(err, 'type');
|
||||
assert.equal(err.type, 'GenericError');
|
||||
});
|
||||
|
||||
test('should support all errors', function() {
|
||||
for (var s in MarionetteError.ERRORS) {
|
||||
var err = new MarionetteError({}, {error: s});
|
||||
assert.strictEqual(err.type, MarionetteError.ERRORS[s]);
|
||||
assert.include(err.message, MarionetteError.ERRORS[s]);
|
||||
assert.instanceOf(err, Error);
|
||||
}
|
||||
});
|
||||
|
||||
test('should contain client', function() {
|
||||
var client = {};
|
||||
var result = new MarionetteError(client, {
|
||||
status: 7777,
|
||||
message: 'foo',
|
||||
stack: 'bar'
|
||||
});
|
||||
|
||||
assert.equal(result.client, client);
|
||||
assert.strictEqual(
|
||||
result.name,
|
||||
MarionetteError.ERRORS['webdriver error']
|
||||
);
|
||||
});
|
||||
|
||||
test('should use GenericError error when unknown error code', function() {
|
||||
var result = new MarionetteError({}, {error: 'cheese'});
|
||||
assert.strictEqual(
|
||||
result.name,
|
||||
MarionetteError.ERRORS['webdriver error']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/* global assert, helper */
|
||||
'use strict';
|
||||
suite('marionette/index', function() {
|
||||
var Index;
|
||||
|
||||
suiteSetup(function() {
|
||||
Index = helper.requireLib('marionette/index');
|
||||
});
|
||||
|
||||
test('should have paths', function() {
|
||||
assert.instanceOf(Index.Element, Object);
|
||||
assert.instanceOf(Index.Client, Object);
|
||||
assert.instanceOf(Index.Drivers, Object);
|
||||
assert.instanceOf(Index.CommandStream, Object);
|
||||
|
||||
assert.instanceOf(Index.Drivers.Abstract, Object);
|
||||
|
||||
|
||||
if (typeof(window) === 'undefined') {
|
||||
assert.instanceOf(Index.Drivers.Tcp, Object);
|
||||
} else {
|
||||
try {
|
||||
if (typeof(window.navigator.mozTCPSocket) !== 'undefined') {
|
||||
assert.instanceOf(Index.Drivers.MozTcp, Object);
|
||||
}
|
||||
} catch(e) {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/* global DeviceInteraction, MockDriver, assert, exampleCmds, helper */
|
||||
'use strict';
|
||||
suite('marionette/multi-actions', function() {
|
||||
var driver, subject, actions, client, device,
|
||||
MultiActions, Actions, Client;
|
||||
|
||||
helper.require('multi-actions', function(obj) {
|
||||
MultiActions = obj;
|
||||
});
|
||||
|
||||
helper.require('actions', function(obj) {
|
||||
Actions = obj;
|
||||
});
|
||||
|
||||
helper.require('client', function(obj) {
|
||||
Client = obj;
|
||||
});
|
||||
|
||||
device = new DeviceInteraction(exampleCmds, function() {
|
||||
return subject;
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
driver = new MockDriver();
|
||||
client = new Client(driver);
|
||||
actions = new Actions(client);
|
||||
subject = new MultiActions(client);
|
||||
});
|
||||
|
||||
suite('initialization', function() {
|
||||
test('should set client', function() {
|
||||
assert.strictEqual(subject.client, client);
|
||||
});
|
||||
});
|
||||
|
||||
suite('.add', function() {
|
||||
setup(function() {
|
||||
subject.add(actions);
|
||||
});
|
||||
|
||||
test('should have a action chain', function() {
|
||||
assert.deepEqual(subject.multiActions[0], actions.actionChain);
|
||||
});
|
||||
});
|
||||
|
||||
suite('.perform', function() {
|
||||
device.
|
||||
issues('perform').
|
||||
shouldSend({
|
||||
type: 'multiAction',
|
||||
value: [],
|
||||
max_length: 0
|
||||
}).
|
||||
serverResponds('ok').
|
||||
callbackReceives();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/* global assert */
|
||||
'use strict';
|
||||
var FakeSocket = require('../support/socket'),
|
||||
CommandStream = require('../../lib/marionette/command-stream'),
|
||||
ConnectionManger = require('../../lib/node/connection-manager');
|
||||
|
||||
|
||||
suite('connection-manager', function() {
|
||||
var RealSocket, subject, sockets = [];
|
||||
|
||||
suiteSetup(function() {
|
||||
RealSocket = ConnectionManger.Socket;
|
||||
ConnectionManger.Socket = FakeSocket;
|
||||
FakeSocket.sockets = sockets;
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
ConnectionManger.Socket = RealSocket;
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
sockets.length = 0;
|
||||
subject = new ConnectionManger();
|
||||
});
|
||||
|
||||
suite('initialization', function() {
|
||||
test('should initialize .connections', function() {
|
||||
assert.deepEqual(subject.connections, {});
|
||||
});
|
||||
});
|
||||
|
||||
suite('.remove', function() {
|
||||
test('should remove connection from list', function() {
|
||||
subject.open();
|
||||
assert.ok(subject.connections[0]);
|
||||
subject.close(0);
|
||||
assert.notOk(subject.connections[0]);
|
||||
});
|
||||
});
|
||||
|
||||
suite('.get', function() {
|
||||
|
||||
test('should return an open connection', function() {
|
||||
var open = subject.open();
|
||||
|
||||
assert.strictEqual(subject.get(open.id), open.connection);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
suite('.open', function() {
|
||||
var result, con;
|
||||
|
||||
setup(function() {
|
||||
result = subject.open();
|
||||
con = subject.connections[0];
|
||||
});
|
||||
|
||||
test('should initialize socket and stream', function() {
|
||||
assert.ok(sockets[0]);
|
||||
assert.strictEqual(con.socket, sockets[0]);
|
||||
assert.strictEqual(sockets[0].port, subject.defaultPort);
|
||||
|
||||
assert.instanceOf(con, CommandStream);
|
||||
});
|
||||
|
||||
test('should increment currentId', function() {
|
||||
assert.strictEqual(subject.currentId, 1);
|
||||
});
|
||||
|
||||
test('should return id and stream', function() {
|
||||
assert.deepEqual(result, {
|
||||
id: 0,
|
||||
connection: subject.connections[0]
|
||||
});
|
||||
});
|
||||
|
||||
function isRemovedOnEvent(event) {
|
||||
suite('on socket ' + event, function() {
|
||||
|
||||
setup(function() {
|
||||
assert.ok(subject.connections[0]);
|
||||
con.socket.emit(event);
|
||||
});
|
||||
|
||||
test('should remove itself from connections', function() {
|
||||
assert.notOk(subject.connections[0]);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
isRemovedOnEvent('close');
|
||||
isRemovedOnEvent('end');
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
'use strict';
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
|
||||
var WSClient = function() {
|
||||
this.sendCalls = [];
|
||||
EventEmitter.call(this);
|
||||
};
|
||||
|
||||
WSClient.prototype = Object.create(EventEmitter.prototype);
|
||||
WSClient.prototype.onsend = function() {};
|
||||
WSClient.prototype.send = function() {
|
||||
this.onsend.apply(this, arguments);
|
||||
this.sendCalls.push(Array.prototype.slice.call(arguments));
|
||||
};
|
||||
|
||||
|
||||
module.exports = exports = WSClient;
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
/* global Marionette, assert */
|
||||
(function(module, ns) {
|
||||
'use strict';
|
||||
|
||||
function DeviceInteraction(exampleCmds, subject) {
|
||||
var commands = exampleCmds;
|
||||
var expectedResponse;
|
||||
|
||||
setup(function() {
|
||||
expectedResponse = null;
|
||||
});
|
||||
|
||||
function driver() {
|
||||
if (subject().client) {
|
||||
return subject().client.driver;
|
||||
}
|
||||
return subject().driver;
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
commandCallback: function commandCallback(error, value) {
|
||||
commandCallback.error = error;
|
||||
commandCallback.value = value;
|
||||
},
|
||||
|
||||
withProtocol: function(version) {
|
||||
setup(function() {
|
||||
subject().protocol = version;
|
||||
});
|
||||
return this;
|
||||
},
|
||||
|
||||
issues: function issues() {
|
||||
var args = Array.prototype.slice.call(arguments),
|
||||
cmd = args.shift(),
|
||||
result,
|
||||
commandCallback = this.commandCallback;
|
||||
|
||||
setup(function() {
|
||||
if (!subject()) {
|
||||
throw new Error('DeviceInteraction must be provided a subject');
|
||||
}
|
||||
|
||||
args.push(commandCallback);
|
||||
if (!(cmd in subject())) {
|
||||
throw new Error('client does not have method ' + cmd);
|
||||
}
|
||||
|
||||
result = subject()[cmd].apply(subject(), args);
|
||||
});
|
||||
|
||||
test('should be chainable', function() {
|
||||
assert.strictEqual(result, subject());
|
||||
});
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
shouldSend: function shouldSend(options) {
|
||||
var check = function(option, value) {
|
||||
test('should send ' + option, function() {
|
||||
var sent = driver().sent[0];
|
||||
if (!(option in sent)) {
|
||||
throw new Error(
|
||||
option + ' was never sent as part of command to server');
|
||||
}
|
||||
assert.deepEqual(sent[option], value);
|
||||
});
|
||||
};
|
||||
|
||||
for (var key in options) {
|
||||
if (options.hasOwnProperty(key)) {
|
||||
check(key, options[key]);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
serverResponds: function serverResponds(type, options) {
|
||||
setup(function() {
|
||||
if (!(type in commands)) {
|
||||
throw new Error('No such example command: ' + type);
|
||||
}
|
||||
expectedResponse = commands[type](options);
|
||||
driver().respond(expectedResponse);
|
||||
});
|
||||
return this;
|
||||
},
|
||||
|
||||
callbackReceives: function callbackReceives(key) {
|
||||
var commandCallback = this.commandCallback;
|
||||
|
||||
if (key) {
|
||||
test('should receive ' + key + ' in response', function() {
|
||||
if (typeof expectedResponse[key] == 'undefined') {
|
||||
throw new Error(key + ' should not be undefined ' +
|
||||
'for test mocks use a real value');
|
||||
}
|
||||
assert.strictEqual(commandCallback.value, expectedResponse[key]);
|
||||
});
|
||||
} else {
|
||||
test('should receive whole body response', function() {
|
||||
assert.strictEqual(commandCallback.value, expectedResponse);
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = DeviceInteraction;
|
||||
|
||||
}.apply(
|
||||
this,
|
||||
(this.Marionette) ?
|
||||
[Marionette('support/device-interaction'), Marionette] :
|
||||
[module, require('../../lib/marionette/marionette')]
|
||||
));
|
||||
45
gaia/tests/jsmarionette/client/marionette-client/test/support/fake-xhr.js
Executable file
45
gaia/tests/jsmarionette/client/marionette-client/test/support/fake-xhr.js
Executable file
|
|
@ -0,0 +1,45 @@
|
|||
/* global Marionette */
|
||||
(function(module) {
|
||||
'use strict';
|
||||
|
||||
function FakeXhr() {
|
||||
this.openArgs = null;
|
||||
this.sendArgs = null;
|
||||
this.headers = {};
|
||||
this.responseHeaders = {};
|
||||
}
|
||||
|
||||
FakeXhr.prototype = {
|
||||
open: function() {
|
||||
this.openArgs = arguments;
|
||||
},
|
||||
|
||||
getResponseHeader: function(key) {
|
||||
return this.responseHeaders[key];
|
||||
},
|
||||
|
||||
setRequestHeader: function(key, value) {
|
||||
this.headers[key] = value;
|
||||
},
|
||||
|
||||
send: function() {
|
||||
this.sendArgs = arguments;
|
||||
},
|
||||
|
||||
respond: function(data, code) {
|
||||
this.readyState = 4;
|
||||
this.responseHeaders['content-type'] = 'application/json';
|
||||
this.responseText = JSON.stringify(data);
|
||||
this.status = code || 200;
|
||||
this.onreadystatechange();
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = FakeXhr;
|
||||
|
||||
}.apply(
|
||||
this,
|
||||
(this.Marionette) ?
|
||||
[Marionette('support/fake-xhr'), Marionette] :
|
||||
[module, require('../../lib/marionette/marionette')]
|
||||
));
|
||||
43
gaia/tests/jsmarionette/client/marionette-client/test/support/mock-driver.js
Executable file
43
gaia/tests/jsmarionette/client/marionette-client/test/support/mock-driver.js
Executable file
|
|
@ -0,0 +1,43 @@
|
|||
/* global Marionette */
|
||||
(function(module) {
|
||||
'use strict';
|
||||
|
||||
function MockDriver() {
|
||||
this.sent = [];
|
||||
this.queue = [];
|
||||
this.timeout = 0;
|
||||
}
|
||||
|
||||
MockDriver.prototype = {
|
||||
|
||||
connectionId: 0,
|
||||
|
||||
setScriptTimeout: function(timeout) {
|
||||
this.timeout = timeout;
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
this.sent.length = 0;
|
||||
this.queue.length = 0;
|
||||
},
|
||||
|
||||
send: function(cmd, cb) {
|
||||
this.sent.push(cmd);
|
||||
this.queue.push(cb);
|
||||
},
|
||||
|
||||
respond: function(cmd) {
|
||||
if (this.queue.length) {
|
||||
(this.queue.shift())(cmd);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = MockDriver;
|
||||
|
||||
}.apply(
|
||||
this,
|
||||
(this.Marionette) ?
|
||||
[Marionette('support/mock-driver'), Marionette] :
|
||||
[module, require('../../lib/marionette/marionette')]
|
||||
));
|
||||
45
gaia/tests/jsmarionette/client/marionette-client/test/support/socket.js
Executable file
45
gaia/tests/jsmarionette/client/marionette-client/test/support/socket.js
Executable file
|
|
@ -0,0 +1,45 @@
|
|||
/* global Marionette */
|
||||
/**
|
||||
@namespace
|
||||
*/
|
||||
(function(module, ns) {
|
||||
'use strict';
|
||||
|
||||
var Responder = ns.require('responder');
|
||||
|
||||
function FakeSocket() {
|
||||
Responder.call(this);
|
||||
FakeSocket.sockets.push(this);
|
||||
|
||||
this.destroyed = false;
|
||||
|
||||
if(arguments.length === 2) {
|
||||
this.host = arguments[0];
|
||||
this.port = arguments[1];
|
||||
}
|
||||
}
|
||||
|
||||
FakeSocket.sockets = [];
|
||||
|
||||
FakeSocket.prototype = Object.create(Responder.prototype);
|
||||
FakeSocket.prototype.connect = function(port, host, cb) {
|
||||
this.port = port;
|
||||
this.host = host;
|
||||
cb && cb();
|
||||
};
|
||||
|
||||
|
||||
FakeSocket.prototype.destroy = function() {
|
||||
this.destroyed = true;
|
||||
};
|
||||
|
||||
FakeSocket.prototype.close = FakeSocket.prototype.destroy;
|
||||
|
||||
module.exports = exports = FakeSocket;
|
||||
|
||||
}.apply(
|
||||
this,
|
||||
(this.Marionette) ?
|
||||
[Marionette('support/socket'), Marionette] :
|
||||
[module, require('../../lib/marionette/marionette')]
|
||||
));
|
||||
Loading…
Reference in a new issue