Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Please consider adding support for TestingBot.com #36

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
43 changes: 8 additions & 35 deletions Readme.md
@@ -1,7 +1,7 @@

# Soda

Selenium Node Adapter. A light-weight Selenium RC client for [NodeJS](http://nodejs.org), with additional [Sauce Labs](http://saucelabs.com) integration for acceptance testing in the cloud.
Selenium Node Adapter. A light-weight Selenium RC client for [NodeJS](http://nodejs.org), forked from [Soda](https://github.com/LearnBoost/soda) with support for [TestingBot](http://testingbot.com)

## Installation

Expand Down Expand Up @@ -62,12 +62,8 @@ When chaining successful commands may receive a callback, which is useful for cu
.getTitle(function(title){
assert.equal('Hello World', title);
})
.end(function(err){
browser.testComplete(function() {
console.log('done');
if(err) throw err;
});
})
.testComplete()
.end(function(err) { if (err) { console.log(err); } })

With the `.and()` method you can add additional commands to the queue. The callback accepts the client instance, which is also the value of "this".

Expand Down Expand Up @@ -101,21 +97,6 @@ With this helper function we can now re-use this logic in several places, an exp
});
});

## Sauce Labs Videos & Logs

When a job is complete, you can request the log or flv video from Sauce Labs. To access the url for these resources you may use `SauceClient#videoUrl` or `SauceClient#logUrl`, for example:

...
.end(function(err){
console.log(this.jobUrl)
console.log(this.videoUrl)
console.log(this.logUrl)
})

Sauce Labs also provides a script that you may embed in your CI server to display the video, accessible via `SauceClient#video`, which will yield something similar to:

<script src="http://saucelabs.com/video-embed/<job-id>.js?username=<username>&access_key=<access-key>"/>

## Selenium RC Example

var soda = require('soda')
Expand Down Expand Up @@ -145,15 +126,13 @@ Sauce Labs also provides a script that you may embed in your CI server to displa
});


## Sauce Labs Example
## TestingBot Example

var soda = require('soda')
, assert = require('assert');

var browser = soda.createSauceClient({
var browser = soda.createTestingBotClient({
'url': 'http://sirrobertborden.ca.app.learnboost.com/'
, 'username': '<your username>'
, 'access-key': '<your api key>'
, 'os': 'Linux'
, 'browser': 'firefox'
, 'browser-version': '3.'
Expand All @@ -177,14 +156,8 @@ Sauce Labs also provides a script that you may embed in your CI server to displa
.clickAndWait('//input[@value="Save"]')
.assertTextPresent('Account info updated')
.clickAndWait('link=Log out')
.end(function(err){
browser.setContext('sauce:job-info={"passed": ' + (err === null) + '}', function(){
browser.testComplete(function(){
console.log(browser.jobUrl);
if (err) throw err;
});
});
});
.testComplete()
.end(function(err) { if (err) { console.log(err); } })

## Creating Helpers

Expand All @@ -206,7 +179,7 @@ Keep in mind you can extend the prototype as needed for your test. An example of

## More Information

- Sauce Labs [Supported Browsers](http://saucelabs.com/docs/ondemand/browsers/env/js/se1/mac)
- TestingBot [Supported Browsers](http://testingbot.com/support/getting-started/browsers.html)
- Introduction to [Selenese](http://seleniumhq.org/docs/02_selenium_basics.html)
- Selenium [Command Reference](http://release.seleniumhq.org/selenium-core/1.0.1/reference.html).

Expand Down
89 changes: 43 additions & 46 deletions lib/soda/client.js
Expand Up @@ -14,14 +14,14 @@ var http = require('http')

/**
* Initialize a `Client` with the given `options`.
*
*
* Options:
*
*
* - `host` Hostname defaulting to localhost
* - `port` Port number defaulting to 4444
* - `browser` Browser name
* - `url` URL string
*
*
* @params {Object} options
* @api public
*/
Expand Down Expand Up @@ -83,51 +83,47 @@ Client.prototype.session = function(fn){
Client.prototype.command = function(cmd, args, fn){
this.emit('command', cmd, args);

// HTTP client
var client = http.createClient(this.port, this.host);

// Path construction
var path = this.commandPath(cmd, args);
var postData = path.replace('/selenium-server/driver/?', "");

// HTTP client request options
var options = {
host: this.host,
port: this.port,
method: "POST",
path: path,
headers: {
Host: this.host + ( this.port ? ':'+this.port : '' ),
'Content-Length': postData.length,
'Content-Type': 'application/x-www-form-urlencoded'
}
};

var req;

// Selenium RC can support POST request: http://svn.openqa.org/fisheye/changelog/selenium-rc/?cs=1898,
// we need to switch to use POST if the URL's is too long (Below I use the Internet Explorer's limit).
// See also: http://jira.openqa.org/browse/SRC-50
if (path.length > 2048 && (this.host + path ).length > 2083) {
postData = this.commandPath(cmd, args).replace('/selenium-server/driver/?', "");
req = client.request('POST'
, path
, { Host: this.host + (this.port ? ':' + this.port : '')
, 'Content-Length': postData.length
, 'Content-Type': 'application/x-www-form-urlencoded'
});

req.write(postData);
} else {
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 ||
res.body.indexOf('Timed out after ') === 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,?/, '');
var req = http.request(options, 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 ||
res.body.indexOf('Timed out after ') === 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);
}
fn(null, res.body, res);
}
});
});
});

req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});

req.write(postData);
req.end();
return this;
};
Expand Down Expand Up @@ -262,7 +258,7 @@ exports.createClient = function(options){

/**
* Command names.
*
*
* @type Array
*/

Expand Down Expand Up @@ -362,7 +358,7 @@ exports.commands = [

/**
* Accessor names.
*
*
* @type Array
*/

Expand Down Expand Up @@ -423,12 +419,13 @@ exports.accessors = [
, 'PromptPresent'
, 'SomethingSelected'
, 'TextPresent'
, 'TextNotPresent'
, 'Visible'
];

/**
* Generate commands via accessors.
*
*
* All accessors get prefixed with:
*
* - get
Expand Down
6 changes: 3 additions & 3 deletions lib/soda/index.js
Expand Up @@ -15,13 +15,13 @@ exports = module.exports = require('./client');
* Export sauce client.
*/

exports.SauceClient = require('./sauce');
exports.createSauceClient = require('./sauce').createClient;
exports.TestingBotClient = require('./testingbot');
exports.createTestingBotClient = require('./testingbot').createClient;

/**
* Library version.
*
* @type String
*/

exports.version = '0.2.4';
exports.version = '0.2.5';