UNPKG

webdriverjs

Version:

A nodejs bindings implementation for selenium 2.0/webdriver

216 lines (180 loc) 6.39 kB
'use strict'; /** * RequestHandler */ var url = require('url'), request = require('request'), merge = require('deepmerge'), errorCodes = require('./errorCodes'); module.exports = RequestHandler; function RequestHandler(instance) { var options = instance.options || {}; this.instance = instance; this.sessionID = null; this.startPath = '/wd/hub'; // Wdjs calls RequestHandler with `host` badly set // A host is an hostname+port if (options.host !== undefined) { options.hostname = options.host; delete options.host; } // default request options this.defaultOptions = { hostname: '127.0.0.1', port: 4444, protocol: 'http' }; // add user specific attributes this.defaultOptions = merge(this.defaultOptions, options); // set auth from user and password configs if(this.defaultOptions.user && this.defaultOptions.key) { this.auth = { user: this.defaultOptions.user, pass: this.defaultOptions.key }; delete this.defaultOptions.user; delete this.defaultOptions.key; } }; /** * set session ID for the next request * * @param {Object} response response data with header information */ RequestHandler.prototype.setSessionID = function(body,response,data) { this.sessionID = body.sessionId; // check if we got a session id /* istanbul ignore next */ if(!this.sessionID) { this.instance.eventHandler.emit('error', { err: { code: 'NOSESSIONID', message: body.message }, body: body, requestOptions: this.fullRequestOptions, response: response }); return; } this.instance.eventHandler.emit('init', { sessionID: this.sessionID, options: body.value, desiredCapabilities: data.desiredCapabilities }); this.instance.logger.log('SET SESSION ID ' + this.sessionID); }; /** * merges default options with request options * * @param {Object} requestOptions request options */ RequestHandler.prototype.createOptions = function(requestOptions, data) { var newOptions = {}; newOptions.uri = url.parse( this.defaultOptions.protocol + '://' + this.defaultOptions.hostname + ':' + this.defaultOptions.port + this.startPath + requestOptions.path.replace(':sessionId', this.sessionID || '')); // send authentication credentials only when creating new session if (requestOptions.path === '/session' && this.auth !== undefined) { newOptions.auth = this.auth; } if (requestOptions.method) { newOptions.method = requestOptions.method; } newOptions.json = true; newOptions.followAllRedirects = true; newOptions.headers = { 'Connection': 'keep-alive', 'Accept': 'application/json' }; if (Object.keys(data).length > 0) { var reqData = JSON.stringify(data); newOptions.body = reqData; newOptions.method = 'POST'; newOptions.headers = merge(newOptions.headers, { 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': Buffer.byteLength(JSON.stringify(data), 'UTF-8') }); } return newOptions; }; /** * creates a http request with its given options and send the protocol * command to the webdriver server * * @param {Object} requestOptions defines url, method and other request options * @param {Object} data contains request data * @param {Function} callback gets fired if server got a response */ RequestHandler.prototype.create = function(requestOptions, data, callback) { if (typeof requestOptions === 'string') { requestOptions = { path: requestOptions } } if (typeof data === 'function') { callback = data; data = {}; } this.fullRequestOptions = this.createOptions(requestOptions, data); this.instance.eventHandler.emit('command', { method: this.fullRequestOptions.method || 'GET', uri: this.fullRequestOptions.uri, data: data }); request(this.fullRequestOptions, function(err, response, body) { var error = null; var makeError = require('./makeError'); if(err || (body && body.status !== 0)) { this.instance.eventHandler.emit('error', { err: err, requestData: data, requestOptions: this.fullRequestOptions, response: response, body: body }); if(body) { error = makeError({ status: body.status, type: errorCodes[body.status] ? errorCodes[body.status].id : 'unknown', message: errorCodes[body.status] ? errorCodes[body.status].message : 'unknown', orgStatusMessage: body.value ? body.value.message : '' }); } else { error = makeError({ status: -1, type: 'ECONNREFUSED', message: 'Couldn\'t connect to selenium server', orgStatusMessage: 'Couldn\'t connect to selenium server' }); // TODO skip rest of driver commands return callback(error); } } // if we dont have a session id we set it here, unless we // call commands that dont require session ids, for // example /sessions. The call to /sessions is not // connected to a session itself and it therefore doesnt // require it if(this.sessionID === null && this.fullRequestOptions.requiresSession !== false) { this.setSessionID(body,response,data); } if(body === undefined) { body = { status: 0, orgStatusMessage: errorCodes[0].message }; } this.instance.eventHandler.emit('result', { requestData: data, requestOptions: this.fullRequestOptions, response: response, body: body, }); if (callback) { callback(error, error ? null : body); } }.bind(this)); };