New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

marionette-client

Package Overview
Dependencies
Maintainers
11
Versions
85
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

marionette-client - npm Package Compare versions

Comparing version 1.7.6 to 1.8.0

3

HISTORY.md

@@ -0,1 +1,4 @@

# 1.8.0
- Bug 1168396 - Adjust Marionette JS client to protocol changes
# 1.5.4

@@ -2,0 +5,0 @@ - Bug 1121223 - Use sockit-to-me built in timeout for connect call. Adjusted default interval, timeout and added separate socketTimeout.

2

lib/marionette/actions.js

@@ -251,3 +251,3 @@ /* global Marionette */

};
this.currentId = this.client._sendCommand(cmd, 'value', callback);
this.currentId = this.client._sendCommand(cmd, callback, 'value');
this.actionChain = [];

@@ -254,0 +254,0 @@ return this;

@@ -191,4 +191,19 @@ /* global Marionette */

/**
* Actor id for instance
* The current Marionette protocol level.
*
* When a new connection is established, the client will assume
* the protocol version that the passed driver connection got upon
* establishing a connection with the remote end.
*
* Defaults to protocol version 1.
*
* @property protocol
* @type Number
*/
protocol: 1,
/**
* Actor ID for instance.
*
* @deprecated
* @property actor

@@ -202,6 +217,6 @@ * @type String

*
* @property session
* @property sessionId
* @type String
*/
session: null,
sessionId: null,

@@ -280,2 +295,5 @@ // _state getters

}
// assume protocol level from driver, if set
this.protocol = this.driver.marionetteProtocol || this.protocol;
},

@@ -428,6 +446,8 @@

