Files
BeWoPlaner/BeWoPlanerMobil/node_modules/wd/lib/webdriver.js
Lyndon Jetten fda2c306b5 MoK: Report Viewer hinzugefügt
FaC: Das alte Flag von Terminen, die in die Zeiterfassung übernommen worden sind, wird ebenfalls berücksichtigt.
2023-03-13 19:39:04 +01:00

259 lines
8.0 KiB
JavaScript

var EventEmitter = require('events').EventEmitter,
_ = require("lodash"),
util = require( 'util' ),
url = require('url'),
http = require('http'),
https = require('https'),
__slice = Array.prototype.slice,
utils = require("./utils"),
findCallback = utils.findCallback,
niceArgs = utils.niceArgs,
niceResp = utils.niceResp,
strip = utils.strip,
deprecator = utils.deprecator,
httpUtils = require('./http-utils'),
config = require('./config'),
Element = require('./element'),
commands = require('./commands'),
SAUCE_API_HOST = process.env["SAUCE_API_HOST"] || "saucelabs.com";
// Webdriver client main class
// configUrl: url object constructed via url.parse
var Webdriver = module.exports = function(configUrl) {
EventEmitter.call( this );
this.sessionID = null;
this.httpAgent = null;
this.configUrl = configUrl;
this.sauceTestPageRoot = "https://" + SAUCE_API_HOST + "/jobs";
this.sauceRestRoot = "https://" + SAUCE_API_HOST + "/rest/v1";
// config url without auth
this.noAuthConfigUrl = url.parse(url.format(this.configUrl));
delete this.noAuthConfigUrl.auth;
this.defaultCapabilities = {
browserName: 'firefox'
, version: ''
, javascriptEnabled: true
, platform: 'ANY'
};
this._httpConfig = _.clone(config.httpConfig);
};
//inherit from EventEmitter
util.inherits( Webdriver, EventEmitter );
// creates a new element
Webdriver.prototype.newElement = function(jsonWireElement) {
return new Element(jsonWireElement, this);
};
/**
* attach(sessionID, cb) -> cb(err)
* Connect to an already-active session.
*/
Webdriver.prototype.attach = function(sessionID) {
var cb = findCallback(arguments);
this.sessionID = sessionID;
if(cb) { cb(null); }
};
/**
* detach(cb) -> cb(err)
* Detach from the current session.
*/
Webdriver.prototype.detach = function() {
var cb = findCallback(arguments);
this.sessionID = null;
if(cb) { cb(null); }
};
commands.chain = function(obj){
deprecator.warn('chain', 'chain api has been deprecated, use promise chain instead.');
require("./deprecated-chain").patch(this);
return this.chain(obj);
};
Webdriver.prototype._init = function() {
delete this.sessionID;
var _this = this;
var fargs = utils.varargs(arguments);
var cb = fargs.callback,
desired = fargs.all[0] || {};
var _desired = _.clone(desired);
if(desired.deviceName || desired.device || desired.wdNoDefaults ||
desired['wd-no-defaults']) {
// no default or appium caps, we dont default
delete _desired.wdNoDefaults;
delete _desired['wd-no-defaults'];
} else {
// using default
_.defaults(_desired, this.defaultCapabilities);
}
// http options
this.httpAgent = (this.configUrl.protocol === 'https:')
? new https.Agent({ keepAlive: false })
: new http.Agent({ keepAlive: false });
var httpOpts = httpUtils.newHttpOpts('POST', _this._httpConfig);
httpOpts.agent = this.httpAgent;
var url = httpUtils.buildInitUrl(this.configUrl);
var data = {};
// building request
if (_desired.allowW3C || _desired.forceW3C) {
data.capabilities = {
alwaysMatch: utils.prefixCapabilities(_desired),
firstMatch: [{}],
};
}
if (!_desired.forceW3C) {
data.desiredCapabilities = _desired;
}
httpUtils.emit(this, httpOpts.method, url, data);
httpOpts.prepareToSend(url, data);
httpUtils.requestWithRetry(httpOpts, this._httpConfig, this.emit.bind(this), function(err, res, data) {
if(err) { return cb(err); }
var resData;
var jsonData;
// retrieving session
try{
jsonData = JSON.parse(data);
_this.sessionID = jsonData.value ? jsonData.value.sessionId : false;
_this.w3c = false;
resData = jsonData.value;
if(!_this.sessionID && jsonData.status === 0 ){
_this.sessionID = jsonData.sessionId;
_this.w3c = true;
}
} catch(ignore){}
if(!_this.sessionID){
// attempting to retrieve the session the OLD old way
try{
var locationArr = res.headers.location.replace(/\/$/, '').split('/');
_this.sessionID = locationArr[locationArr.length - 1];
} catch(ignore){}
}
if (_this.sessionID) {
if (/saucelabs\.com/.exec(url.hostname)) {
_this.emit('status', '\nDriving the web on session: ' + _this.sauceTestPageRoot + '/' + _this.sessionID + '\n');
} else {
_this.emit('status', '\nDriving the web on session: ' + _this.sessionID + '\n');
}
if (cb) { cb(null, _this.sessionID, resData); }
} else {
data = strip(data);
if (cb) {
err = new Error('The environment you requested was unavailable.' + ((jsonData && jsonData.value) ? ('\n' + jsonData.value.message) : ''));
err.data = data;
return cb(err);
} else {
/* eslint-disable no-console */
console.error('\x1b[31mError\x1b[0m: The environment you requested was unavailable.\n');
console.error('\x1b[33mReason\x1b[0m:\n');
console.error(data);
console.error('\nFor the available values please consult the WebDriver JSONWireProtocol,');
console.error('located at: \x1b[33mhttp://code.google.com/p/selenium/wiki/JsonWireProtocol#/session\x1b[0m');
/* eslint-enable no-console */
}
}
});
};
// standard jsonwire call
Webdriver.prototype._jsonWireCall = function(opts) {
var _this = this;
// http options init
var httpOpts = httpUtils.newHttpOpts(opts.method, this._httpConfig);
httpOpts.agent = this.httpAgent;
var url = httpUtils.buildJsonCallUrl(this.noAuthConfigUrl, this.sessionID, opts.relPath, opts.absPath);
// building callback
var cb = opts.cb;
if (opts.emit) {
// wrapping cb if we need to emit a message
var _cb = cb;
cb = function() {
var args = __slice.call(arguments, 0);
_this.emit(opts.emit.event, opts.emit.message);
if (_cb) { _cb.apply(_this,args); }
};
}
// logging
httpUtils.emit(this, httpOpts.method, url, opts.data);
// writting data
var data = opts.data || {};
httpOpts.prepareToSend(url, data);
// building request
httpUtils.requestWithRetry(httpOpts, this._httpConfig, this.emit.bind(this), function(err, res, data) {
if(err) { return cb(err); }
data = strip(data);
cb(null, data || "");
});
};
Webdriver.prototype._sauceJobUpdate = function(jsonData, done) {
var _this = this;
if(!this.configUrl || !this.configUrl.auth){
return done(new Error("Missing auth token."));
} else if(!this.configUrl.auth.match(/^.+:.+$/)){
return done(new Error("Invalid auth token."));
}
var jobUpdateUrl = url.resolve(
this.sauceRestRoot.replace(/\/?$/,'/'),
this.configUrl.auth.replace(/:.*$/,'') + '/jobs/' + this.sessionID);
var httpOpts = httpUtils.newHttpOpts('PUT', this._httpConfig);
httpOpts.auth = {
user: this.configUrl.auth.split(':')[0],
pass: this.configUrl.auth.split(':')[1],
};
httpOpts.jar = false; // disable cookies: avoids CSRF issues
httpOpts.prepareToSend(jobUpdateUrl, jsonData);
httpUtils.requestWithoutRetry(httpOpts, this.emit.bind(this), function(err, resp) {
if(err) { return done(err); }
if(resp.statusCode !== 200) {
return done(new Error("Sauce job update failed with http status code:" +
resp.statusCode));
}
httpUtils.emit(_this, 'POST', '/rest/v1/:user/jobs/:sessionID', jsonData);
done();
});
};
_(commands).each(function(fn, name) {
Webdriver.prototype[name] = function() {
var _this = this;
var fargs = utils.varargs(arguments);
this.emit('command', "CALL" , name + niceArgs(fargs.all));
var cb = function(err) {
if(err) {
err.message = '[' + name + niceArgs(fargs.all) + "] " + err.message;
if(fargs.callback) { fargs.callback(err); }
} else {
var cbArgs = __slice.call(arguments, 0);
_this.emit('command', "RESPONSE" , name + niceArgs(fargs.all),
niceResp(_.drop(cbArgs)));
if(fargs.callback) { fargs.callback.apply(null, cbArgs); }
}
};
var args = fargs.all.concat([cb]);
return fn.apply(this, args);
};
});