SodaThe Selenium Node Adapter or Soda provides a unified client to both Selenium RC and Saucelabs OnDemand. | |
| lib/soda/client.js |
Module dependencies.
|
var http = require('http')
, qs = require('querystring')
, EventEmitter = require('events').EventEmitter;
|
Initialize a Client with the given options .
Options
host Hostname defaulting to localhostport Port number defaulting to 4444browser Browser nameurl URL string
params: Object options api: public
|
var Client = exports = module.exports = function Client(options) {
this.host = options.host || 'localhost';
this.port = options.port || 4444;
this.browser = options.browser || 'firefox';
this.url = options.url;
if (this.browser[0] !== '*') {
this.browser = '*' + this.browser;
}
EventEmitter.call(this);
};
|
Interit from EventEmitter .
|
Client.prototype.__proto__ = EventEmitter.prototype;
|
Initialize a new session, then callback fn(err, sid)
param: Function fn return: Client api: public
|
Client.prototype.session = function(fn){
var self = this;
if (!this.browser) throw new Error('browser required');
if (!this.url) throw new Error('browser url required');
if (this.queue) {
return this.enqueue('getNewBrowserSession', [this.browser, this.url], function(body){
self.sid = body;
});
} else {
this.command('getNewBrowserSession', [this.browser, this.url], function(err, body){
if (err) return fn(err);
fn(null, self.sid = body);
});
}
};
|
Execute the given cmd / args , then callback fn(err, body, res) .
|
Client.prototype.command = function(cmd, args, fn){
this.emit('command', cmd, args);
var client = http.createClient(this.port, this.host);
var path = this.commandPath(cmd, args);
var req = client.request('GET'
, path
, { Host: this.host + (this.port ? ':' + this.port : '') });
req.on('response', function(res){
res.body = '';
res.setEncoding('utf8');
res.on('data', function(chunk){ res.body += chunk; });
res.on('end', function(){
if (res.body.indexOf('ERROR') === 0) {
var err = res.body.replace(/^ERROR: */, '');
err = cmd + '(' + args.join(', ') + '): ' + err;
fn(new Error(err), res.body, res);
} else {
if (res.body.indexOf('OK') === 0) {
res.body = res.body.replace(/^OK,?/, '');
}
fn(null, res.body, res);
}
});
});
req.end();
return this;
};
|
Construct a cmd path with the given args .
param: String name param: Array args return: String api: private
|
Client.prototype.commandPath = function(cmd, args){
var obj = { cmd: cmd };
if (args) {
args.forEach(function(arg, i){
obj[i+1] = arg;
});
}
if (this.sid && cmd !== 'getNewBrowserSession') {
obj.sessionId = this.sid;
}
return '/selenium-server/driver/?' + qs.stringify(obj);
};
|
Indicate that commands should be queued.
Example
browser
.chain
.session()
.open('/')
.type('q', 'Hello World')
.clickAndWait('btnG')
.assertTitle('Hello World - Google')
.testComplete()
.end(function(err){ ... });
|
Client.prototype.__defineGetter__('chain', function(){
this.queue = [];
return this;
});
|
Callback fn(err) when the queue is complete, or
when an exception has occurred.
param: Function fn api: public
|
Client.prototype.end = function(fn){
this._done = fn;
this.queue.shift()();
};
|
Enqueue the given cmd and array of args for execution.
param: String cmd param: Array args return: Client api: private
|
Client.prototype.enqueue = function(cmd, args, fn){
var self = this
, len = args.length;
if (typeof args[len - 1] === 'function') {
fn = args.pop();
}
this.queue.push(function(){
self.command(cmd, args, function(err, body, res){
if (!err && fn) {
try {
fn(body, res);
} catch (err) {
return self._done(err, body, res);
}
}
if (err) {
self._done(err, body, res);
} else if (self.queue.length) {
self.queue.shift()();
} else {
self._done(null, body, res);
}
});
});
return this;
};
|
Arbitrary callback fn(this) when using the chaining api.
param: Function fn return: Client api: public
|
Client.prototype.and = function(fn){
fn.call(this, this);
return this;
};
|
Shortcut for new soda.Client() .
param: Object options return: Client api: public
|
exports.createClient = function(options){
return new Client(options);
};
|
Command names.
|
exports.commands = [
'getNewBrowserSession'
, 'setContext'
, 'testComplete'
, 'addLocationStrategy'
, 'addScript'
, 'addSelection'
, 'allowNativeXpath'
, 'altKeyDown'
, 'altKeyUp'
, 'answerOnNextPrompt'
, 'assignId'
, 'break'
, 'captureEntirePageScreenshot'
, 'check'
, 'chooseCancelOnNextConfirmation'
, 'chooseOkOnNextConfirmation'
, 'click'
, 'clickAndWait'
, 'clickAt'
, 'clickAtAndWait'
, 'close'
, 'contextMenu'
, 'contextMenuAt'
, 'controlKeyDown'
, 'controlKeyUp'
, 'createCookie'
, 'deleteAllVisibleCookies'
, 'deleteCookie'
, 'deselectPopUp'
, 'doubleClick'
, 'doubleClickAt'
, 'dragAndDrop'
, 'dragAndDropToObject'
, 'echo'
, 'fireEvent'
, 'focus'
, 'goBack'
, 'highlight'
, 'ignoreAttributesWithoutValue'
, 'keyDown'
, 'keyPress'
, 'keyUp'
, 'metaKeyDown'
, 'metaKeyUp'
, 'mouseDown'
, 'mouseDownAt'
, 'mouseDownRight'
, 'mouseDownRightAt'
, 'mouseMove'
, 'mouseMoveAt'
, 'mouseOut'
, 'mouseOver'
, 'mouseUp'
, 'mouseUpAt'
, 'mouseUpRight'
, 'mouseUpRightAt'
, 'open'
, 'openWindow'
, 'refresh'
, 'removeAllSelections'
, 'removeScript'
, 'removeSelection'
, 'rollup'
, 'runScript'
, 'select'
, 'selectFrame'
, 'selectPopUp'
, 'selectWindow'
, 'setBrowserLogLevel'
, 'setCursorPosition'
, 'setMouseSpeed'
, 'setSpeed'
, 'setTimeout'
, 'shiftKeyDown'
, 'shiftKeyUp'
, 'submit'
, 'type'
, 'typeKeys'
, 'uncheck'
, 'useXpathLibrary'
, 'waitForCondition'
, 'waitForFrameToLoad'
, 'waitForPageToLoad'
, 'waitForPopUp'
, 'windowFocus'
, 'windowMaximize'
];
|
Accessor names.
|
exports.accessors = [
'ErrorOnNext'
, 'FailureOnNext'
, 'Alert'
, 'AllButtons'
, 'AllFields'
, 'AllLinks'
, 'AllWindowIds'
, 'AllWindowNames'
, 'AllWindowTitles'
, 'Attribute'
, 'AttributeFromAllWindows'
, 'BodyText'
, 'Confirmation'
, 'Cookie'
, 'CookieByName'
, 'CursorPosition'
, 'ElementHeight'
, 'ElementIndex'
, 'ElementPositionLeft'
, 'ElementPositionTop'
, 'ElementWidth'
, 'Eval'
, 'Expression'
, 'HtmlSource'
, 'Location'
, 'LogMessages'
, 'MouseSpeed'
, 'Prompt'
, 'SelectedId'
, 'SelectedIds'
, 'SelectedIndex'
, 'SelectedIndexes'
, 'SelectedLabel'
, 'SelectedLabels'
, 'SelectedValue'
, 'SelectedValues'
, 'SelectOptions'
, 'Speed'
, 'Table'
, 'Text'
, 'Title'
, 'Value'
, 'WhetherThisFrameMatchFrameExpression'
, 'WhetherThisWindowMatchWindowExpression'
, 'XpathCount'
, 'AlertPresent'
, 'Checked'
, 'ConfirmationPresent'
, 'CookiePresent'
, 'Editable'
, 'ElementPresent'
, 'ElementNotPresent'
, 'Ordered'
, 'PromptPresent'
, 'SomethingSelected'
, 'TextPresent'
, 'Visible'
];
|
Generate commands via accessors.
All accessors get prefixed with:
- get
- assert
- assertNot
- verify
- verifyNot
- waitFor
- waitForNot
For example providing us with:
- getTitle
- assertTitle
- verifyTitle
...
|
exports.accessors.map(function(cmd){
exports.commands.push(
'get' + cmd
, 'assert' + cmd
, 'assertNot' + cmd
, 'verify' + cmd
, 'verifyNot' + cmd
, 'waitFor' + cmd
, 'waitForNot' + cmd);
});
|
Generate command methods.
|
exports.commands.map(function(cmd){
Client.prototype[cmd] = function(){
if (this.queue) {
var args = Array.prototype.slice.call(arguments);
return this.enqueue(cmd, args);
} else {
var len = arguments.length
, fn = arguments[len - 1]
, args = Array.prototype.slice.call(arguments, 0, len - 1);
return this.command(cmd, args, fn);
}
};
});
|
| lib/soda/index.js |
Export all of ./client.
|
exports = module.exports = require('./client');
|
Export sauce client.
|
exports.SauceClient = require('./sauce');
exports.createSauceClient = require('./sauce').createClient;
|
Library version.
|
exports.version = '0.2.0';
|
| lib/soda/sauce.js |
Module dependencies.
|
var Client = require('./client');
|
Initialize a SauceClient with the given options . A suite of environment
variables are also supported in place of the options described below.
Options
username Saucelabs usernameaccess-key Account access keyos Operating system ex "Linux"browser Browser name, ex "firefox"browser-version Browser version, ex "3.0.", "7."max-duration Maximum test duration in seconds, ex 300 (5 minutes)
Environment Variables
SAUCE_HOST Defaulting to "saucelabs.com"SAUCE_PORT Defaulting to 4444SAUCE_OS SAUCE_BROWSER SAUCE_USERNAME SAUCE_ACCESS_KEY SAUCE_BROWSER_VERSION
params: Object options api: public
|
var SauceClient = exports = module.exports = function SauceClient(options) {
options = options || {};
this.host = process.env.SAUCE_HOST || 'saucelabs.com';
this.port = process.env.SAUCE_PORT || 4444;
options.os = options.os || process.env.SAUCE_OS || 'Linux';
options.url = options.url || process.env.SAUCE_BROWSER_URL;
options.browser = options.browser || process.env.SAUCE_BROWSER || 'firefox';
options.username = options.username || process.env.SAUCE_USERNAME;
options['access-key'] = options['access-key'] || process.env.SAUCE_ACCESS_KEY;
options['browser-version'] = options['browser-version'] == undefined
? (process.env.SAUCE_BROWSER_VERSION || '')
: (options['browser-version'] || '');
this.url = options.url;
this.username = options.username;
this.accessKey = options['access-key'];
this.options = options;
this.browser = JSON.stringify(options);
};
|
Interit from Client .
|
SauceClient.prototype.__proto__ = Client.prototype;
|
Return saucelabs video flv url.
return: String api: public
|
SauceClient.prototype.__defineGetter__('videoUrl', function(){
return exports.url(this.username, this.sid, 'video.flv');
});
|
Return saucelabs log file url.
return: String api: public
|
SauceClient.prototype.__defineGetter__('logUrl', function(){
return exports.url(this.username, this.sid, 'selenium-server.log');
});
|
Return saucelabs video embed script.
return: String api: public
|
SauceClient.prototype.__defineGetter__('video', function(){
return exports.video(this.username, this.accessKey, this.sid);
});
|
Shortcut for new soda.SauceClient() .
param: Object options return: Client api: public
|
exports.createClient = function(options){
return new SauceClient(options);
};
|
Return saucelabs url to jobId 's filename .
param: String username param: String jobId param: String filename return: String api: public
|
exports.url = function(username, jobId, filename){
return 'https://saucelabs.com/rest/'
+ username + '/jobs/'
+ jobId + '/results/'
+ filename;
};
|
Return saucelabs video embed script.
param: String username param: String accessKey param: String jobId return: String api: public
|
exports.video = function(username, accessKey, jobId){
return '<script src="http://saucelabs.com/video-embed/'
+ jobId + '.js?username='
+ username + '&access_key='
+ accessKey + '"/>';
};
|