| 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 Clientwith the givenoptions. OptionshostHostname defaulting to localhostportPort number defaulting to 4444browserBrowser nameurlURL string
 params: Object  optionsapi: 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  fnreturn: 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 callbackfn(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 cmdpath with the givenargs. param: String  nameparam: Array  argsreturn: 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  fnapi: public
 | Client.prototype.end = function(fn){
  this._done = fn;
  this.queue.shift()();
};
 | 
| Enqueue the given cmdand array ofargsfor execution. param: String  cmdparam: Array  argsreturn: 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  fnreturn: Client api: public
 | Client.prototype.and = function(fn){
  fn.call(this, this);
  return this;
};
 | 
| Shortcut for new soda.Client(). param: Object  optionsreturn: 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: getassertassertNotverifyverifyNotwaitForwaitForNot
 For example providing us with: getTitleassertTitleverifyTitle...
 | 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 SauceClientwith the givenoptions. A suite of environment
variables are also supported in place of the options described below. OptionsusernameSaucelabs usernameaccess-keyAccount access keyosOperating system ex "Linux"browserBrowser name, ex "firefox"browser-versionBrowser version, ex "3.0.", "7."max-durationMaximum test duration in seconds, ex 300 (5 minutes)
 Environment VariablesSAUCE_HOSTDefaulting to "saucelabs.com"SAUCE_PORTDefaulting to 4444SAUCE_OSSAUCE_BROWSERSAUCE_USERNAMESAUCE_ACCESS_KEYSAUCE_BROWSER_VERSION
 params: Object  optionsapi: 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  optionsreturn: Client api: public
 | exports.createClient = function(options){
  return new SauceClient(options);
};
 | 
| Return saucelabs url to jobId'sfilename. param: String  usernameparam: String  jobIdparam: String  filenamereturn: 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  usernameparam: String  accessKeyparam: String  jobIdreturn: String api: public
 | exports.video = function(username, accessKey, jobId){
  return '<script src="http://saucelabs.com/video-embed/'
    + jobId + '.js?username='
    + username + '&access_key='
    + accessKey + '"/>';
};
 |