marionette-client
Advanced tools
Comparing version 1.7.6 to 1.8.0
@@ -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. |
@@ -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 @@ } |
Wildcard dependency
QualityPackage has a dependency with a floating version range. This can cause issues if the dependency publishes a new major version.
Found 3 instances in 1 package
322238
7583
1
- Removedjson-wire-protocol@1.0.0(transitive)
- Removedsocket-retry-connect@0.0.1(transitive)
- Removedsockit-to-me@1.0.2(transitive)