From 3a4587034aef93fb0355e1a26f3dcb0e54a126ad Mon Sep 17 00:00:00 2001 From: Jochen Date: Mon, 26 Dec 2011 19:25:46 +0100 Subject: [PATCH 1/7] TestingBotClient for use with TestingBot.com's Selenium Grid --- lib/soda/testingbot.js | 155 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 lib/soda/testingbot.js diff --git a/lib/soda/testingbot.js b/lib/soda/testingbot.js new file mode 100644 index 0000000..6d0f3f0 --- /dev/null +++ b/lib/soda/testingbot.js @@ -0,0 +1,155 @@ +/*! + * Soda - TestingBot + * Copyright(c) 2011 TestingBot + * MIT Licensed + */ + +/** + * Module dependencies. + */ +var http = require('http') + , qs = require('querystring') + , EventEmitter = require('events').EventEmitter + , fs = require('fs') + , path = require('path'); +var Client = require('./client'); + +/** + * Initialize a TestingBot client with the given `options`. A suite of environment + * variables are also supported in place of the options described below. + * + * Options: + * + * - `client_key` TestingBot client key + * - `client_secret` TestingBot client secret + * - `os` 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) + * + * @params {Object} options + * @api public + */ + +var TestingBotClient = exports = module.exports = function TestingBotClient(options) { + options = options || {}; + this.host = 'hub.testingbot.com'; + this.port = 4444; + + options.os = options.os || 'Windows'; + options['browser-version'] = options['browser-version'] == undefined ? '' : options['browser-version']; + + this.options = options; + this.browser = options.browser || 'firefox'; + this.url = options.url; + + if (path.existsSync(process.env.HOME + "/.testingbot")) { + var data = fs.readFileSync(process.env.HOME + "/.testingbot", "utf-8"); + var parts = data.split(':'); + this.client_key = parts[0]; + this.client_secret = parts[1].replace("\n", ""); + } else { + if (options.client_key && options.client_secret) { + this.client_key = options.client_key; + this.client_secret = options.client_secret; + } else { + console.log("*** Please specify your TestingBot client_key and client_secret in the options, or add the ~/.testingbot file"); + } + } +}; + +/** + * Construct a `cmd` path with the given `args`. + * + * @param {String} name + * @param {Array} args + * @return {String} + * @api private + */ + +TestingBotClient.prototype.commandPath = function(cmd, args){ + var obj = { cmd: cmd, client_key: this.client_key, client_secret: this.client_secret }; + + // Arguments by nth + if (args) { + args.forEach(function(arg, i) { + obj[i+1] = arg; + }); + } + + if (cmd === 'getNewBrowserSession') { + obj[3] = ''; + obj[4] = 'platform=' + this.options.os + ';version=' + this.options['browser-version']; + } + // Ignore session id for getNewBrowserSession + if (this.sid && cmd !== 'getNewBrowserSession') { + obj.sessionId = this.sid; + } + return '/selenium-server/driver/?' + qs.stringify(obj); +}; + + +/** + * Interit from `Client`. + */ + +TestingBotClient.prototype.__proto__ = Client.prototype; + +/** + * Return testingbot test url. + * + * @return {String} + * @api public + */ + +TestingBotClient.prototype.__defineGetter__('testUrl', function(){ + return 'https://testingbot.com/members/tests/' + this.sid; +}); + +/** + * Shortcut for `new soda.TestingBotClient()`. + * + * @param {Object} options + * @return {Client} + * @api public + */ + +exports.createClient = function(options){ + var obj = new TestingBotClient(options); + obj.end = function(fn) { + TestingBotClient.prototype.end.call(this, function(err) { + // original callback + fn(); + // send results to TestingBot + var postData = qs.stringify({ + client_key: obj.client_key, + client_secret: obj.client_secret, + session_id: obj.sid, + success: err === null, + kind: 10 + }); + + // An object of options to indicate where to post to + var post_options = { + host: 'testingbot.com', + port: '80', + path: '/hq', + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Content-Length': postData.length + } + }; + + // Set up the request + var post_req = http.request(post_options, function(res) { + res.setEncoding('utf8'); + }); + + // post the data + post_req.write(postData); + post_req.end(); + }); + }; + return obj; +}; \ No newline at end of file From dd102f2ff319b9853f4c4f16b428181ac211a144 Mon Sep 17 00:00:00 2001 From: Jochen Date: Mon, 26 Dec 2011 19:34:25 +0100 Subject: [PATCH 2/7] update README --- Readme.md | 35 ++++++++--------------------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/Readme.md b/Readme.md index f3c04cf..1da015e 100644 --- a/Readme.md +++ b/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 @@ -101,21 +101,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: - -