goog.provide('webdriver.http.Client');
goog.provide('webdriver.http.Executor');
goog.provide('webdriver.http.Request');
goog.provide('webdriver.http.Response');
goog.require('bot.ErrorCode');
goog.require('goog.array');
goog.require('webdriver.CommandExecutor');
goog.require('webdriver.CommandName');
goog.require('webdriver.logging');
webdriver.http.Client = function() {
};
webdriver.http.Client.prototype.send = function(request) {};
webdriver.http.Executor = function(client) {
this.client_ = client;
this.customCommands_ = {};
this.log_ = webdriver.logging.getLogger('webdriver.http.Executor');
};
webdriver.http.Executor.prototype.defineCommand = function(
name, method, path) {
this.customCommands_[name] = {method: method, path: path};
};
webdriver.http.Executor.prototype.execute = function(command) {
var resource =
this.customCommands_[command.getName()] ||
webdriver.http.Executor.COMMAND_MAP_[command.getName()];
if (!resource) {
throw new Error('Unrecognized command: ' + command.getName());
}
var parameters = command.getParameters();
var path = webdriver.http.Executor.buildPath_(resource.path, parameters);
var request = new webdriver.http.Request(resource.method, path, parameters);
var log = this.log_;
log.finer(function() {
return '>>>\n' + request;
});
return this.client_.send(request).then(function(response) {
log.finer(function() {
return '<<<\n' + response;
});
return webdriver.http.Executor.parseHttpResponse_(
(response));
});
};
webdriver.http.Executor.buildPath_ = function(path, parameters) {
var pathParameters = path.match(/\/:(\w+)\b/g);
if (pathParameters) {
for (var i = 0; i < pathParameters.length; ++i) {
var key = pathParameters[i].substring(2);
if (key in parameters) {
var value = parameters[key];
if (value && value['ELEMENT']) {
value = value['ELEMENT'];
}
path = path.replace(pathParameters[i], '/' + value);
delete parameters[key];
} else {
throw new Error('Missing required parameter: ' + key);
}
}
}
return path;
};
webdriver.http.Executor.parseHttpResponse_ = function(httpResponse) {
try {
return (JSON.parse(
httpResponse.body));
} catch (ex) {
}
var response = {
'status': bot.ErrorCode.SUCCESS,
'value': httpResponse.body.replace(/\r\n/g, '\n')
};
if (!(httpResponse.status > 199 && httpResponse.status < 300)) {
response['status'] = httpResponse.status == 404 ?
bot.ErrorCode.UNKNOWN_COMMAND :
bot.ErrorCode.UNKNOWN_ERROR;
}
return response;
};
webdriver.http.Executor.COMMAND_MAP_ = (function() {
return new Builder().
put(webdriver.CommandName.GET_SERVER_STATUS, get('/status')).
put(webdriver.CommandName.NEW_SESSION, post('/session')).
put(webdriver.CommandName.GET_SESSIONS, get('/sessions')).
put(webdriver.CommandName.DESCRIBE_SESSION, get('/session/:sessionId')).
put(webdriver.CommandName.QUIT, del('/session/:sessionId')).
put(webdriver.CommandName.CLOSE, del('/session/:sessionId/window')).
put(webdriver.CommandName.GET_CURRENT_WINDOW_HANDLE,
get('/session/:sessionId/window_handle')).
put(webdriver.CommandName.GET_WINDOW_HANDLES,
get('/session/:sessionId/window_handles')).
put(webdriver.CommandName.GET_CURRENT_URL,
get('/session/:sessionId/url')).
put(webdriver.CommandName.GET, post('/session/:sessionId/url')).
put(webdriver.CommandName.GO_BACK, post('/session/:sessionId/back')).
put(webdriver.CommandName.GO_FORWARD,
post('/session/:sessionId/forward')).
put(webdriver.CommandName.REFRESH,
post('/session/:sessionId/refresh')).
put(webdriver.CommandName.ADD_COOKIE,
post('/session/:sessionId/cookie')).
put(webdriver.CommandName.GET_ALL_COOKIES,
get('/session/:sessionId/cookie')).
put(webdriver.CommandName.DELETE_ALL_COOKIES,
del('/session/:sessionId/cookie')).
put(webdriver.CommandName.DELETE_COOKIE,
del('/session/:sessionId/cookie/:name')).
put(webdriver.CommandName.FIND_ELEMENT,
post('/session/:sessionId/element')).
put(webdriver.CommandName.FIND_ELEMENTS,
post('/session/:sessionId/elements')).
put(webdriver.CommandName.GET_ACTIVE_ELEMENT,
post('/session/:sessionId/element/active')).
put(webdriver.CommandName.FIND_CHILD_ELEMENT,
post('/session/:sessionId/element/:id/element')).
put(webdriver.CommandName.FIND_CHILD_ELEMENTS,
post('/session/:sessionId/element/:id/elements')).
put(webdriver.CommandName.CLEAR_ELEMENT,
post('/session/:sessionId/element/:id/clear')).
put(webdriver.CommandName.CLICK_ELEMENT,
post('/session/:sessionId/element/:id/click')).
put(webdriver.CommandName.SEND_KEYS_TO_ELEMENT,
post('/session/:sessionId/element/:id/value')).
put(webdriver.CommandName.SUBMIT_ELEMENT,
post('/session/:sessionId/element/:id/submit')).
put(webdriver.CommandName.GET_ELEMENT_TEXT,
get('/session/:sessionId/element/:id/text')).
put(webdriver.CommandName.GET_ELEMENT_TAG_NAME,
get('/session/:sessionId/element/:id/name')).
put(webdriver.CommandName.IS_ELEMENT_SELECTED,
get('/session/:sessionId/element/:id/selected')).
put(webdriver.CommandName.IS_ELEMENT_ENABLED,
get('/session/:sessionId/element/:id/enabled')).
put(webdriver.CommandName.IS_ELEMENT_DISPLAYED,
get('/session/:sessionId/element/:id/displayed')).
put(webdriver.CommandName.GET_ELEMENT_LOCATION,
get('/session/:sessionId/element/:id/location')).
put(webdriver.CommandName.GET_ELEMENT_SIZE,
get('/session/:sessionId/element/:id/size')).
put(webdriver.CommandName.GET_ELEMENT_ATTRIBUTE,
get('/session/:sessionId/element/:id/attribute/:name')).
put(webdriver.CommandName.GET_ELEMENT_VALUE_OF_CSS_PROPERTY,
get('/session/:sessionId/element/:id/css/:propertyName')).
put(webdriver.CommandName.ELEMENT_EQUALS,
get('/session/:sessionId/element/:id/equals/:other')).
put(webdriver.CommandName.TAKE_ELEMENT_SCREENSHOT,
get('/session/:sessionId/element/:id/screenshot')).
put(webdriver.CommandName.SWITCH_TO_WINDOW,
post('/session/:sessionId/window')).
put(webdriver.CommandName.MAXIMIZE_WINDOW,
post('/session/:sessionId/window/:windowHandle/maximize')).
put(webdriver.CommandName.GET_WINDOW_POSITION,
get('/session/:sessionId/window/:windowHandle/position')).
put(webdriver.CommandName.SET_WINDOW_POSITION,
post('/session/:sessionId/window/:windowHandle/position')).
put(webdriver.CommandName.GET_WINDOW_SIZE,
get('/session/:sessionId/window/:windowHandle/size')).
put(webdriver.CommandName.SET_WINDOW_SIZE,
post('/session/:sessionId/window/:windowHandle/size')).
put(webdriver.CommandName.SWITCH_TO_FRAME,
post('/session/:sessionId/frame')).
put(webdriver.CommandName.GET_PAGE_SOURCE,
get('/session/:sessionId/source')).
put(webdriver.CommandName.GET_TITLE,
get('/session/:sessionId/title')).
put(webdriver.CommandName.EXECUTE_SCRIPT,
post('/session/:sessionId/execute')).
put(webdriver.CommandName.EXECUTE_ASYNC_SCRIPT,
post('/session/:sessionId/execute_async')).
put(webdriver.CommandName.SCREENSHOT,
get('/session/:sessionId/screenshot')).
put(webdriver.CommandName.SET_TIMEOUT,
post('/session/:sessionId/timeouts')).
put(webdriver.CommandName.SET_SCRIPT_TIMEOUT,
post('/session/:sessionId/timeouts/async_script')).
put(webdriver.CommandName.IMPLICITLY_WAIT,
post('/session/:sessionId/timeouts/implicit_wait')).
put(webdriver.CommandName.MOVE_TO, post('/session/:sessionId/moveto')).
put(webdriver.CommandName.CLICK, post('/session/:sessionId/click')).
put(webdriver.CommandName.DOUBLE_CLICK,
post('/session/:sessionId/doubleclick')).
put(webdriver.CommandName.MOUSE_DOWN,
post('/session/:sessionId/buttondown')).
put(webdriver.CommandName.MOUSE_UP, post('/session/:sessionId/buttonup')).
put(webdriver.CommandName.MOVE_TO, post('/session/:sessionId/moveto')).
put(webdriver.CommandName.SEND_KEYS_TO_ACTIVE_ELEMENT,
post('/session/:sessionId/keys')).
put(webdriver.CommandName.TOUCH_SINGLE_TAP,
post('/session/:sessionId/touch/click')).
put(webdriver.CommandName.TOUCH_DOUBLE_TAP,
post('/session/:sessionId/touch/doubleclick')).
put(webdriver.CommandName.TOUCH_DOWN,
post('/session/:sessionId/touch/down')).
put(webdriver.CommandName.TOUCH_UP,
post('/session/:sessionId/touch/up')).
put(webdriver.CommandName.TOUCH_MOVE,
post('/session/:sessionId/touch/move')).
put(webdriver.CommandName.TOUCH_SCROLL,
post('/session/:sessionId/touch/scroll')).
put(webdriver.CommandName.TOUCH_LONG_PRESS,
post('/session/:sessionId/touch/longclick')).
put(webdriver.CommandName.TOUCH_FLICK,
post('/session/:sessionId/touch/flick')).
put(webdriver.CommandName.ACCEPT_ALERT,
post('/session/:sessionId/accept_alert')).
put(webdriver.CommandName.DISMISS_ALERT,
post('/session/:sessionId/dismiss_alert')).
put(webdriver.CommandName.GET_ALERT_TEXT,
get('/session/:sessionId/alert_text')).
put(webdriver.CommandName.SET_ALERT_TEXT,
post('/session/:sessionId/alert_text')).
put(webdriver.CommandName.GET_LOG, post('/session/:sessionId/log')).
put(webdriver.CommandName.GET_AVAILABLE_LOG_TYPES,
get('/session/:sessionId/log/types')).
put(webdriver.CommandName.GET_SESSION_LOGS, post('/logs')).
put(webdriver.CommandName.UPLOAD_FILE, post('/session/:sessionId/file')).
build();
function Builder() {
var map = {};
this.put = function(name, resource) {
map[name] = resource;
return this;
};
this.build = function() {
return map;
};
}
function post(path) { return resource('POST', path); }
function del(path) { return resource('DELETE', path); }
function get(path) { return resource('GET', path); }
function resource(method, path) { return {method: method, path: path}; }
})();
webdriver.http.headersToString_ = function(headers) {
var ret = [];
for (var key in headers) {
ret.push(key + ': ' + headers[key]);
}
return ret.join('\n');
};
webdriver.http.Request = function(method, path, opt_data) {
this.method = method;
this.path = path;
this.data = opt_data || {};
this.headers = {'Accept': 'application/json; charset=utf-8'};
};
webdriver.http.Request.prototype.toString = function() {
return [
this.method + ' ' + this.path + ' HTTP/1.1',
webdriver.http.headersToString_(this.headers),
'',
JSON.stringify(this.data)
].join('\n');
};
webdriver.http.Response = function(status, headers, body) {
this.status = status;
this.body = body;
this.headers = {};
for (var header in headers) {
this.headers[header.toLowerCase()] = headers[header];
}
};
webdriver.http.Response.fromXmlHttpRequest = function(xhr) {
var headers = {};
if (xhr.getAllResponseHeaders) {
var tmp = xhr.getAllResponseHeaders();
if (tmp) {
tmp = tmp.replace(/\r\n/g, '\n').split('\n');
goog.array.forEach(tmp, function(header) {
var parts = header.split(/\s*:\s*/, 2);
if (parts[0]) {
headers[parts[0]] = parts[1] || '';
}
});
}
}
var status = xhr.status || 200;
return new webdriver.http.Response(status, headers,
xhr.responseText.replace(/\0/g, ''));
};
webdriver.http.Response.prototype.toString = function() {
var headers = webdriver.http.headersToString_(this.headers);
var ret = ['HTTP/1.1 ' + this.status, headers];
if (headers) {
ret.push('');
}
if (this.body) {
ret.push(this.body);
}
return ret.join('\n');
};