/**
* Sends a command to the server.
* Adds additional information like actor and session
* to command if not present.
* Send given command to the server with optional callback fired
* on completion.
*
* Adds additional information like actor and session ID to command
* if not present and using the deprecated version 1 of the Marionette
* protocol.
*

@@ -455,10 +475,11 @@ * @method send

if (!cmd.to) {
cmd.to = this.actor || 'root';
if (this.protocol == 1) {
if (!cmd.to) {
cmd.to = this.actor || 'root';
}
if (this.sessionId) {
cmd.session = cmd.session || this.sessionId;
}
}
if (this.session) {
cmd.session = cmd.session || this.session;
}
if (!cb && this.defaultCallback) {

@@ -485,3 +506,4 @@ cb = this.defaultCallback();

assert(typeof callback === 'function', 'you must use functions');
assert(typeof callback == 'function',
'expected function, got ' + callback);

@@ -505,24 +527,33 @@ // Convert first argument to an error it is possible for this to already

*
*
* @private
* @method _sendCommand
* @chainable
* @param {Object} command marionette command.
* @param {String} responseKey the part of the response to pass \
* unto the callback.
* @param {Object} callback wrapped callback.
* @param {Object} body The body of the Marionette command
* @param {Object} cb wrapped callback
* @param {String} key optional key in the response to pass
* unto the callback, will return the full object if undefined
*/
_sendCommand: function(command, responseKey, callback) {
var self = this;
_sendCommand: function(body, cb, key) {
try {
return this.send(body, function(data) {
var res, err;
try {
return this.send(command, function(data) {
var value;
try {
value = self._transformResultValue(data[responseKey]);
} catch (e) {
console.log('Error: unable to transform marionette response', data);
if ('error' in data) {
if (this.protocol == 1) {
err = data.error;
} else {
err = data;
}
} else if (key) {
res = data[key];
} else {
res = data;
}
return self._handleCallback(callback, data.error, value);
});
if (res) {
res = this._unmarshalWebElement(res);
}
return this._handleCallback(cb, err, res);
}.bind(this));
} catch (e) {

@@ -538,39 +569,44 @@ // Attach current client to any host related errors too...

*
* @deprecated
* @private
* @method _getActorId
* @param {Function} callback executed when response is sent.
* @param {Function} callback executed when response is sent
*/
_getActorId: function _getActorId(callback) {
var self = this, cmd;
cmd = { name: 'getMarionetteID' };
return this._sendCommand(cmd, 'id', function(err, actor) {
self.actor = actor;
if (callback) {
callback(err, actor);
_getActorId: function(cb) {
var body = {name: 'getMarionetteID'};
return this._sendCommand(body, function(err, actor) {
this.actor = actor;
if (cb) {
cb(err, actor);
}
});
}.bind(this), 'id');
},
/**
* Starts a remote session.
* Starts a new remote session with the old Marionette protocol.
*
* @deprecated
* @private
* @method _newSession
* @param {Function} callback optional.
* @param {Function} optional callback
* @param {Object} desired capabilities
*/
_newSession: function _newSession(callback, desiredCapabilities) {
var self = this;
function newSession(data) {
self.session = data.value;
return self._handleCallback(callback, data.error, data);
}
return this.send({
_newSession: function(callback, desiredCapabilities) {
var newSession = function(data) {
this.sessionId = data.value;
var err;
if ('error' in data) {
if (typeof data.error == 'object') {
err = data.error;
} else {
err = data;
}
}
return this._handleCallback(callback, err, data);
}.bind(this);
var body = {
name: 'newSession',
parameters: { capabilities: desiredCapabilities }
}, newSession);
parameters: {capabilities: desiredCapabilities},
};
return this.send(body, newSession);
},

@@ -691,12 +727,10 @@

var err, result;
function done(_err, _result) {
var testFunc = function(_err, _result) {
err = _err;
result = _result;
}
};
var wait = function(ms) {
setTimeout(marionetteScriptFinished, ms);
};
function sleep(waitMillis) {
setTimeout(marionetteScriptFinished, waitMillis);
}
while (Date.now() < timeout) {

@@ -707,4 +741,5 @@ if (err || result) {

test(done);
this.executeAsyncScript(sleep, [interval]);
test(testFunc);
this.executeAsyncScript(wait, [interval]);
}

@@ -749,4 +784,3 @@

/**
* Finds actor and creates connection to marionette.
* This is a combination of calling getMarionetteId and then newSession.
* Starts a new session with Marionette.
*

@@ -758,15 +792,34 @@ * @method startSession

startSession: function startSession(callback, desiredCapabilities) {
var self = this;
callback = callback || this.defaultCallback;
desiredCapabilities = desiredCapabilities || {};
function runHook(err) {
if (err) return callback(err);
self.runHook('startSession', callback);
if (this.protocol == 1) {
var runHook = function(err) {
if (err) {
return callback(err);
}
this.runHook('startSession', callback);
};
return this._getActorId(function() {
// actor will not be set if we send the command then
this._newSession(runHook, desiredCapabilities);
}.bind(this));
} else {
var newSession = function(err, res) {
if (err) {
callback(err);
} else {
this.sessionId = res.sessionId;
this.capabilities = res.capabilities;
this.runHook('startSession', function() { callback(err, res); });
}
}.bind(this);
var body = {
name: 'newSession',
parameters: {capabilities: desiredCapabilities},
};
return this._sendCommand(body, newSession);
}
return this._getActorId(function() {
//actor will not be set if we send the command then
self._newSession(runHook, desiredCapabilities);
});
},

@@ -777,3 +830,2 @@

*
*
* @chainable

@@ -787,9 +839,10 @@ * @method deleteSession

var closeDriver = function closeDriver() {
this._sendCommand(cmd, 'ok', function(err, value) {
this._sendCommand(cmd, function(err) {
// clear state of the past session
this.session = null;
this.sessionId = null;
this.capabilities = null;
this.actor = null;
this.driver.close();
this._handleCallback(callback, err, value);
this._handleCallback(callback, err);
}.bind(this));

@@ -812,4 +865,5 @@ }.bind(this);

sessionCapabilities: function sessionCapabilities(callback) {
var cmd = { name: 'getSessionCapabilities' };
return this._sendCommand(cmd, 'value', callback);
var cmd = {name: 'getSessionCapabilities'};
return this._sendCommand(
cmd, callback, this.protocol == 1 ? 'value' : 'capabilities');
},

@@ -826,4 +880,4 @@

getWindow: function getWindow(callback) {
var cmd = { name: 'getWindow' };
return this._sendCommand(cmd, 'value', callback);
var cmd = {name: 'getWindow'};
return this._sendCommand(cmd, callback, 'value');
},

@@ -839,4 +893,5 @@

getWindows: function getWindows(callback) {
var cmd = { name: 'getWindows' };
return this._sendCommand(cmd, 'value', callback);
var cmd = {name: 'getWindows'};
return this._sendCommand(
cmd, callback, this.protocol == 1 ? 'value' : undefined);
},

@@ -854,4 +909,4 @@

switchToWindow: function switchToWindow(id, callback) {
var cmd = { name: 'switchToWindow', parameters: {value: id }};
return this._sendCommand(cmd, 'ok', callback);
var cmd = {name: 'switchToWindow', parameters: {value: id}};
return this._sendCommand(cmd, callback);
},

@@ -867,4 +922,4 @@

getWindowType: function getWindowType(callback) {
var cmd = { name: 'getWindowType' };
return this._sendCommand(cmd, 'value', callback);
var cmd = {name: 'getWindowType'};
return this._sendCommand(cmd, callback, 'value');
},

@@ -884,4 +939,4 @@

importScript: function(script, callback) {
var cmd = { name: 'importScript', parameters: {script: script }};
return this._sendCommand(cmd, 'ok', callback);
var cmd = {name: 'importScript', parameters: {script: script}};
return this._sendCommand(cmd, callback);
},

@@ -933,3 +988,3 @@

return this._sendCommand(cmd, 'ok', callback);
return this._sendCommand(cmd, callback);
},

@@ -953,3 +1008,3 @@

* @chainable
* @param {String} context either: 'chome' or 'content'.
* @param {String} context either: 'chrome' or 'content'.
* @param {Function} callback receives boolean.

@@ -963,4 +1018,4 @@ */

setState(this, 'context', context);
var cmd = { name: 'setContext', parameters: { value: context }};
return this._sendCommand(cmd, 'ok', callback);
var cmd = {name: 'setContext', parameters: {value: context}};
return this._sendCommand(cmd, callback);
},

@@ -978,6 +1033,6 @@

setScriptTimeout: function setScriptTimeout(timeout, callback) {
var cmd = { name: 'setScriptTimeout', parameters: {ms: timeout} };
var cmd = {name: 'setScriptTimeout', parameters: {ms: timeout}};
setState(this, 'scriptTimeout', timeout);
this.driver.setScriptTimeout(timeout);
return this._sendCommand(cmd, 'ok', callback);
return this._sendCommand(cmd, callback);
},

@@ -1005,3 +1060,3 @@

setState(this, 'searchTimeout', timeout);
return this._sendCommand(cmd, 'ok', callback);
return this._sendCommand(cmd, callback);
},

@@ -1017,4 +1072,4 @@

title: function title(callback) {
var cmd = { name: 'getTitle' };
return this._sendCommand(cmd, 'value', callback);
var cmd = {name: 'getTitle'};
return this._sendCommand(cmd, callback, 'value');
},

@@ -1030,4 +1085,4 @@

getUrl: function getUrl(callback) {
var cmd = { name: 'getUrl' };
return this._sendCommand(cmd, 'value', callback);
var cmd = {name: 'getUrl'};
return this._sendCommand(cmd, callback, 'value');
},

@@ -1043,4 +1098,4 @@

refresh: function refresh(callback) {
var cmd = { name: 'refresh' };
return this._sendCommand(cmd, 'ok', callback);
var cmd = {name: 'refresh'};
return this._sendCommand(cmd, callback);
},

@@ -1057,4 +1112,4 @@

goUrl: function goUrl(url, callback) {
var cmd = { name: 'goUrl', parameters: { url: url }};
return this._sendCommand(cmd, 'ok', callback);
var cmd = {name: 'goUrl', parameters: {url: url}};
return this._sendCommand(cmd, callback);
},

@@ -1071,4 +1126,4 @@

goForward: function goForward(callback) {
var cmd = { name: 'goForward' };
return this._sendCommand(cmd, 'ok', callback);
var cmd = {name: 'goForward'};
return this._sendCommand(cmd, callback);
},

@@ -1084,4 +1139,4 @@

goBack: function goBack(callback) {
var cmd = { name: 'goBack' };
return this._sendCommand(cmd, 'ok', callback);
var cmd = {name: 'goBack'};
return this._sendCommand(cmd, callback);
},

@@ -1101,4 +1156,4 @@

log: function log(msg, level, callback) {
var cmd = { name: 'log', parameters:{level: level, value: msg }};
return this._sendCommand(cmd, 'ok', callback);
var cmd = {name: 'log', parameters: {level: level, value: msg}};
return this._sendCommand(cmd, callback);
},

@@ -1126,4 +1181,5 @@

getLogs: function getLogs(callback) {
var cmd = { name: 'getLogs' };
return this._sendCommand(cmd, 'value', callback);
var cmd = {name: 'getLogs'};
return this._sendCommand(
cmd, callback, this.protocol == 1 ? 'value' : undefined);
},

@@ -1139,4 +1195,4 @@

pageSource: function pageSource(callback) {
var cmd = { name: 'getPageSource' };
return this._sendCommand(cmd, 'value', callback);
var cmd = {name: 'getPageSource'};
return this._sendCommand(cmd, callback, 'value');
},

@@ -1182,3 +1238,3 @@

return this._sendCommand(cmd, 'value', callback);
return this._sendCommand(cmd, callback, 'value');
},

@@ -1337,4 +1393,2 @@

_findElement: function _findElement(type, query, method, id, callback) {
var cmd, self = this;
if (isFunction(id)) {

@@ -1352,3 +1406,3 @@ callback = id;

cmd = {
var cmd = {
name: type || 'findElement',

@@ -1361,36 +1415,35 @@ parameters: {

// only pass element when id is given.
if (id) cmd.parameters.element = id;
// only pass element when id is given
if (id) {
cmd.parameters.element = id;
}
if (this.searchMethods.indexOf(cmd.parameters.using) === -1) {
if (this.searchMethods.indexOf(cmd.parameters.using) < 0) {
throw new Error(
'invalid option for using: \'' +
cmd.parameters.using +
'\' use one of : ' +
this.searchMethods.join(', ')
'invalid option for using: \'' + cmd.parameters.using + '\' ' +
'use one of : ' + this.searchMethods.join(', ')
);
}
//proably should extract this function into a private
return this._sendCommand(cmd, 'value',
function processElements(err, result) {
var processElements = function(err, res) {
var rv;
if (res instanceof Array) {
rv = [];
res.forEach(function(el) {
rv.push(this._unmarshalWebElement(el));
}, this);
} else {
rv = this._unmarshalWebElement(res);
}
return this._handleCallback(callback, err, rv);
}.bind(this);
if (result instanceof this.Element) {
return self._handleCallback(callback, err, result);
}
// always look for "value" key for protocol 1,
// but only for single element searches under protocol 2
var extract;
if (this.protocol == 1 || type == 'findElement') {
extract = 'value';
}
var element;
if (result instanceof Array) {
element = [];
result.forEach(function(el) {
if (typeof el === 'object' && el.ELEMENT) {
el = el.ELEMENT;
}
element.push(new this.Element(el, self));
}, this);
} else {
element = new this.Element(result, self);
}
return self._handleCallback(callback, err, element);
});
return this._sendCommand(cmd, processElements, extract);
},

@@ -1416,4 +1469,2 @@

*
*
*
* @method findElement

@@ -1457,3 +1508,2 @@ * @chainable

/**

@@ -1477,15 +1527,17 @@ * Converts an function into a string

/**
* Processes result of command
* if an {'ELEMENT': 'uuid'} combination
* is returned a Marionette.Element
* instance will be created and returned.
* Unmarshals a web element object if provided input holds a web
* element reference and returns a Marionette.Element object, or the
* original input if not.
*
* A web element represents a DOM element through a
* {"ELEMENT": <UUID>} JSON object.
*
* @private
* @method _transformResultValue
* @param {Object} value original result from server.
* @return {Object|Marionette.Element} processed result.
* @method _unmarshalWebElement
* @param {Object} value result body from server.
* @return {Object|Marionette.Element} unmarshaled element, or the
* original input.
*/
_transformResultValue: function _transformResultValue(value) {
if (value && typeof(value.ELEMENT) === 'string') {
_unmarshalWebElement: function(value) {
if (typeof value == 'object' && 'ELEMENT' in value) {
return new this.Element(value.ELEMENT, this);

@@ -1545,7 +1597,6 @@ }

}
}, 'value', callback);
}, callback, 'value');
}
};
//gjslint: ignore

@@ -1552,0 +1603,0 @@ var proto = Client.prototype;

@@ -99,6 +99,6 @@ /* global Marionette */

* MyClass.prototype._connect = function _connect(){
* //open a socket to marrionete accept response
* //you *must* call _onDeviceResponse with the first
* //response from marionette it looks like this:
* //{ from: 'root', applicationType: 'gecko', traits: [] }
* // open a socket to marrionete accept response
* // you *must* call _onDeviceResponse with the first
* // response from Marionette it looks like this:
* // {applicationType: "gecko", marionetteProtocol: 2}
* this.connectionId = result.id;

@@ -114,4 +114,15 @@ * }

this._responseQueue.push(function(data) {
// determine protocol version
if ('marionetteProtocol' in data) {
this.marionetteProtocol = data.marionetteProtocol;
} else {
this.marionetteProtocol = 1;
}
// protocol specific properties to populate
if (this.marionetteProtocol == 1) {
this.traits = data.traits;
}
this.applicationType = data.applicationType;
this.traits = data.traits;
callback();

@@ -118,0 +129,0 @@ }.bind(this));

@@ -59,3 +59,3 @@ 'use strict';

options = options || {};
var interval = options.interval || 0;
var interval = options.interval || 100;
var timeout = options.timeout || 30000;

@@ -66,2 +66,3 @@ var socketTimeout = 1000;

var start = Date.now();
var lastDebugMessage = '';
var self = this;

@@ -87,3 +88,10 @@

catch(e) {
debug('exception when probing socket', e.message);
// This may seem ridiculous, but we have to keep these errors showing up
// but, they often repeat like CRAZY, so, quiet them down by only showing
// each exception we encounter once.
if (lastDebugMessage != e.message) {
lastDebugMessage = e.message;
debug('exception when probing socket', lastDebugMessage);
}
// Above read _may_ fail so it is important to close the socket...

@@ -126,3 +134,6 @@ sockit.close();

this._readResponse();
var resp = this._readResponse();
this.marionetteProtocol = resp.marionetteProtocol || 1;
this.traits = resp.traits;
this.applicationType = resp.applicationType;

@@ -129,0 +140,0 @@ callback();

@@ -36,13 +36,13 @@ /* global Marionette */

* @param {Object} command marionette request.
* @param {String} responseKey key in the response to pass to callback.
* @param {Function} callback callback function receives the result of
* response[responseKey] as its first argument.
* response[key] as its first argument.
* @param {String} key key in the response to pass to callback.
*
* @return {Object} self.
*/
_sendCommand: function(command, responseKey, callback) {
_sendCommand: function(command, callback, key) {
if (!command.parameters) {
command.parameters = {};
}
if (typeof(command.parameters.id) === 'undefined') {
if (typeof command.parameters.id == 'undefined') {
command.parameters.id = this.id;

@@ -52,4 +52,3 @@ }

var isSync = this.client.isSync;
var result =
this.client._sendCommand(command, responseKey, callback);
var result = this.client._sendCommand(command, callback, key);

@@ -138,10 +137,10 @@ if (isSync)

getAttribute: function getAttribute(attr, callback) {
var cmd = {
var body = {
name: 'getElementAttribute',
parameters: {
name: attr
}
name: attr,
},
};
return this._sendCommand(cmd, 'value', callback);
return this._sendCommand(body, callback, 'value');
},

@@ -162,9 +161,9 @@

}
var cmd = {
var body = {
name: 'sendKeysToElement',
parameters: {
value: input
}
value: input,
},
};
return this._sendCommand(cmd, 'ok', callback);
return this._sendCommand(body, callback);
},

@@ -180,6 +179,4 @@

click: function click(callback) {
var cmd = {
name: 'clickElement'
};
return this._sendCommand(cmd, 'ok', callback);
var body = {name: 'clickElement'};
return this._sendCommand(body, callback);
},

@@ -195,6 +192,4 @@

text: function text(callback) {
var cmd = {
name: 'getElementText'
};
return this._sendCommand(cmd, 'value', callback);
var body = {name: 'getElementText'};
return this._sendCommand(body, callback, 'value');
},

@@ -210,6 +205,4 @@

tagName: function tagName(callback) {
var cmd = {
name: 'getElementTagName'
};
return this._sendCommand(cmd, 'value', callback);
var body = {name: 'getElementTagName'};
return this._sendCommand(body, callback, 'value');
},

@@ -228,16 +221,16 @@

tap: function(x, y, callback) {
var cmd = {
var body = {
name: 'singleTap',
parameters: {}
parameters: {},
};
if (typeof(x) === 'number') {
cmd.parameters.x = x;
if (typeof x == 'number') {
body.parameters.x = x;
}
if (typeof(y) === 'number') {
cmd.parameters.y = y;
if (typeof y == 'number') {
body.parameters.y = y;
}
return this._sendCommand(cmd, 'value', callback);
return this._sendCommand(body, callback, 'value');
},

@@ -253,6 +246,4 @@

clear: function clear(callback) {
var cmd = {
name: 'clearElement'
};
return this._sendCommand(cmd, 'ok', callback);
var body = {name: 'clearElement'};
return this._sendCommand(body, callback);
},

@@ -263,3 +254,2 @@

*
*
* @method selected

@@ -270,6 +260,4 @@ * @param {Function} callback boolean argument.

selected: function selected(callback) {
var cmd = {
name: 'isElementSelected'
};
return this._sendCommand(cmd, 'value', callback);
var body = {name: 'isElementSelected'};
return this._sendCommand(body, callback, 'value');
},

@@ -285,6 +273,4 @@

enabled: function enabled(callback) {
var cmd = {
name: 'isElementEnabled'
};
return this._sendCommand(cmd, 'value', callback);
var body = {name: 'isElementEnabled'};
return this._sendCommand(body, callback, 'value');
},

@@ -295,3 +281,2 @@

*
*
* @method displayed

@@ -302,6 +287,4 @@ * @param {Function} callback boolean argument.

displayed: function displayed(callback) {
var cmd = {
name: 'isElementDisplayed'
};
return this._sendCommand(cmd, 'value', callback);
var body = {name: 'isElementDisplayed'};
return this._sendCommand(body, callback, 'value');
},

@@ -325,6 +308,5 @@

size: function size(callback) {
var cmd = {
name: 'getElementRect'
};
return this._sendCommand(cmd, 'value', callback);
var body = {name: 'getElementRect'};
return this._sendCommand(
body, callback, this.client.protocol == 1 ? 'value' : undefined);
},

@@ -348,6 +330,5 @@

location: function location(callback) {
var cmd = {
name: 'getElementRect'
};
return this._sendCommand(cmd, 'value', callback);
var body = {name: 'getElementRect'};
return this._sendCommand(
body, callback, this.client.protocol == 1 ? 'value' : undefined);
},

@@ -359,2 +340,3 @@

* height and width of the element
*
* @method rect

@@ -365,6 +347,5 @@ * @param {Function} callback [Error err, Object rect]

rect: function rect (callback) {
var cmd = {
name: 'getElementRect'
};
return this._sendCommand(cmd, 'value', callback);
var body = {name: 'getElementRect'};
return this._sendCommand(
body, callback, this.client.protocol == 1 ? 'value' : undefined);
},

@@ -381,9 +362,9 @@

cssProperty: function cssProperty(property, callback) {
var cmd = {
var body = {
name: 'getElementValueOfCssProperty',
parameters: {
propertyName: property
}
propertyName: property,
},
};
return this._sendCommand(cmd, 'value', callback);
return this._sendCommand(body, callback, 'value');
}

@@ -390,0 +371,0 @@ };

@@ -6,56 +6,54 @@ /* jshint -W069 */

var STATUSES = Object.freeze({
var ERRORS = Object.freeze({
'element not accessible': 'ElementNotAccessibleError',
'element not selectable': 'ElementIsNotSelectable',
'element not visible': 'ElementNotVisible',
'invalid cookie domain': 'InvalidCookieDomain',
'invalid element coordinates': 'InvalidElementCoordinates',
'invalid element state': 'InvalidElementState',
'invalid selector': 'InvalidSelector',
'invalid xpath selector': 'XPathLookupError',
'javascript error': 'JavaScriptError',
'no such alert': 'NoAlertOpenError',
'no such element': 'NoSuchElement',
'no such frame': 'NoSuchFrame',
'unknown command': 'UnknownCommand',
'no such window': 'NoSuchWindow',
'script timeout': 'ScriptTimeout',
'stale element reference': 'StaleElementReference',
'element not visible': 'ElementNotVisible',
'invalid element state': 'InvalidElementState',
'unknown error': 'UnknownError',
'element not selectable': 'ElementIsNotSelectable',
'javascript error': 'JavaScriptError',
'invalid xpath selector': 'XPathLookupError',
'timeout': 'Timeout',
'no such window': 'NoSuchWindow',
'invalid cookie domain': 'InvalidCookieDomain',
'unable to set cookie': 'UnableToSetCookie',
'unexpected alert open': 'UnexpectedAlertOpen',
'no such alert': 'NoAlertOpenError',
'script timeout': 'ScriptTimeout',
'invalid element coordinates': 'InvalidElementCoordinates',
'invalid selector': 'InvalidSelector',
'unknown command': 'UnknownCommand',
'unknown error': 'UnknownError',
'webdriver error': 'GenericError',
'element not accessible': 'ElementNotAccessibleError'
});
var CODES = Object.freeze({
7: STATUSES['no such element'],
8: STATUSES['no such frame'],
9: STATUSES['unknown command'],
10: STATUSES['stale element reference'],
11: STATUSES['element not visible'],
12: STATUSES['invalid element state'],
13: STATUSES['unknown error'],
15: STATUSES['element not selectable'],
17: STATUSES['javascript error'],
19: STATUSES['invalid xpath selector'],
21: STATUSES['timeout'],
23: STATUSES['no such window'],
24: STATUSES['invalid cookie domain'],
25: STATUSES['unable to set cookie'],
26: STATUSES['unexpected alert open'],
27: STATUSES['no such alert'],
28: STATUSES['script timeout'],
29: STATUSES['invalid element coordinates'],
32: STATUSES['invalid selector'],
56: STATUSES['element not accessible'],
500: STATUSES['webdriver error']
7: ERRORS['no such element'],
8: ERRORS['no such frame'],
9: ERRORS['unknown command'],
10: ERRORS['stale element reference'],
11: ERRORS['element not visible'],
12: ERRORS['invalid element state'],
13: ERRORS['unknown error'],
15: ERRORS['element not selectable'],
17: ERRORS['javascript error'],
19: ERRORS['invalid xpath selector'],
21: ERRORS['timeout'],
23: ERRORS['no such window'],
24: ERRORS['invalid cookie domain'],
25: ERRORS['unable to set cookie'],
26: ERRORS['unexpected alert open'],
27: ERRORS['no such alert'],
28: ERRORS['script timeout'],
29: ERRORS['invalid element coordinates'],
32: ERRORS['invalid selector'],
56: ERRORS['element not accessible'],
500: ERRORS['webdriver error']
});
var DEFAULT_STATUS = STATUSES['webdriver error'];
var DEFAULT_ERROR = ERRORS['webdriver error'];
/**
* Returns an error object given
* a error object from the marionette client.
* Expected input follows this format:
* Returns an error object given an error object from the Marionette client.
*

@@ -68,8 +66,18 @@ * Codes are from:

*
* {
* message: "Something",
* stacktrace: "wentwrong@line",
* status: "javascript error"
* }
* The expected input for protocol version 2 and higher:
*
* {
* error: "javascript error",
* message: "Something",
* stacktrace: "wentwrong@line",
* }
*
* The expected input for protocol version 1:
*
* {
* message: "Something",
* stacktrace: "wentwrong@line",
* status: "javascript error",
* }
*
* @param {Client} client which the error originates from.

@@ -79,10 +87,13 @@ * @param {Object} options for error (see above).

function MarionetteError(client, options) {
var status = DEFAULT_STATUS;
if (options.status in CODES)
status = CODES[options.status];
else if (options.status in STATUSES)
status = STATUSES[options.status];
var error = DEFAULT_ERROR;
if (options.status in CODES) {
error = CODES[options.status];
} else if (options.status in ERRORS) {
error = ERRORS[options.status];
} else if (options.error in ERRORS) {
error = ERRORS[options.error];
}
this.client = client;
this.type = status;
this.type = error;
this.name = this.type;

@@ -114,3 +125,3 @@

MarionetteError.STATUSES = STATUSES;
MarionetteError.ERRORS = ERRORS;
MarionetteError.CODES = CODES;

@@ -117,0 +128,0 @@ module.exports = MarionetteError;

@@ -5,15 +5,21 @@ /* global Marionette */

function merge() {
var args = Array.prototype.slice.call(arguments),
result = {};
args.forEach(function(object) {
var key;
for (key in object) {
if (object.hasOwnProperty(key)) {
result[key] = object[key];
function deepmerge(d) {
for (var i = 1; i < arguments.length; ++i) {
var o = arguments[i];
for (var k in o) {
var v = o[k];
if (typeof v == 'object') {
d[k] = deepmerge(d[k], v);
} else {
if (Array.isArray(d)) {
if (d.indexOf(v) < 0) {
d.push(v);
}
} else {
d[k] = v;
}
}
}
});
return result;
}
return d;
}

@@ -26,3 +32,3 @@

}
return merge(defaults, override);
return deepmerge(defaults, override);
};

@@ -32,104 +38,87 @@ }

module.exports = {
connect: cmd(
{ from: 'root', applicationType: 'gecko', traits: [] }
),
connectProto1: cmd({from: 'root', applicationType: 'gecko', traits: []}),
connectProto2: cmd({applicationType: 'gecko', marionetteProtocol: 2}),
getMarionetteID: cmd(
{ type: 'getMarionetteID' }
),
getMarionetteID: cmd({type: 'getMarionetteID'}),
getMarionetteIDResponse: cmd({from: 'root', id: 'con1'}),
getMarionetteIDResponse: cmd(
{ from: 'root', id: 'con1' }
),
newSession: cmd({type: 'newSession'}),
newSessionResponseProto1: cmd({
from: 'actor',
value: 'b2g-7',
}),
newSessionResponseProto2: cmd({
sessionId: '{2dddca75-7f78-415f-a7de-63eb2bc9412b}',
capabilities: {browserName: 'firefox'},
}),
newSession: cmd(
{ type: 'newSession' }
),
getWindow: cmd({name: 'getWindow'}),
getWindowResponse: cmd({value: '3-b2g'}),
newSessionResponse: cmd(
{ from: 'actor', value: 'b2g-7' }
),
getWindows: cmd({name: 'getWindows'}),
getWindowsResponseProto1: cmd({from: 'actor', value: ['1-b2g', '2-b2g']}),
getWindowsResponseProto2: cmd(['1-b2g', '2-b2g']),
getWindow: cmd(
{ type: 'getWindow' }
),
getUrl: cmd({name: 'getUrl'}),
getUrlResponse: cmd({value: 'http://localhost/'}),
getWindows: cmd(
{ type: 'getWindows' }
),
getLogsResponseProto1: cmd({
from: 'actor',
value: [
['debug', 'wow', 'Fri Apr 27 2012 11:00:32 GMT-0700 (PDT)'],
],
}),
getLogsResponseProto2: cmd([
['debug', 'wow', 'Fri Apr 27 2012 11:00:32 GMT-0700 (PDT)'],
]),
getWindowsResponse: cmd(
{ from: 'actor', value: ['1-b2g', '2-b2g'] }
),
screenshotResponse: cmd({
value: 'data:image/png;base64,iVBOgoAAAANSUhEUgAAAUAAAAHMCAYAAACk4nEJA',
}),
getWindowResponse: cmd(
{ from: 'actor', value: '3-b2g' }
),
elementEqualsResponse: cmd({value: false}),
getUrl: cmd(
{ type: 'getUrl' }
),
getUrlResponse: cmd(
{ from: 'actor', value: 'http://localhost/' }
),
getLogsResponse: cmd(
{
from: 'actor',
value: [
//log, level, time
['debug', 'wow', 'Fri Apr 27 2012 11:00:32 GMT-0700 (PDT)']
]
}
),
screenshotResponse: cmd(
{
from: 'actor',
value: 'data:image/png;base64,iVBOgoAAAANSUhEUgAAAUAAAAHMCAYAAACk4nEJA'
}
),
elementEqualsResponse: cmd(
{ from: 'actor', value: false }
),
findElementResponse: cmd(
{ from: 'actor', value: '{some-uuid}' }
),
{value: {ELEMENT: '{8056e6f7-2213-41d4-9db6-ad77ac7a96d3}'}}),
findElementsResponseProto1: cmd({
from: 'actor',
value: [
{ELEMENT: '{46982c9e-bb0c-486e-a514-d1cf20b42641}'},
{ELEMENT: '{585e70ee-e088-43cc-9b07-a4b078c1b8db}'},
],
}),
findElementsResponseProto2: cmd([
{ELEMENT: '{46982c9e-bb0c-486e-a514-d1cf20b42641}'},
{ELEMENT: '{585e70ee-e088-43cc-9b07-a4b078c1b8db}'},
]),
findElementsResponse: cmd(
{ from: 'actor', value: ['{some-uuid}', '{some-other-uuid}'] }
),
numberError: cmd({
from: 'actor',
error: {
message: 'you fail',
status: 7,
stacktrace: 'fail@url\nother:300',
},
}),
stringError: cmd({
from: 'actor',
error: {
message: 'you fail',
status: 'no such element',
stacktrace: 'fail@url\nother:300',
},
}),
modernError: cmd({
error: 'no such element',
message: 'you fail',
stacktrace: 'fail@url\nother:300',
}),
numberError: cmd(
{
from: 'actor',
error: {
message: 'you fail',
status: 7,
stacktrace: 'fail@url\nother:300'
}
}
),
//valueProto1: cmd({from: 'actor', value: 'zomg'}),
value: cmd({value: 'zomg'}),
stringError: cmd(
{
from: 'actor',
error: {
message: 'you fail',
status: 'no such element',
stacktrace: 'fail@url\nother:300'
}
}
),
capabilities: cmd({capabilities: {browserName: 'firefox'}}),
value: cmd(
{ from: 'actor', value: 'zomg' }
),
ok: cmd(
{ from: 'actor', ok: true }
)
//okProto1: cmd({from: 'actor', ok: true}),
ok: cmd({}),
};

@@ -136,0 +125,0 @@

@@ -51,3 +51,3 @@ /* global Marionette */

this.client._sendCommand(cmd, 'ok', callback);
this.client._sendCommand(cmd, callback);
this.multiActions = [];

@@ -54,0 +54,0 @@ return this;

{
"name": "marionette-client",
"version": "1.7.6",
"version": "1.8.0",
"author": "The Gaia Team <dev-gaia@lists.mozilla.org>",

@@ -10,5 +10,5 @@ "description": "Marionette Javascript Client",

"debug": "~0.6",
"json-wire-protocol": "*",
"socket-retry-connect": "*",
"sockit-to-me": "*"
"json-wire-protocol": "file:../json-wire-protocol",
"socket-retry-connect": "file:../socket-retry-connect",
"sockit-to-me": "file:../sockit-to-me"
},

@@ -15,0 +15,0 @@

@@ -24,4 +24,5 @@ /* global DeviceInteraction, MockDriver, assert, exampleCmds, helper */

function commandCallback(data) {
commandCallback.value = data;
function commandCallback(error, value) {
commandCallback.error = error;
commandCallback.value = value;
}

@@ -251,3 +252,3 @@

var err = {
status: 'script timeout',
error: 'script timeout',
message: 'foo',

@@ -290,57 +291,72 @@ stacktrace: 'bar'

suite('.send', function() {
suite('protocol 1 .send', function() {
suite('when session: is present', function() {
var result;
setup(function() {
subject.session = 'session';
subject.sessionId = 'session';
subject.actor = 'actor';
result = subject.send({ name: 'newSession' });
result = subject.send({name: 'newSession'});
});
test('should be chainable', function() {
assert.strictEqual(result, subject);
});
test('should add session to cmd', function() {
assert.deepEqual(driver.sent[0], {
to: subject.actor,
session: subject.session,
name: 'newSession'
session: subject.sessionId,
name: 'newSession',
});
});
});
suite('when to: is not given', function() {
suite('with an actor', function() {
setup(function() {
subject.actor = 'foo';
subject.send({ name: '_getActorId' }, cb);
subject.send({name: '_getActorId'}, cb);
});
test('should add to:', function() {
assert.deepEqual(driver.sent[0], {
to: 'foo',
name: '_getActorId'
name: '_getActorId',
});
});
});
suite('without an actor', function() {
setup(function() {
subject.send({ name: '_getActorId' }, cb);
subject.send({name: '_getActorId'}, cb);
});
test('should add to:', function() {
test('should add to', function() {
assert.deepEqual(driver.sent[0], {
to: 'root',
name: '_getActorId'
name: '_getActorId',
});
});
});
});
});
suite('protocol 2 .send', function() {
var result;
setup(function() {
subject.protocol = 2;
result = subject.send({name: 'get', parameters: {'url': 'about:blank'}});
});
test('should be chainable', function() {
assert.strictEqual(result, subject);
});
test('sends exact packet', function() {
assert.deepEqual(driver.sent[0], {
name: 'get',
parameters: {'url': 'about:blank'},
});
});
});

@@ -372,4 +388,4 @@

test('should update the ._scope' +
'when state changes in scoped', function() {
test('should update the ._scope when state changes in scoped',
function() {
scope.setScriptTimeout(250);

@@ -389,9 +405,9 @@ assert.strictEqual(scope._scope.scriptTimeout, 250);

suite('.startSession', function() {
suite('.startSession protocol version 1', function() {
var result;
var desiredCapabilities = { desiredCapability: true };
var desiredCapabilities = {desiredCapability: true};
setup(function(done) {
var firesHook = false;
subject.addHook('startSession', function(complete) {

@@ -401,3 +417,3 @@ firesHook = true;

});
result = subject.startSession(function() {

@@ -407,9 +423,56 @@ assert.ok(firesHook);

}, desiredCapabilities);
device.shouldSend({parameters: {capabilities: desiredCapabilities}});
driver.respond(exampleCmds.getMarionetteIDResponse());
driver.respond(exampleCmds.newSessionResponseProto1());
});
test('should be chainable', function() {
assert.strictEqual(result, subject);
});
test('should have an actor property', function() {
assert.property(subject, 'actor');
assert.isNotNull(subject.actor);
});
test('should have a sessionId property', function() {
assert.property(subject, 'sessionId');
assert.isNotNull(subject.sessionId);
});
device.shouldSend({
parameters: { capabiltiies: desiredCapabilities }
test('should have protocol version 1', function() {
assert.property(subject, 'protocol');
assert.strictEqual(subject.protocol, 1);
});
});
suite('.startSession protocol version 2', function() {
var result;
var response = exampleCmds.newSessionResponseProto2();
var desiredCapabilities = {desiredCapability: true};
setup(function(done) {
subject.protocol = 2;
var hookFired = false;
subject.addHook('startSession', function(done) {
hookFired = true;
done();
});
driver.respond(exampleCmds.getMarionetteIDResponse());
driver.respond(exampleCmds.newSessionResponse());
result = subject.startSession(function() {
cbResponse = arguments;
assert.ok(hookFired);
done();
}, desiredCapabilities);
device.
withProtocol(2).
shouldSend({
parameters: {capabilities: desiredCapabilities}
});
driver.respond(response);
});

@@ -421,30 +484,46 @@

test('should have actor', function() {
assert.ok(subject.actor);
test('should have an empty actor property', function() {
assert.isNull(subject.actor);
});
test('should have a session', function() {
assert.ok(subject.session);
test('should have sessionId property', function() {
assert.property(subject, 'sessionId');
assert.strictEqual(subject.sessionId, response.sessionId);
});
});
suite('._getActorId', function() {
device.
issues('_getActorId').
shouldSend({ name: 'getMarionetteID' }).
serverResponds('getMarionetteIDResponse').
callbackReceives('id');
test('should have a capabilities property', function() {
assert.property(subject, 'capabilities');
assert.strictEqual(subject.capabilities, response.capabilities);
});
test('should save actor id', function() {
assert.strictEqual(
subject.actor,
exampleCmds.getMarionetteIDResponse().id
);
test('should send newSession', function() {
assert.strictEqual(driver.sent[0].name, 'newSession');
});
test('should send callback response', function() {
assert.deepEqual(cbResponse[1], response);
});
test('should have protocol version 2', function() {
assert.property(subject, 'protocol');
assert.strictEqual(subject.protocol, 2);
});
});
suite('._getActorId', function() {
device
.issues('_getActorId')
.shouldSend({name: 'getMarionetteID'})
.serverResponds('getMarionetteIDResponse')
.callbackReceives('id');
test('should save actor ID', function() {
var resp = exampleCmds.getMarionetteIDResponse();
assert.strictEqual(subject.actor, resp.id);
});
});
suite('._sendCommand', function() {
var cmd, response,
calledTransform, result,
calledUnmarshal, result,
calledWith;

@@ -458,10 +537,10 @@

calledTransform = false;
subject._transformResultValue = function(value) {
calledTransform = true;
assert.strictEqual(value, response.value);
calledUnmarshal = false;
subject._unmarshalWebElement = function(value) {
calledUnmarshal = true;
assert.strictEqual(value, response);
return 'foo';
};
result = subject._sendCommand(cmd, 'value', function() {
result = subject._sendCommand(cmd, function() {
calledWith = arguments;

@@ -478,4 +557,4 @@ done();

test('should send command through _transformResultValue', function() {
assert.strictEqual(calledTransform, true);
test('should send command through _unmarshalWebElement', function() {
assert.strictEqual(calledUnmarshal, true);
assert.strictEqual(calledWith[1], 'foo');

@@ -486,4 +565,3 @@ });

suite('on number error', function() {
suite('on number error from protocol 1', function() {
setup(function(done) {

@@ -494,7 +572,6 @@ calledWith = null;

subject._sendCommand(cmd, 'value', function(err, data) {
subject._sendCommand(cmd, function(err, data) {
calledWith = arguments;
done();
});
}, 'value');
driver.respond(response);

@@ -507,7 +584,5 @@ });

});
});
suite('on string error', function() {
suite('on string error from protocol 1', function() {
setup(function(done) {

@@ -518,7 +593,26 @@ calledWith = null;

subject._sendCommand(cmd, 'value', function(err, data) {
subject._sendCommand(cmd, function(err, data) {
calledWith = arguments;
done();
});
}, 'value');
driver.respond(response);
});
test('should pass error to callback', function() {
assert.ok(calledWith[0]);
assert.notOk(calledWith[1]);
});
});
suite('on modern error from protocol 2', function() {
setup(function(done) {
calledWith = null;
cmd = exampleCmds.getUrl();
response = exampleCmds.modernError();
subject._sendCommand(cmd, function(err, data) {
calledWith = arguments;
done();
}, 'value');
driver.respond(response);

@@ -531,5 +625,3 @@ });

});
});
});

@@ -546,3 +638,4 @@

subject.actor = '1';
subject.session = 'sess';
subject.sessionId = 'session id';
subject.capabilities = {capability: true};

@@ -565,10 +658,14 @@ subject.driver.close = function() {

test('should clear session', function() {
assert.notOk(subject.session);
test('should set actorId to null', function() {
assert.isNull(subject.actor);
});
test('should set actor to null', function() {
assert.notOk(subject.actor);
test('should set sessionId to null', function() {
assert.isNull(subject.sessionId);
});
test('should set capabilities to null', function() {
assert.isNull(subject.capabilities);
});
test('should be chainable', function() {

@@ -587,3 +684,4 @@ assert.strictEqual(result, subject);

});
suite('after setting', function() {
suite('after setting with protocol 1', function() {
device.

@@ -598,3 +696,3 @@ issues('setSearchTimeout', 50).

serverResponds('ok').
callbackReceives('ok');
callbackReceives();

@@ -605,6 +703,25 @@ test('should set timeout', function() {

});
suite('after setting with protocol 2', function() {
device.
withProtocol(2).
issues('setSearchTimeout', 50).
shouldSend({
name: 'setSearchTimeout',
parameters: {
ms: 50
}
}).
serverResponds('ok').
callbackReceives();
test('should set timeout', function() {
assert.strictEqual(subject.searchTimeout, 50);
});
});
});
suite('.sessionCapabilities', function() {
suite('.sessionCapabilities with protocol 1', function() {
device.
withProtocol(1).
issues('sessionCapabilities').

@@ -618,2 +735,13 @@ shouldSend({

suite('.sessionCapabilities with protocol 2', function() {
device.
withProtocol(2).
issues('sessionCapabilities').
shouldSend({
name: 'getSessionCapabilities'
}).
serverResponds('capabilities').
callbackReceives('capabilities');
});
suite('.getWindow', function() {

@@ -629,3 +757,3 @@ device.

suite('.setContext', function() {
suite('.setContext with protocol 1', function() {
test('should have a default context', function() {

@@ -645,3 +773,3 @@ assert.strictEqual(subject.context, 'content');

serverResponds('ok').
callbackReceives('ok');
callbackReceives();

@@ -654,4 +782,29 @@ test('should remember context', function() {

suite('.getWindows', function() {
suite('.setContext with protocol 2', function() {
test('should have a default context', function() {
assert.strictEqual(subject.context, 'content');
});
suite('after setting context', function() {
device.
withProtocol(2).
issues('setContext', 'chrome').
shouldSend({
name: 'setContext',
parameters: {
value: 'chrome'
}
}).
serverResponds('ok').
callbackReceives();
test('should remember context', function() {
assert.strictEqual(subject.context, 'chrome');
});
});
});
suite('.getWindows with protocol 1', function() {
device.
withProtocol(1).
issues('getWindows').

@@ -661,8 +814,19 @@ shouldSend({

}).
serverResponds('getWindowsResponse').
serverResponds('getWindowsResponseProto1').
callbackReceives('value');
});
suite('.switchToWindow', function() {
suite('.getWindows with protocol 2', function() {
device.
withProtocol(2).
issues('getWindows').
shouldSend({
name: 'getWindows'
}).
serverResponds('getWindowsResponseProto2').
callbackReceives();
});
suite('.switchToWindow with protocol 1', function() {
device.
issues('switchToWindow', '1-b2g').

@@ -676,5 +840,19 @@ shouldSend({

serverResponds('ok').
callbackReceives('ok');
callbackReceives();
});
suite('.switchToWindow with protocol 2', function() {
device.
withProtocol(2).
issues('switchToWindow', '1-b2g').
shouldSend({
name: 'switchToWindow',
parameters: {
value: '1-b2g'
}
}).
serverResponds('ok').
callbackReceives();
});
suite('.getWindowType', function() {

@@ -696,3 +874,3 @@ device.

serverResponds('ok').
callbackReceives('ok');
callbackReceives();
});

@@ -710,3 +888,3 @@

serverResponds('ok').
callbackReceives('ok');
callbackReceives();
});

@@ -730,3 +908,3 @@

serverResponds('ok').
callbackReceives('ok');
callbackReceives();
});

@@ -750,11 +928,11 @@

serverResponds('ok').
callbackReceives('ok');
callbackReceives();
});
suite('when switch to a frame with options', function() {
var el;
var el, options;
setup(function() {
el = { ELEMENT: 'foo' };
var options = { focus: true };
options = { focus: true };
subject.switchToFrame(el, options, commandCallback);

@@ -772,11 +950,11 @@ });

serverResponds('ok').
callbackReceives('ok');
callbackReceives();
});
suite('when switch to a frame with multiple options', function() {
var el;
var el, options;
setup(function() {
el = { ELEMENT: 'foo' };
var options = {
el = {ELEMENT: 'foo'};
options = {
focus: true,

@@ -798,3 +976,3 @@ testOption: 'hi'

serverResponds('ok').
callbackReceives('ok');
callbackReceives();
});

@@ -813,3 +991,3 @@ });

serverResponds('ok').
callbackReceives('ok');
callbackReceives();
});

@@ -832,3 +1010,3 @@

serverResponds('ok').
callbackReceives('ok');
callbackReceives();

@@ -866,3 +1044,3 @@ test('should update .scriptTimeout', function() {

serverResponds('ok').
callbackReceives('ok');
callbackReceives();
});

@@ -887,3 +1065,3 @@

serverResponds('ok').
callbackReceives('ok');
callbackReceives();
});

@@ -898,8 +1076,8 @@

serverResponds('ok').
callbackReceives('ok');
callbackReceives();
});
suite('script executing commands', function() {
var calledWith;
var script = 'return null;';
var calledWith,
script = 'return null;';

@@ -935,9 +1113,6 @@ setup(function() {

test('should call _executeScript', function() {
assert.deepEqual(calledWith, [
{
name: 'executeJSScript',
parameters: {script: script, timeout: true, args: null }
},
commandCallback
]);
assert.deepEqual(calledWith, [{
name: 'executeJSScript',
parameters: {script: script, timeout: true, args: null}
}, commandCallback]);
});

@@ -955,3 +1130,3 @@ });

name: 'executeAsyncScript',
parameters: {script: script, args: null }
parameters: {script: script, args: null}
},

@@ -969,3 +1144,3 @@ commandCallback

shouldSend({ name: 'refresh' }).
callbackReceives('ok');
callbackReceives();
});

@@ -978,15 +1153,24 @@

serverResponds('ok').
callbackReceives('ok');
callbackReceives();
});
suite('.getLogs', function() {
suite('.getLogs with protocol 1', function() {
device.
issues('getLogs').
shouldSend({ name: 'getLogs' }).
serverResponds('getLogsResponse').
shouldSend({name: 'getLogs'}).
serverResponds('getLogsResponseProto1').
callbackReceives('value');
});
suite('.pageSouce', function() {
suite('.getLogs with protocol 2', function() {
device.
withProtocol(2).
issues('getLogs').
shouldSend({name: 'getLogs'}).
serverResponds('getLogsResponseProto2').
callbackReceives();
});
suite('.pageSource', function() {
device.
issues('pageSource').

@@ -1030,18 +1214,20 @@ shouldSend({ name: 'getPageSource' }).

function receivesElement() {
var value;
var els;
suite('callback argument', function() {
setup(function() {
value = device.commandCallback.value;
if (!(value instanceof Element) && !(value instanceof Array)) {
throw new Error('result is not an array or an Element instance');
}
var value = device.commandCallback.value;
if (!(value instanceof Array)) {
value = [value];
}
if (!(value instanceof Element) && !(value instanceof Array))
throw new Error(
'Result is not an array or an Element instance: ' + value);
if (value instanceof Array)
els = value;
else
els = [value];
});
test('should be an instance of Marionette.Element', function() {
value.forEach(function(el) {
els.forEach(function(el) {
assert.instanceOf(el, Element);

@@ -1079,4 +1265,4 @@ assert.strictEqual(el.client, subject);

test('should return an instance of MyElement', function() {
var value = device.commandCallback.value;
assert.instanceOf(value, MyElement);
var el = device.commandCallback.value;
assert.instanceOf(el, MyElement);
});

@@ -1204,7 +1390,6 @@ });

suite('._newSession', function() {
var response;
var desiredCapabilities = { desiredCapability: true };
var desiredCapabilities = {desiredCapability: true};
var response = exampleCmds.newSessionResponseProto1();
setup(function(done) {
response = exampleCmds.newSessionResponse();
subject._newSession(function() {

@@ -1215,6 +1400,3 @@ cbResponse = arguments;

device.shouldSend({
parameters: { capabiltiies: desiredCapabilities }
});
device.shouldSend({parameters: {capabilities: desiredCapabilities}});
driver.respond(response);

@@ -1227,4 +1409,4 @@ });

test('should save session id', function() {
assert.strictEqual(subject.session, response.value);
test('should save session ID', function() {
assert.strictEqual(subject.sessionId, response.value);
});

@@ -1235,3 +1417,2 @@

});
});

@@ -1261,9 +1442,7 @@

suite('._transformResultValue', function() {
suite('._unmarshalWebElement', function() {
var result;
suite('when it is an element', function() {
setup(function() {
result = subject._transformResultValue({
'ELEMENT': 'foo'
});
result = subject._unmarshalWebElement({'ELEMENT': 'foo'});
});

@@ -1275,3 +1454,2 @@

});
});

@@ -1283,3 +1461,3 @@

setup(function() {
result = subject._transformResultValue(obj);
result = subject._unmarshalWebElement(obj);
});

@@ -1293,3 +1471,2 @@

suite('._prepareArguments', function() {

@@ -1296,0 +1473,0 @@ var args, result;

@@ -140,7 +140,7 @@ /* global assert, exampleCmds, helper */

suite('.connect', function() {
suite('.connect with protocol 1', function() {
var cmd, calledChild;
setup(function(done) {
cmd = exampleCmds.connect();
cmd = exampleCmds.connectProto1();
calledChild = false;

@@ -165,7 +165,61 @@

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.deepEqual(subject.traits, []);
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);

@@ -185,3 +239,2 @@ });

});
});

@@ -251,3 +304,2 @@

suite('when device is not ready', function() {
test('should throw an error', function() {

@@ -311,2 +363,1 @@ assert.throws(function() {

});

@@ -5,3 +5,3 @@ 'use strict';

var response = '53:{"from":"root","applicationType":"gecko","traits":[]}';
var response = '54:{"applicationType": "gecko", "marionetteProtocol": 2}';

@@ -8,0 +8,0 @@ var server = net.createServer(function(connection) { //'connection' listener

@@ -19,3 +19,3 @@ /* global DeviceInteraction, MockDriver, assert, exampleCmds, helper */

function simpleCommand(method, type, responseKey) {
function simpleCommand(method, type, response, key) {
suite('.' + method, function() {

@@ -30,4 +30,4 @@ device.

}).
serverResponds(responseKey).
callbackReceives(responseKey);
serverResponds(response).
callbackReceives(key);
});

@@ -58,6 +58,6 @@ }

device.
issues('_sendCommand', { name: 'test' }, 'ok').
shouldSend({ name: 'test', parameters:{ id: id}}).
serverResponds('ok').
callbackReceives('ok');
issues('_sendCommand', {name: 'test'}).
shouldSend({name: 'test', parameters: {id: id}}).
serverResponds('value').
callbackReceives('value');
});

@@ -79,4 +79,4 @@

test('should send callback a single element', function() {
var value = device.commandCallback.value,
resultId = exampleCmds.findElementResponse().value;
var value = device.commandCallback.value;
var resultId = exampleCmds.findElementResponse().value;
assert.instanceOf(value, Element);

@@ -201,3 +201,3 @@ assert.strictEqual(value.id, resultId);

serverResponds('ok').
callbackReceives('ok');
callbackReceives();
});

@@ -217,3 +217,3 @@

serverResponds('ok').
callbackReceives('ok');
callbackReceives();
});

@@ -278,13 +278,13 @@ });

simpleCommand('tagName', 'getElementTagName', 'value');
simpleCommand('tagName', 'getElementTagName', 'value', 'value');
simpleCommand('click', 'clickElement', 'ok');
simpleCommand('text', 'getElementText', 'value');
simpleCommand('text', 'getElementText', 'value', 'value');
simpleCommand('clear', 'clearElement', 'ok');
simpleCommand('selected', 'isElementSelected', 'value');
simpleCommand('enabled', 'isElementEnabled', 'value');
simpleCommand('displayed', 'isElementDisplayed', 'value');
simpleCommand('size', 'getElementRect', 'value');
simpleCommand('location', 'getElementRect', 'value');
simpleCommand('rect', 'getElementRect', 'value');
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');
});

@@ -11,10 +11,6 @@ /* global assert, helper */

test('should expose .CODES', function() {
assert.operator(Object.keys(MarionetteError.CODES).length, '>', 0);
test('should expose .ERRORS', function() {
assert.property(MarionetteError, 'ERRORS');
});
test('should expose .STATUSES', function() {
assert.operator(Object.keys(MarionetteError.STATUSES).length, '>', 0);
});
suite('#error', function() {

@@ -40,4 +36,4 @@ test('should populate message', function() {

test('should recognise known number', function() {
var err = new MarionetteError({}, {status: 7});
test('should recognise known error code', function() {
var err = new MarionetteError({}, {error: 'no such element'});
assert.property(err, 'type');

@@ -47,25 +43,13 @@ assert.equal(err.type, 'NoSuchElement');

test('should recognise known string', function() {
var err = new MarionetteError({}, {status: 'no such element'});
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, 'NoSuchElement');
});
test('should fall back to GenericError for unknown number', function() {
var err = new MarionetteError({}, {status: 666});
assert.property(err, 'type');
assert.equal(err.type, 'GenericError');
});
test('should fall back to GenericError for unknown string', function() {
var err = new MarionetteError({}, {status: 'brunost'});
assert.property(err, 'type');
assert.equal(err.type, 'GenericError');
});
test('should support all error number codes', function() {
for (var n in MarionetteError.CODES) {
var err = new MarionetteError({}, {status: n});
assert.strictEqual(err.type, MarionetteError.CODES[n]);
assert.include(err.message, MarionetteError.CODES[n]);
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);

@@ -75,11 +59,2 @@ }

test('should support all error status strings', function() {
for (var s in MarionetteError.STATUSES) {
var err = new MarionetteError({}, {status: s});
assert.strictEqual(err.type, MarionetteError.STATUSES[s]);
assert.include(err.message, MarionetteError.STATUSES[s]);
assert.instanceOf(err, Error);
}
});
test('should contain client', function() {

@@ -96,23 +71,15 @@ var client = {};

result.name,
MarionetteError.STATUSES['webdriver error']
MarionetteError.ERRORS['webdriver error']
);
});
test('should use GenericError when unknown error code', function() {
var result = new MarionetteError({}, {status: 7777});
test('should use GenericError error when unknown error code', function() {
var result = new MarionetteError({}, {error: 'cheese'});
assert.strictEqual(
result.name,
MarionetteError.STATUSES['webdriver error']
MarionetteError.ERRORS['webdriver error']
);
});
test('should use GenericError error when unknown error status', function() {
var result = new MarionetteError({}, {status: 'cheese'});
assert.strictEqual(
result.name,
MarionetteError.STATUSES['webdriver error']
);
});
});
});

@@ -55,4 +55,4 @@ /* global DeviceInteraction, MockDriver, assert, exampleCmds, helper */

serverResponds('ok').
callbackReceives('ok');
callbackReceives();
});
});

@@ -6,9 +6,7 @@ /* global Marionette, assert */

function DeviceInteraction(exampleCmds, subject) {
var cmdResult;
subject = subject;
var commands = exampleCmds;
var expectedResponse;
setup(function() {
cmdResult = null;
expectedResponse = null;
});

@@ -25,7 +23,14 @@

commandCallback: function commandCallback(error, data) {
commandCallback.value = data;
commandCallback: function commandCallback(error, value) {
commandCallback.error = error;
commandCallback.value = value;
},
withProtocol: function(version) {
setup(function() {
subject().protocol = version;
});
return this;
},
issues: function issues() {

@@ -46,2 +51,3 @@ var args = Array.prototype.slice.call(arguments),

}
result = subject()[cmd].apply(subject(), args);

@@ -58,3 +64,3 @@ });

shouldSend: function shouldSend(options) {
function check(option, value) {
var check = function(option, value) {
test('should send ' + option, function() {

@@ -64,8 +70,7 @@ var sent = driver().sent[0];

throw new Error(
option + ' was never sent as part of command to server'
);
option + ' was never sent as part of command to server');
}
assert.deepEqual(sent[option], value);
});
}
};

@@ -77,2 +82,3 @@ for (var key in options) {

}
return this;

@@ -83,7 +89,7 @@ },

setup(function() {
if (!(type in exampleCmds)) {
throw new Error('there is no \'' + type + '\' example command');
if (!(type in commands)) {
throw new Error('No such example command: ' + type);
}
cmdResult = commands[type](options);
driver().respond(cmdResult);
expectedResponse = commands[type](options);
driver().respond(expectedResponse);
});

@@ -95,10 +101,17 @@ return this;

var commandCallback = this.commandCallback;
test('should receive the ' + key + ' from response', function() {
if (cmdResult[key] === undefined) {
throw new Error(
key + ' should not be undefined for test mocks use a real value'
);
}
assert.strictEqual(commandCallback.value, cmdResult[key]);
});
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;

@@ -105,0 +118,0 @@ }

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc