first post

This commit is contained in:
2012-05-25 09:03:56 -04:00
commit 6a753904b7
609 changed files with 252648 additions and 0 deletions

26
Nodejs-Socketio-Mysql-Demo/node_modules/wd/lib/bin.js generated vendored Normal file
View File

@@ -0,0 +1,26 @@
#!/usr/bin/env node
var net = require('net')
, repl = require('repl')
, assert = require('assert')
, wd = require('./main')
;
var startRepl = function() {
var r = repl.start('(wd): ');
r.context.assert = assert;
r.context.wd = wd;
r.context.help = function() {
console.log("WD - Shell.");
console.log("Access the webdriver object via the object: 'wd'");
};
net.createServer(function (socket) {
connections += 1;
repl.start("(wd): ", socket);
}).listen("/tmp/node-repl-sock");
};
if (process.argv[2] == "shell") {
startRepl()
}

View File

@@ -0,0 +1,10 @@
var code = arguments[0], args = arguments[1], done = arguments[2];
var wrap = function() {
return eval(code);
};
try {
args.push(done);
return wrap.apply(this, args);
} catch (err) {
throw err;
}

View File

@@ -0,0 +1,9 @@
var code = arguments[0], args = arguments[1];
var wrap = function() {
return eval(code);
};
try {
return wrap.apply(this, args);
} catch (err) {
throw err;
}

View File

@@ -0,0 +1,32 @@
// run in the browser
//parse arguments
var condExpr = arguments[0], timeout = arguments[1],
poll = arguments[2], cb = arguments[3];
// recursive implementation
waitForConditionImpl = function(conditionExpr, limit, poll, cb) {
// timeout check
if (Date.now() < limit) {
// condition check
res = eval(conditionExpr);
if (res == true ) {
// condition ok
return cb(res);
} else {
// wait for poll and try again
setTimeout(function() {
waitForConditionImpl(conditionExpr, limit, poll, cb);
}, poll);
}
} else {
// try one last time
res = eval(conditionExpr);
return cb(res);
}
};
// calling impl
limit = Date.now() + timeout;
waitForConditionImpl(condExpr, limit, poll, cb);

View File

@@ -0,0 +1,316 @@
var http = require('http')
, __slice = Array.prototype.slice;
var strip = function strip(str) {
var x = [];
for (var i = 0; i < str.length; i++) {
if (str.charCodeAt(i)) {
x.push(str.charAt(i));
}
}
return x.join('');
};
var newError = function(opts)
{
var err = new Error();
for (var k in opts) {
err[k] = opts[k]
}
// nicer error output
err.inspect = function() {
var res = "";
for (var k in this) {
var _this = this;
(function() {
var v = _this[k];
if (typeof v === 'object') {
if ((v["class"] != null) && v["class"].match(/org.openqa.selenium.remote.Response/)) {
// for selenium classes, hidding long fields or field with
// duplicate information
var vAsStr = JSON.stringify(v, function(key, value) {
if (key === 'screen' || key === 'stackTrace' || key === 'buildInformation' || key === 'localizedMessage') {
return '[hidden]';
} else {
return value;
}
}, " ");
res = res + k + ": " + vAsStr + "\n";
} else {
// for other objects making sure output is not too long
var vAsStr = JSON.stringify(v, undefined, " ");
var maxLength = 1000;
if (vAsStr.length > maxLength) {
vAsStr = vAsStr.substr(0, maxLength) + "\n...";
}
res = res + k + ": " + vAsStr + "\n";
}
} else if (typeof v != 'function')
{
// printing non object types without modif
res = res + k + ": " + v + "\n";
}
})();
};
return res;
};
return err;
};
var isWebDriverException = function(res) {
var _ref;
if ((typeof res !== "undefined" && res !== null ?
(_ref = res["class"]) != null ? _ref.indexOf('WebDriverException') :
void 0 : void 0) > 0) {
return true;
}
return false;
}
// just calls the callback when there is no result
var simpleCallback = function(cb) {
return function(res) {
if(res==null) {
// expected behaviour for quit
if(cb!=null){ return cb();}
}else{
res.setEncoding('utf8');
var data = '';
res.on('data', function(chunk) { data += chunk.toString(); });
res.on('end', function() {
if(data == '') {
// expected behaviour
return cb()
} else {
// something wrong
if(cb!=null){
return cb(new Error(
{message:'Unexpected data in simpleCallback.', data:data}) );
}
}
});
}
};
};
// base for all callback handling data
var callbackWithDataBase = function(cb) {
return function(res) {
res.setEncoding('utf8');
var data = '';
res.on('data', function(chunk) { data += chunk.toString(); });
res.on('end', function() {
var obj;
try {
obj = JSON.parse(strip(data));
} catch (e) {
return cb(newError({message:'Not JSON response', data:data}));
}
if (obj.status > 0) {
cb(newError(
{message:'Error response status.',status:obj.status,cause:obj}));
} else {
cb(null, obj);
}
});
}
};
// retrieves field value from result
var callbackWithData = function(cb) {
return callbackWithDataBase(function(err,obj) {
if(err != null) {return cb(err);}
if(isWebDriverException(obj.value)) {return cb(newError(
{message:obj.value.message,cause:obj.value}));}
cb(null, obj.value);
});
};
// retrieves ONE element
var elementCallback = function(cb) {
return callbackWithDataBase(function(err, obj) {
if(err != null) {return cb(err);}
if(isWebDriverException(obj.value)) {return cb(newError(
{message:obj.value.message,cause:obj.value}));}
if (!obj.value.ELEMENT) {
cb(newError(
{message:"no ELEMENT in response value field.",cause:obj}));
} else {
cb(null, obj.value.ELEMENT);
}
});
};
// retrieves SEVERAL elements
var elementsCallback = function(cb) {
return callbackWithDataBase(function(err, obj) {
if(err != null) {return cb(err);}
if(isWebDriverException(obj.value)) {return cb(newError(
{message:obj.value.message,cause:obj.value}));}
if (!(obj.value instanceof Array)) {return cb(newError(
{message:"Response value field is not an Array.", cause:obj.value}));}
var i, elements = [];
for (i = 0; i < obj.value.length; i++) {
elements.push(obj.value[i].ELEMENT);
}
cb(null, elements);
});
};
var newHttpOpts = function(method) {
var opts = new Object();
opts.method = method;
for (var o in this.options) {
opts[o] = this.options[o];
}
opts.headers = {};
opts.headers['Connection'] = 'keep-alive';
if (opts.method === 'POST' || opts.method === 'GET')
opts.headers['Accept'] = 'application/json';
if (opts.method == 'POST')
opts.headers['Content-Type'] = 'application/json; charset=UTF-8';
return opts;
};
// session initialization
var init = function(desired, cb) {
var _this = this;
//allow desired ovveride to be left out
if (typeof desired == 'function') {
cb = desired;
desired = {};
}
// making copy
var _desired = {};
for (var k in desired) {
_desired[k] = desired[k];
}
// defaulting capabilities when necessary
for (var k in this.defaultCapabilities) {
_desired[k] = _desired[k] || this.defaultCapabilities[k];
}
// http options
var httpOpts = newHttpOpts.apply(this, ['POST']);
// authentication (for saucelabs)
if ((_this.username != null) && (_this.accessKey != null)) {
var authString = _this.username + ':' + _this.accessKey;
var buf = new Buffer(authString);
httpOpts['headers'] = {
'Authorization': 'Basic ' + buf.toString('base64')
};
}
// building request
var req = http.request(httpOpts, function(res) {
var data = '';
res.on('data', function(chunk) {
data += chunk;
});
res.on('end', function() {
if (res.headers.location == undefined) {
console.log('\x1b[31mError\x1b[0m: The environment you requested was unavailable.\n');
console.log('\x1b[33mReason\x1b[0m:\n');
console.log(data);
console.log('\nFor the available values please consult the WebDriver JSONWireProtocol,');
console.log('located at: \x1b[33mhttp://code.google.com/p/selenium/wiki/JsonWireProtocol#/session\x1b[0m');
if (cb)
cb({ message: 'The environment you requested was unavailable.' });
return;
}
var locationArr = res.headers.location.split('/');
_this.sessionID = locationArr[locationArr.length - 1];
_this.emit('status', '\nDriving the web on session: ' + _this.sessionID + '\n');
if (cb) { cb(null, _this.sessionID) }
});
});
req.on('error', function(e) { cb(e); });
// writting data
req.write(JSON.stringify({desiredCapabilities: _desired}));
// sending
req.end();
};
// used to build all the methods except init
var methodBuilder = function(builderOpt) {
// by default we call simpleCallBack(cb) assuming cb is the last argument
var defaultCb = function() {
var args, cb, _i;
args = 2 <= arguments.length ? __slice.call(arguments, 0,
_i = arguments.length - 1) : (_i = 0, []), cb = arguments[_i++];
return simpleCallback(cb);
};
return function(cb) {
var _this = this;
// parsing arguments
var args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
// http options init
var httpOpts = newHttpOpts.apply(this, [builderOpt.method]);
// retrieving path information
var relPath = builderOpt.relPath;
if (typeof relPath === 'function') { relPath = relPath.apply(this, args) }
var absPath = builderOpt.absPath;
if (typeof absPath === 'function') { absPath = absPath.apply(this, args) }
// setting path in http options
if (this.sessionID != null) { httpOpts['path'] += '/' + this.sessionID; }
if (relPath) { httpOpts['path'] += relPath; }
if (absPath) { httpOpts['path'] = absPath;}
// building callback
cb = (builderOpt.cb || defaultCb).apply(this, args);
// wrapping cb if we need to emit a message
if (builderOpt.emit != null) {
var _cb = cb;
cb = function(res) {
if (builderOpt.emit != null) {
_this.emit(builderOpt.emit.event, builderOpt.emit.message);
}
if (_cb) { _cb(); }
};
}
// logging
_this.emit('command', httpOpts['method'],
httpOpts['path'].replace(this.sessionID, ':sessionID')
.replace(this.basePath, '')
);
// building request
var req = http.request(httpOpts, cb);
req.on('error', function(e) { cb(e); });
// writting data
var data = '';
if (builderOpt.data != null) {
data = builderOpt.data.apply(this, args);
}
if (typeof data === 'object') {
data = JSON.stringify(data);
}
req.write(data);
//sending
req.end();
};
};
exports.simpleCallback = simpleCallback;
exports.callbackWithData = callbackWithData;
exports.elementCallback = elementCallback;
exports.elementsCallback = elementsCallback;
exports.init = init;
exports.methodBuilder = methodBuilder;

83
Nodejs-Socketio-Mysql-Demo/node_modules/wd/lib/main.js generated vendored Normal file
View File

@@ -0,0 +1,83 @@
var EventEmitter = require('events').EventEmitter
, __slice = Array.prototype.slice
, protocol = require('./protocol'),
SPECIAL_KEYS = require('./special-keys');
// webdriver client main class
// remoteWdConfig is an option object containing the following fields:
// host,port, username, accessKey
var webdriver = function(remoteWdConfig) {
this.sessionID = null;
this.username = remoteWdConfig.username;
this.accessKey = remoteWdConfig.accessKey;
this.basePath = (remoteWdConfig.path || '/wd/hub');
// default
this.options = {
host: remoteWdConfig.host || '127.0.0.1'
, port: remoteWdConfig.port || 4444
, path: (this.basePath + '/session').replace('//', '/')
};
this.defaultCapabilities = {
browserName: 'firefox'
, version: ''
, javascriptEnabled: true
, platform: 'ANY'
};
// saucelabs default
if ((this.username != null) && (this.accessKey != null)) {
this.defaultCapabilities.platform = 'VISTA';
}
EventEmitter.call(this);
};
// wraps protocol methods to hide implementation
var wrap = function(f) {
return function() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return f.apply(this, args);
};
};
// adding protocol methods
var k, v;
for (k in protocol) {
v = protocol[k];
if (typeof v === 'function') {
webdriver.prototype[k] = wrap(v);
}
}
webdriver.prototype.__proto__ = EventEmitter.prototype;
// parses server parameters
var parseRemoteWdConfig = function(args) {
var accessKey, host, path, port, username, _ref;
if (typeof (args != null ? args[0] : void 0) === 'object') {
return args[0];
} else {
host = args[0], port = args[1], username = args[2], accessKey = args[3];
return {
host: host,
port: port,
username: username,
accessKey: accessKey
};
}
};
// creates the webdriver object
// server parameters can be passed in 2 ways
// - as a list of arguments host,port, username, accessKey
// - as an option object containing the fields above
exports.remote = function() {
var args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
var rwc = parseRemoteWdConfig(args);
return new webdriver(rwc);
};
exports.SPECIAL_KEYS = SPECIAL_KEYS

View File

@@ -0,0 +1,604 @@
fs = require('fs');
var builder = require('./builder');
var methodBuilder = builder.methodBuilder
, callbackWithData = builder.callbackWithData
, elementCallback = builder.elementCallback
, elementsCallback = builder.elementsCallback
, __slice = Array.prototype.slice;
var protocol = {};
protocol.init = builder.init;
protocol.status = methodBuilder({
method: 'GET'
, absPath: function() { return this.basePath + '/status' }
, cb: function(cb) { return callbackWithData(cb); }
});
protocol.sessions = methodBuilder({
method: 'GET'
, absPath: function() { return this.basePath + '/sessions' }
, cb: function(cb) { return callbackWithData(cb); }
});
// alternate strategy to get session capabilities
// extract session capabilities from session list
protocol.altSessionCapabilities = function(cb) {
var _this = this;
// looking for the current session
protocol.sessions.apply(this, [function(err, sessions) {
if (err == null) {
sessions = sessions.filter(function(session) {
return session.id === _this.sessionID;
});
var _ref;
return cb(null, (_ref = sessions[0]) != null ? _ref.capabilities : void 0);
} else {
return cb(err, sessions);
}
}]);
};
protocol.sessionCapabilities = methodBuilder({
method: 'GET'
// default url
, cb: function(cb) { return callbackWithData(cb); }
});
protocol.close = methodBuilder({
method: 'DELETE'
, relPath: '/window'
});
protocol.quit = methodBuilder({
method: 'DELETE'
// default url
, emit: {event: 'status', message: '\nEnding your web drivage..\n'}
});
protocol.eval = function(code, cb) {
code = "return " + code + ";"
protocol.execute.apply( this, [code, function(err, res) {
if(err!=null) {return cb(err);}
cb(null, res);
}]);
};
protocol.safeEval = function(code, cb) {
protocol.safeExecute.apply( this, [code, function(err, res) {
if(err!=null) {return cb(err);}
cb(null, res);
}]);
};
protocol.execute = methodBuilder({
method: 'POST'
, relPath: '/execute'
, cb: function() {
// parsing args, cb at the end
var cb, _args, _i;
_args = 2 <= arguments.length ? __slice.call(arguments, 0,
_i = arguments.length - 1) : (_i = 0, []), cb = arguments[_i++];
return callbackWithData(cb);
}
, data: function() {
// parsing arguments (code,args,cb) with optional args
var args, cb, code, _args, _i;
_args = 2 <= arguments.length ? __slice.call(arguments, 0,
_i = arguments.length - 1) : (_i = 0, []), cb = arguments[_i++];
code = _args[0], args = _args[1];
//args default
if (typeof args === "undefined" || args === null) {
args = [];
}
return {script: code, args: args};
}
});
// script to be executed in browser
var safeExecuteJsScript = fs.readFileSync( __dirname + "/browser-scripts/safe-execute.js", 'utf8');
protocol.safeExecute = methodBuilder({
method: 'POST'
, relPath: '/execute'
, cb: function() {
// parsing args, cb at the end
var cb, _args, _i;
_args = 2 <= arguments.length ? __slice.call(arguments, 0,
_i = arguments.length - 1) : (_i = 0, []), cb = arguments[_i++];
return callbackWithData(cb);
}
, data: function() {
// parsing arguments (code,args,cb) with optional args
var args, cb, code, _args, _i;
_args = 2 <= arguments.length ? __slice.call(arguments, 0,
_i = arguments.length - 1) : (_i = 0, []), cb = arguments[_i++];
code = _args[0], args = _args[1];
//args default
if (typeof args === "undefined" || args === null) {
args = [];
}
return {script: safeExecuteJsScript, args: [code, args]};
}
});
protocol.executeAsync = methodBuilder({
method: 'POST'
, relPath: '/execute_async'
, cb: function() {
// parsing args, cb at the end
var cb, _args, _i;
_args = 2 <= arguments.length ? __slice.call(arguments, 0,
_i = arguments.length - 1) : (_i = 0, []), cb = arguments[_i++];
return callbackWithData(cb);
}
, data: function(code) {
// parsing arguments (code,args,cb) with optional args
var args, cb, code, _args, _i;
_args = 2 <= arguments.length ? __slice.call(arguments, 0,
_i = arguments.length - 1) : (_i = 0, []), cb = arguments[_i++];
code = _args[0], args = _args[1];
//args default
if (typeof args === "undefined" || args === null) {
args = [];
}
return {script: code, args: args};
}
});
// script to be executed in browser
var safeExecuteAsyncJsScript = fs.readFileSync( __dirname + "/browser-scripts/safe-execute-async.js", 'utf8');
protocol.safeExecuteAsync = methodBuilder({
method: 'POST'
, relPath: '/execute_async'
, cb: function() {
// parsing args, cb at the end
var cb, _args, _i;
_args = 2 <= arguments.length ? __slice.call(arguments, 0,
_i = arguments.length - 1) : (_i = 0, []), cb = arguments[_i++];
return callbackWithData(cb);
}
, data: function(code) {
// parsing arguments (code,args,cb) with optional args
var args, cb, code, _args, _i;
_args = 2 <= arguments.length ? __slice.call(arguments, 0,
_i = arguments.length - 1) : (_i = 0, []), cb = arguments[_i++];
code = _args[0], args = _args[1];
//args default
if (typeof args === "undefined" || args === null) {
args = [];
}
return {script: safeExecuteAsyncJsScript , args: [code, args]};
}
});
protocol.get = methodBuilder({
method: 'POST'
, relPath: '/url'
, data: function(url) { return {'url': url}; }
});
protocol.refresh = methodBuilder({
method: 'POST'
, relPath: '/refresh'
});
protocol.forward = methodBuilder({
method: 'POST'
, relPath: '/forward'
});
protocol.back = methodBuilder({
method: 'POST'
, relPath: '/back'
});
protocol.setImplicitWaitTimeout = methodBuilder({
method: 'POST'
, relPath: '/timeouts/implicit_wait'
, data: function(ms) { return {ms: ms}; }
});
// for backward compatibility
protocol.setWaitTimeout = protocol.setImplicitWaitTimeout;
protocol.setAsyncScriptTimeout = methodBuilder({
method: 'POST'
, relPath: '/timeouts/async_script'
, data: function(ms) { return {ms: ms}; }
});
protocol.setPageLoadTimeout = methodBuilder({
method: 'POST'
, relPath: '/timeouts/timeouts'
, data: function(ms) { return {type: 'page load', ms: ms}; }
});
protocol.element = methodBuilder({
method: 'POST'
, relPath: '/element'
, cb: function(using, value, cb) { return elementCallback(cb); }
, data: function(using, value) { return {using: using, value: value}; }
});
// avoid not found exception and return null instead
protocol.elementOrNull = function(using, value, cb) {
protocol.elements.apply(this, [using, value,
function(err, elements) {
if(err == null)
if(elements.length>0) {cb(null,elements[0]);} else {cb(null,null);}
else
cb(err);
}
]);
};
// avoid not found exception and return undefined instead
protocol.elementIfExists = function(using, value, cb) {
protocol.elements.apply(this, [using, value,
function(err, elements) {
if(err == null)
if(elements.length>0) {cb(null,elements[0]);} else {cb(null,undefined);}
else
cb(err);
}
]);
};
protocol.elements = methodBuilder({
method: 'POST'
, relPath: '/elements'
, cb: function(using, value, cb) { return elementsCallback(cb); }
, data: function(using, value) { return {using: using, value: value}; }
});
protocol.hasElement = function(using, value, cb){
protocol.elements.apply( this, [using, value, function(err, elements){
if(err==null)
cb(null, elements.length > 0 )
else
cb(err);
}]);
}
// convert to type to something like ById, ByCssSelector, etc...
var elFuncSuffix = function(type){
res = (' by ' + type).replace(/(\s[a-z])/g,
function($1){return $1.toUpperCase().replace(' ','');});
return res.replace('Xpath', 'XPath');
};
// return correct jsonwire type
var elFuncFullType = function(type){
if(type == 'css') {return 'css selector'} // shortcut for css
return type;
};
// from JsonWire spec + shortcuts
var elementFuncTypes = ['class name', 'css selector','id','name','link text',
'partial link text','tag name', 'xpath', 'css' ];
// adding all elementBy... , elementsBy... function
for (var i = 0; i < elementFuncTypes.length; i++) {
(function() {
var type = elementFuncTypes[i];
protocol['element' + elFuncSuffix(type)] = function(value, cb) {
protocol.element.apply(this, [elFuncFullType(type), value, cb]);
};
// avoid not found exception and return null instead
protocol['element' + elFuncSuffix(type)+ 'OrNull'] = function(value, cb) {
protocol.elements.apply(this, [elFuncFullType(type), value,
function(err, elements) {
if(err == null)
if(elements.length>0) {cb(null,elements[0]);} else {cb(null,null);}
else
cb(err);
}
]);
};
// avoid not found exception and return undefined instead
protocol['element' + elFuncSuffix(type)+ 'IfExists'] = function(value, cb) {
protocol.elements.apply(this, [elFuncFullType(type), value,
function(err, elements) {
if(err == null)
if(elements.length>0) {cb(null,elements[0]);} else {cb(null,undefined);}
else
cb(err);
}
]);
};
protocol['hasElement' + elFuncSuffix(type)] = function(value, cb) {
protocol.hasElement.apply(this, [elFuncFullType(type), value, cb]);
};
protocol['elements' + elFuncSuffix(type)] = function(value, cb) {
protocol.elements.apply(this, [elFuncFullType(type), value, cb]);
};
})();
}
protocol.getAttribute = methodBuilder({
method: 'GET'
, relPath: function(element, attrName) {
return '/element/' + element + '/attribute/' + attrName; }
, cb: function(element, attrName, cb) { return callbackWithData(cb); }
});
protocol.getValue = function(element, cb) {
protocol.getAttribute.apply(this, [element, 'value', cb]);
};
protocol.clickElement = methodBuilder({
method: 'POST'
, relPath: function(element, attrName) {
return '/element/' + element + '/click'; }
});
protocol.moveTo = methodBuilder({
method: 'POST'
, relPath: '/moveto'
, data: function(element, xoffset, yoffset) {
return { element: element, xoffset: xoffset, yoffset: yoffset }; }
});
//@todo simulate the scroll event using dispatchEvent and browser.execute
/* it's not implemented so taking it out
protocol.scroll = methodBuilder({
method: 'POST'
, relPath:'/moveto'
, data: function(element, xoffset, yoffset) {
return { element : element, xoffset : xoffset, yoffset : yoffset }; }
});
*/
protocol.buttonDown = methodBuilder({
method: 'POST'
, relPath: '/buttondown'
});
protocol.buttonUp = methodBuilder({
method: 'POST'
, relPath: '/buttonup'
});
//{LEFT = 0, MIDDLE = 1 , RIGHT = 2}
protocol.click = methodBuilder({
method: 'POST'
, relPath: '/click'
, data: function(button) { return {button: button}; }
});
protocol.doubleclick = methodBuilder({
method: 'POST'
, relPath: '/doubleclick'
});
//All keys are up at end of command
protocol.type = methodBuilder({
method: 'POST'
, relPath: function(element, keys) {
return '/element/' + element + '/value'; }
, data: function(element, keys) {
if (!(keys instanceof Array)) {keys = [keys];}
return {value: keys};
}
});
protocol.keys = methodBuilder({
method: 'POST'
, relPath: '/keys'
, data: function(keys) {
if (!(keys instanceof Array)) {keys = [keys];}
return {value: keys};
}
});
protocol.clear = methodBuilder({
method: 'POST'
, relPath: function(element) { return '/element/' + element + '/clear'; }
});
protocol.title = methodBuilder({
method: 'GET'
, relPath: '/title'
, cb: function(cb) { return callbackWithData(cb); }
});
// element must be specified
_rawText = methodBuilder({
method: 'GET'
, relPath: function(element) { return '/element/' + element + '/text'; }
, cb: function(element, cb) { return callbackWithData(cb); }
});
// element is specific element, 'body', or undefined
protocol.text = function(element, cb) {
var _this = this;
if (typeof element === 'undefined' || element == 'body' || element === null) {
protocol.element.apply(this, ['tag name', 'body', function(err, bodyEl) {
if (err == null) {_rawText.apply(_this, [bodyEl, cb]);} else {cb(err);}
}]);
}else {
_rawText.apply(_this, [element, cb]);
}
};
// element is specific element, 'body', or undefined
protocol.textPresent = function(searchText, element, cb) {
protocol.text.apply(this, [element, function(err, text) {
if (err) {
cb(err, null);
} else {
cb(err, text.indexOf(searchText) >= 0);
}
}]);
};
protocol.acceptAlert = methodBuilder({
method: 'POST'
, relPath: '/accept_alert'
});
protocol.dismissAlert = methodBuilder({
method: 'POST'
, relPath: '/dismiss_alert'
});
protocol.active = methodBuilder({
method: 'POST'
, relPath: '/element/active'
, cb: function(cb) {
return callbackWithData(function(e, o) { cb(null, o['ELEMENT'])});
}
});
protocol.url = methodBuilder({
method: 'GET'
, relPath: '/url'
, cb: function(cb) { return callbackWithData(cb); }
});
protocol.allCookies = methodBuilder({
method: 'GET'
, relPath: '/cookie'
, cb: function(cb) { return callbackWithData(cb); }
});
/*
cookie like the following:
{name:'fruit', value:'apple'}
optional fields: path, domain, secure, expiry
check the JsonWire doc for details
*/
protocol.setCookie = methodBuilder({
method: 'POST'
, relPath: '/cookie'
, data: function(cookie) {
// setting secure otherwise selenium server throws
if ((typeof cookie !== 'undefined' && cookie !== null) &&
!((typeof cookie !== 'undefined' &&
cookie !== null ? cookie.secure : void 0) != null)) {
cookie.secure = false;
}
return { cookie: cookie };
}
});
protocol.deleteAllCookies = methodBuilder({
method: 'DELETE'
, relPath: '/cookie'
});
protocol.deleteCookie = methodBuilder({
method: 'DELETE'
, relPath: function(name) {
return '/cookie/' + encodeURIComponent(name); }
});
// waitForCondition recursive implementation
var waitForConditionImpl = function(conditionExpr, limit, poll, cb) {
var _this = this;
// timeout check
if (Date.now() < limit) {
// condition check
protocol.eval.apply( _this , [conditionExpr, function(err, res) {
if(err != null) {return cb(err);}
if (res == true) {
// condition ok
return cb(null, true);
} else {
// wait for poll and try again
setTimeout(function() {
waitForConditionImpl.apply(_this, [conditionExpr, limit, poll, cb]);
}, poll);
}
}]);
} else {
// try one last time
protocol.eval.apply( _this, [conditionExpr, function(err, res) {
if(err != null) {return cb(err);}
if (res == true) {
return cb(null, true);
} else {
// condition nok within timeout
return cb("waitForCondition failure for: " + conditionExpr);
}
}]);
}
};
// args: (conditionExpr, timeout, poll, cb)
// timeout and poll are optional
protocol.waitForCondition = function() {
// parsing args
var args, cb, conditionExpr, limit, poll, timeout, _i;
args = 2 <= arguments.length ? __slice.call(arguments, 0,
_i = arguments.length - 1) : (_i = 0, []),
cb = arguments[_i++];
conditionExpr = args[0], timeout = args[1], poll = args[2];
//defaults
timeout = timeout || 1000;
poll = poll || 100;
// calling implementation
limit = Date.now() + timeout;
waitForConditionImpl.apply(this, [conditionExpr, limit, poll, cb]);
};
// script to be executed in browser
var waitForConditionInBrowserJsScript = fs.readFileSync( __dirname + "/browser-scripts/wait-for-cond-in-browser.js", 'utf8');
// args: (conditionExpr, timeout, poll, cb)
// timeout and poll are optional
protocol.waitForConditionInBrowser = function() {
var _this = this;
// parsing args
var args, cb, conditionExpr, limit, poll, timeout, _i;
args = 2 <= arguments.length ? __slice.call(arguments, 0,
_i = arguments.length - 1) : (_i = 0, []),
cb = arguments[_i++];
conditionExpr = args[0], timeout = args[1], poll = args[2];
//defaults
timeout = timeout || 1000;
poll = poll || 100;
// calling script
protocol.executeAsync.apply( _this, [waitForConditionInBrowserJsScript,
[conditionExpr,timeout,poll], function(err,res) {
if(err != null) {return cb(err);}
if(res != true) {return cb("waitForConditionInBrowser failure for: " + conditionExpr);}
cb(null, res);
}
]);
};
module.exports = protocol;

View File

@@ -0,0 +1,61 @@
var SPECIAL_KEYS = {
'NULL': '\uE000',
'Cancel': '\uE001',
'Help': '\uE002',
'Back space': '\uE003',
'Tab': '\uE004',
'Clear': '\uE005',
'Return': '\uE006',
'Enter': '\uE007',
'Shift': '\uE008',
'Control': '\uE009',
'Alt': '\uE00A',
'Pause': '\uE00B',
'Escape': '\uE00C',
'Key': 'Code',
'Space': '\uE00D',
'Pageup': '\uE00E',
'Pagedown': '\uE00F',
'End': '\uE010',
'Home': '\uE011',
'Left arrow': '\uE012',
'Up arrow': '\uE013',
'Right arrow': '\uE014',
'Down arrow': '\uE015',
'Insert': '\uE016',
'Delete': '\uE017',
'Semicolon': '\uE018',
'Equals': '\uE019',
'Numpad 0': '\uE01A',
'Numpad 1': '\uE01B',
'Numpad 2': '\uE01C',
'Numpad 3': '\uE01D',
'Numpad 4': '\uE01E',
'Numpad 5': '\uE01F',
'Numpad 6': '\uE020',
'Numpad 7': '\uE021',
'Numpad 8': '\uE022',
'Numpad 9': '\uE023',
'Multiply': '\uE024',
'Add': '\uE025',
'Separator': '\uE026',
'Subtract': '\uE027',
'Decimal': '\uE028',
'Divide': '\uE029',
'F1': '\uE031',
'F2': '\uE032',
'F3': '\uE033',
'F4': '\uE034',
'F5': '\uE035',
'F6': '\uE036',
'F7': '\uE037',
'F8': '\uE038',
'F9': '\uE039',
'F10': '\uE03A',
'F11': '\uE03B',
'F12': '\uE03C',
'Command': '\uE03D',
'Meta': '\uE03D'
};
module.exports = SPECIAL_KEYS;