webdriver 5.11.10 → 5.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/command.js CHANGED
@@ -24,61 +24,36 @@ function _default(method, endpointUri, commandInfo) {
24
24
  isHubCommand = false
25
25
  } = commandInfo;
26
26
  return function protocolCommand(...args) {
27
- let endpoint = endpointUri; // clone endpointUri in case we change it
28
-
27
+ let endpoint = endpointUri;
29
28
  const commandParams = [...variables.map(v => Object.assign(v, {
30
- /**
31
- * url variables are:
32
- */
33
29
  required: true,
34
- // always required as they are part of the endpoint
35
- type: 'string' // have to be always type of string
36
-
30
+ type: 'string'
37
31
  })), ...parameters];
38
32
  const commandUsage = `${command}(${commandParams.map(p => p.name).join(', ')})`;
39
33
  const moreInfo = `\n\nFor more info see ${ref}\n`;
40
34
  const body = {};
41
- /**
42
- * parameter check
43
- */
44
-
45
35
  const minAllowedParams = commandParams.filter(param => param.required).length;
46
36
 
47
37
  if (args.length < minAllowedParams || args.length > commandParams.length) {
48
38
  const parameterDescription = commandParams.length ? `\n\nProperty Description:\n${commandParams.map(p => ` "${p.name}" (${p.type}): ${p.description}`).join('\n')}` : '';
49
39
  throw new Error(`Wrong parameters applied for ${command}\n` + `Usage: ${commandUsage}` + parameterDescription + moreInfo);
50
40
  }
51
- /**
52
- * parameter type check
53
- */
54
-
55
41
 
56
42
  for (const [i, arg] of Object.entries(args)) {
57
43
  const commandParam = commandParams[i];
58
44
 
59
45
  if (!(0, _utils.isValidParameter)(arg, commandParam.type)) {
60
- /**
61
- * ignore if argument is not required
62
- */
63
46
  if (typeof arg === 'undefined' && !commandParam.required) {
64
47
  continue;
65
48
  }
66
49
 
67
50
  throw new Error(`Malformed type for "${commandParam.name}" parameter of command ${command}\n` + `Expected: ${commandParam.type}\n` + `Actual: ${(0, _utils.getArgumentType)(arg)}` + moreInfo);
68
51
  }
69
- /**
70
- * inject url variables
71
- */
72
-
73
52
 
74
53
  if (i < variables.length) {
75
- endpoint = endpoint.replace(`:${commandParams[i].name}`, arg);
54
+ endpoint = endpoint.replace(`:${commandParams[i].name}`, encodeURIComponent(encodeURIComponent(arg)));
76
55
  continue;
77
56
  }
78
- /**
79
- * rest of args are part of body payload
80
- */
81
-
82
57
 
83
58
  body[commandParams[i].name] = arg;
84
59
  }
@@ -5,103 +5,52 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.DEFAULTS = void 0;
7
7
  const DEFAULTS = {
8
- /**
9
- * protocol of automation driver
10
- */
11
8
  protocol: {
12
9
  type: 'string',
13
10
  default: 'http',
14
11
  match: /(http|https)/
15
12
  },
16
-
17
- /**
18
- * hostname of automation driver
19
- */
20
13
  hostname: {
21
14
  type: 'string',
22
15
  default: 'localhost'
23
16
  },
24
-
25
- /**
26
- * port of automation driver
27
- */
28
17
  port: {
29
18
  type: 'number',
30
19
  default: 4444
31
20
  },
32
-
33
- /**
34
- * path to WebDriver endpoints
35
- */
36
21
  path: {
37
22
  type: 'string',
38
23
  default: '/wd/hub'
39
24
  },
40
-
41
- /**
42
- * A key-value store of query parameters to be added to every selenium request
43
- */
44
25
  queryParams: {
45
26
  type: 'object'
46
27
  },
47
-
48
- /**
49
- * capability of WebDriver session
50
- */
51
28
  capabilities: {
52
29
  type: 'object',
53
30
  required: true
54
31
  },
55
-
56
- /**
57
- * Level of logging verbosity
58
- */
59
32
  logLevel: {
60
33
  type: 'string',
61
34
  default: 'info',
62
35
  match: /(trace|debug|info|warn|error|silent)/
63
36
  },
64
-
65
- /**
66
- * Timeout for any request to the Selenium server
67
- */
68
37
  connectionRetryTimeout: {
69
38
  type: 'number',
70
39
  default: 90000
71
40
  },
72
-
73
- /**
74
- * Count of request retries to the Selenium server
75
- */
76
41
  connectionRetryCount: {
77
42
  type: 'number',
78
43
  default: 3
79
44
  },
80
-
81
- /**
82
- * cloud user if applicable
83
- */
84
45
  user: {
85
46
  type: 'string'
86
47
  },
87
-
88
- /**
89
- * access key to user
90
- */
91
48
  key: {
92
49
  type: 'string'
93
50
  },
94
-
95
- /**
96
- * Override default agent
97
- */
98
51
  agent: {
99
52
  type: 'object'
100
53
  },
101
-
102
- /**
103
- * Pass custom headers
104
- */
105
54
  headers: {
106
55
  type: 'object'
107
56
  }
package/build/index.js CHANGED
@@ -41,7 +41,9 @@ var _chromium = _interopRequireDefault(require("../protocol/chromium.json"));
41
41
 
42
42
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
43
43
 
44
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
44
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
45
+
46
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
45
47
 
46
48
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
47
49
 
@@ -52,66 +54,35 @@ class WebDriver {
52
54
  if (!options.logLevels || !options.logLevels['webdriver']) {
53
55
  _logger.default.setLevel('webdriver', params.logLevel);
54
56
  }
55
- /**
56
- * the user could have passed in either w3c style or jsonwp style caps
57
- * and we want to pass both styles to the server, which means we need
58
- * to check what style the user sent in so we know how to construct the
59
- * object for the other style
60
- */
61
-
62
-
63
- const [w3cCaps, jsonwpCaps] = params.capabilities && params.capabilities.alwaysMatch
64
- /**
65
- * in case W3C compliant capabilities are provided
66
- */
67
- ? [params.capabilities, params.capabilities.alwaysMatch]
68
- /**
69
- * otherwise assume they passed in jsonwp-style caps (flat object)
70
- */
71
- : [{
57
+
58
+ const [w3cCaps, jsonwpCaps] = params.capabilities && params.capabilities.alwaysMatch ? [params.capabilities, params.capabilities.alwaysMatch] : [{
72
59
  alwaysMatch: params.capabilities,
73
60
  firstMatch: [{}]
74
61
  }, params.capabilities];
75
62
  const sessionRequest = new _request.default('POST', '/session', {
76
63
  capabilities: w3cCaps,
77
- // W3C compliant
78
- desiredCapabilities: jsonwpCaps // JSONWP compliant
79
-
64
+ desiredCapabilities: jsonwpCaps
80
65
  });
81
66
  const response = await sessionRequest.makeRequest(params);
82
- /**
83
- * save original set of capabilities to allow to request the same session again
84
- * (e.g. for reloadSession command in WebdriverIO)
85
- */
86
-
87
67
  params.requestedCapabilities = {
88
68
  w3cCaps,
89
69
  jsonwpCaps
90
- /**
91
- * save actual receveived session details
92
- */
93
-
94
70
  };
95
71
  params.capabilities = response.value.capabilities || response.value;
96
72
  const environment = (0, _utils.environmentDetector)(params);
97
73
  const environmentPrototype = (0, _utils.getEnvironmentVars)(environment);
98
74
  const protocolCommands = (0, _utils.getPrototype)(environment);
99
75
 
100
- const prototype = _objectSpread({}, protocolCommands, environmentPrototype, userPrototype);
76
+ const prototype = _objectSpread({}, protocolCommands, {}, environmentPrototype, {}, userPrototype);
101
77
 
102
78
  const monad = (0, _monad.default)(params, modifier, prototype);
103
79
  return monad(response.value.sessionId || response.sessionId, commandWrapper);
104
80
  }
105
- /**
106
- * allows user to attach to existing sessions
107
- */
108
-
109
81
 
110
82
  static attachToSession(options = {}, modifier, userPrototype = {}, commandWrapper) {
111
83
  if (typeof options.sessionId !== 'string') {
112
84
  throw new Error('sessionId is required to attach to existing session');
113
- } // logLevel can be undefined in watch mode when SIGINT is called
114
-
85
+ }
115
86
 
116
87
  if (options.logLevel !== undefined) {
117
88
  _logger.default.setLevel('webdriver', options.logLevel);
@@ -122,7 +93,7 @@ class WebDriver {
122
93
  const environmentPrototype = (0, _utils.getEnvironmentVars)(options);
123
94
  const protocolCommands = (0, _utils.getPrototype)(options);
124
95
 
125
- const prototype = _objectSpread({}, protocolCommands, environmentPrototype, userPrototype);
96
+ const prototype = _objectSpread({}, protocolCommands, {}, environmentPrototype, {}, userPrototype);
126
97
 
127
98
  const monad = (0, _monad.default)(options, modifier, prototype);
128
99
  return monad(options.sessionId, commandWrapper);
@@ -135,10 +106,6 @@ class WebDriver {
135
106
  static get DEFAULTS() {
136
107
  return _constants.DEFAULTS;
137
108
  }
138
- /**
139
- * Protocols
140
- */
141
-
142
109
 
143
110
  static get WebDriverProtocol() {
144
111
  return _webdriver.default;
@@ -161,9 +128,5 @@ class WebDriver {
161
128
  }
162
129
 
163
130
  }
164
- /**
165
- * Helper methods consumed by webdriverio package
166
- */
167
-
168
131
 
169
132
  exports.default = WebDriver;
package/build/monad.js CHANGED
@@ -14,29 +14,17 @@ var _utils = require("./utils");
14
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
15
 
16
16
  const SCOPE_TYPES = {
17
- 'browser':
18
- /* istanbul ignore next */
19
- function Browser() {},
20
- 'element':
21
- /* istanbul ignore next */
22
- function Element() {}
17
+ 'browser': function Browser() {},
18
+ 'element': function Element() {}
23
19
  };
24
20
 
25
21
  function WebDriver(options, modifier, propertiesObject = {}) {
26
- /**
27
- * In order to allow named scopes for elements we have to propagate that
28
- * info within the `propertiesObject` object. This doesn't have any functional
29
- * advantages just provides better description of objects when debugging them
30
- */
31
22
  const scopeType = SCOPE_TYPES[propertiesObject.scope] || SCOPE_TYPES['browser'];
32
23
  delete propertiesObject.scope;
33
24
  const prototype = Object.create(scopeType.prototype);
34
25
  const log = (0, _logger.default)('webdriver');
35
26
  const eventHandler = new _events.EventEmitter();
36
27
  const EVENTHANDLER_FUNCTIONS = Object.getPrototypeOf(eventHandler);
37
- /**
38
- * WebDriver monad
39
- */
40
28
 
41
29
  function unit(sessionId, commandWrapper) {
42
30
  propertiesObject.commandList = {
@@ -44,11 +32,6 @@ function WebDriver(options, modifier, propertiesObject = {}) {
44
32
  };
45
33
  propertiesObject.options = {
46
34
  value: options
47
- /**
48
- * allow to wrap commands if necessary
49
- * e.g. in wdio-cli to make them synchronous
50
- */
51
-
52
35
  };
53
36
 
54
37
  if (typeof commandWrapper === 'function') {
@@ -63,25 +46,14 @@ function WebDriver(options, modifier, propertiesObject = {}) {
63
46
  propertiesObject[commandName].configurable = true;
64
47
  }
65
48
  }
66
- /**
67
- * overwrite native element commands with user defined
68
- */
69
-
70
49
 
71
50
  _utils.overwriteElementCommands.call(this, propertiesObject);
72
- /**
73
- * assign propertiesObject to itself so the client can be recreated
74
- */
75
-
76
51
 
77
52
  propertiesObject['__propertiesObject__'] = {
78
53
  value: propertiesObject
79
54
  };
80
55
  let client = Object.create(prototype, propertiesObject);
81
56
  client.sessionId = sessionId;
82
- /**
83
- * register capabilities only to browser scope
84
- */
85
57
 
86
58
  if (scopeType.name === 'Browser') {
87
59
  client.capabilities = options.capabilities;
@@ -95,9 +67,6 @@ function WebDriver(options, modifier, propertiesObject = {}) {
95
67
  const customCommand = typeof commandWrapper === 'function' ? commandWrapper(name, func) : func;
96
68
 
97
69
  if (attachToElement) {
98
- /**
99
- * add command to every multiremote instance
100
- */
101
70
  if (instances) {
102
71
  Object.values(instances).forEach(instance => {
103
72
  instance.__propertiesObject__[name] = {
@@ -113,32 +82,16 @@ function WebDriver(options, modifier, propertiesObject = {}) {
113
82
  unit.lift(name, customCommand, proto);
114
83
  }
115
84
  };
116
- /**
117
- * overwriteCommand
118
- * @param {String} name command name to be overwritten
119
- * @param {Function} func function to replace original command with;
120
- * takes original function as first argument.
121
- * @param {boolean=} attachToElement overwrite browser command (false) or element command (true)
122
- * @param {Object=} proto prototype to add function to (optional)
123
- * @param {Object=} instances multiremote instances
124
- */
125
-
126
85
 
127
86
  client.overwriteCommand = function (name, func, attachToElement = false, proto, instances) {
128
87
  let customCommand = typeof commandWrapper === 'function' ? commandWrapper(name, func) : func;
129
88
 
130
89
  if (attachToElement) {
131
90
  if (instances) {
132
- /**
133
- * add command to every multiremote instance
134
- */
135
91
  Object.values(instances).forEach(instance => {
136
92
  instance.__propertiesObject__.__elementOverrides__.value[name] = customCommand;
137
93
  });
138
94
  } else {
139
- /**
140
- * regular mode
141
- */
142
95
  this.__propertiesObject__.__elementOverrides__.value[name] = customCommand;
143
96
  }
144
97
  } else if (client[name]) {
@@ -152,32 +105,15 @@ function WebDriver(options, modifier, propertiesObject = {}) {
152
105
 
153
106
  return client;
154
107
  }
155
- /**
156
- * Enhance monad prototype with function
157
- * @param {String} name name of function to attach to prototype
158
- * @param {Function} func function to be added to prototype
159
- * @param {Object} proto prototype to add function to (optional)
160
- * @param {Function} origCommand original command to be passed to custom command as first argument
161
- */
162
-
163
108
 
164
109
  unit.lift = function (name, func, proto, origCommand) {
165
110
  (proto || prototype)[name] = function next(...args) {
166
111
  log.info('COMMAND', (0, _utils.commandCallStructure)(name, args));
167
- /**
168
- * set name of function for better error stack
169
- */
170
-
171
112
  Object.defineProperty(func, 'name', {
172
113
  value: name,
173
114
  writable: false
174
115
  });
175
116
  const result = func.apply(this, origCommand ? [origCommand, ...args] : args);
176
- /**
177
- * always transform result into promise as we don't know whether or not
178
- * the user is running tests with wdio-sync or not
179
- */
180
-
181
117
  Promise.resolve(result).then(res => {
182
118
  log.info('RESULT', res);
183
119
  this.emit('result', {
@@ -188,10 +124,6 @@ function WebDriver(options, modifier, propertiesObject = {}) {
188
124
  return result;
189
125
  };
190
126
  };
191
- /**
192
- * register event emitter
193
- */
194
-
195
127
 
196
128
  for (let eventCommand in EVENTHANDLER_FUNCTIONS) {
197
129
  prototype[eventCommand] = function (...args) {
package/build/request.js CHANGED
@@ -66,10 +66,6 @@ class WebDriverRequest extends _events.default {
66
66
  agent: options.agent || agents[options.protocol],
67
67
  headers: typeof options.headers === 'object' ? options.headers : {},
68
68
  qs: typeof options.queryParams === 'object' ? options.queryParams : {}
69
- /**
70
- * only apply body property if existing
71
- */
72
-
73
69
  };
74
70
 
75
71
  if (this.body && (Object.keys(this.body).length || this.method === 'POST')) {
@@ -78,21 +74,12 @@ class WebDriverRequest extends _events.default {
78
74
  'Content-Length': Buffer.byteLength(JSON.stringify(requestOptions.body), 'UTF-8')
79
75
  });
80
76
  }
81
- /**
82
- * if we don't have a session id we set it here, unless we call commands that don't require session ids, for
83
- * example /sessions. The call to /sessions is not connected to a session itself and it therefore doesn't
84
- * require it
85
- */
86
-
87
77
 
88
78
  if (this.requiresSessionId && !sessionId) {
89
79
  throw new Error('A sessionId is required for this command');
90
80
  }
91
81
 
92
82
  requestOptions.uri = _url.default.parse(`${options.protocol}://` + `${options.hostname}:${options.port}` + (this.isHubCommand ? this.endpoint : _path.default.join(options.path, this.endpoint.replace(':sessionId', sessionId))));
93
- /**
94
- * send authentication credentials only when creating new session
95
- */
96
83
 
97
84
  if (this.endpoint === '/session' && options.user && options.key) {
98
85
  requestOptions.auth = {
@@ -100,10 +87,6 @@ class WebDriverRequest extends _events.default {
100
87
  pass: options.key
101
88
  };
102
89
  }
103
- /**
104
- * if the environment variable "STRICT_SSL" is defined as "false", it doesn't require SSL certificates to be valid.
105
- */
106
-
107
90
 
108
91
  requestOptions.strictSSL = !(process.env.STRICT_SSL === 'false' || process.env.strict_ssl === 'false');
109
92
  return requestOptions;
@@ -118,16 +101,8 @@ class WebDriverRequest extends _events.default {
118
101
 
119
102
  return new Promise((resolve, reject) => (0, _request.default)(fullRequestOptions, (err, response, body) => {
120
103
  const error = err || (0, _utils.getErrorFromResponseBody)(body);
121
- /**
122
- * hub commands don't follow standard response formats
123
- * and can have empty bodies
124
- */
125
104
 
126
105
  if (this.isHubCommand) {
127
- /**
128
- * if body contains HTML the command was called on a node
129
- * directly without using a hub, therefor throw
130
- */
131
106
  if (typeof body === 'string' && body.startsWith('<!DOCTYPE html>')) {
132
107
  return reject(new Error('Command can only be called to a Selenium Hub'));
133
108
  }
@@ -136,10 +111,6 @@ class WebDriverRequest extends _events.default {
136
111
  value: body || null
137
112
  };
138
113
  }
139
- /**
140
- * Resolve only if successful response
141
- */
142
-
143
114
 
144
115
  if (!err && (0, _utils.isSuccessfulResponse)(response.statusCode, body)) {
145
116
  this.emit('response', {
@@ -147,11 +118,6 @@ class WebDriverRequest extends _events.default {
147
118
  });
148
119
  return resolve(body);
149
120
  }
150
- /**
151
- * stop retrying as this will never be successful.
152
- * we will handle this at the elementErrorHandler
153
- */
154
-
155
121
 
156
122
  if (error.name === 'stale element reference') {
157
123
  log.warn('Request encountered a stale element - terminating request');
@@ -160,11 +126,6 @@ class WebDriverRequest extends _events.default {
160
126
  });
161
127
  return reject(error);
162
128
  }
163
- /**
164
- * stop retrying if totalRetryCount was exceeded or there is no reason to
165
- * retry, e.g. if sessionId is invalid
166
- */
167
-
168
129
 
169
130
  if (retryCount >= totalRetryCount || error.message.includes('invalid session id')) {
170
131
  log.error('Request failed due to', error);
package/build/utils.js CHANGED
@@ -44,35 +44,16 @@ var _selenium = _interopRequireDefault(require("../protocol/selenium.json"));
44
44
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
45
45
 
46
46
  const log = (0, _logger.default)('webdriver');
47
- /**
48
- * check if WebDriver requests was successful
49
- * @param {Object} body body payload of response
50
- * @return {Boolean} true if request was successful
51
- */
52
47
 
53
48
  function isSuccessfulResponse(statusCode, body) {
54
- /**
55
- * response contains a body
56
- */
57
49
  if (!body || typeof body.value === 'undefined') {
58
50
  log.debug('request failed due to missing body');
59
51
  return false;
60
52
  }
61
- /**
62
- * ignore failing element request to enable lazy loading capability
63
- */
64
53
 
65
-
66
- if (body.status === 7 && body.value && body.value.message && (body.value.message.toLowerCase().startsWith('no such element') || // Appium
67
- body.value.message === 'An element could not be located on the page using the given search parameters.' || // Internet Explorter
68
- body.value.message.toLowerCase().startsWith('unable to find element'))) {
54
+ if (body.status === 7 && body.value && body.value.message && (body.value.message.toLowerCase().startsWith('no such element') || body.value.message === 'An element could not be located on the page using the given search parameters.' || body.value.message.toLowerCase().startsWith('unable to find element'))) {
69
55
  return true;
70
56
  }
71
- /**
72
- * if it has a status property, it should be 0
73
- * (just here to stay backwards compatible to the jsonwire protocol)
74
- */
75
-
76
57
 
77
58
  if (body.status && body.status !== 0) {
78
59
  log.debug(`request failed due to status ${body.status}`);
@@ -80,26 +61,14 @@ function isSuccessfulResponse(statusCode, body) {
80
61
  }
81
62
 
82
63
  const hasErrorResponse = body.value && (body.value.error || body.value.stackTrace || body.value.stacktrace);
83
- /**
84
- * check status code
85
- */
86
64
 
87
65
  if (statusCode === 200 && !hasErrorResponse) {
88
66
  return true;
89
67
  }
90
- /**
91
- * if an element was not found we don't flag it as failed request because
92
- * we lazy load it
93
- */
94
-
95
68
 
96
69
  if (statusCode === 404 && body.value && body.value.error === 'no such element') {
97
70
  return true;
98
71
  }
99
- /**
100
- * that has no error property (Appium only)
101
- */
102
-
103
72
 
104
73
  if (hasErrorResponse) {
105
74
  log.debug('request failed due to response error:', body.value.error);
@@ -108,14 +77,6 @@ function isSuccessfulResponse(statusCode, body) {
108
77
 
109
78
  return true;
110
79
  }
111
- /**
112
- * checks if command argument is valid according to specificiation
113
- *
114
- * @param {*} arg command argument
115
- * @param {Object} expectedType parameter type (e.g. `number`, `string[]` or `(number|string)`)
116
- * @return {Boolean} true if argument is valid
117
- */
118
-
119
80
 
120
81
  function isValidParameter(arg, expectedType) {
121
82
  let shouldBeArray = false;
@@ -124,19 +85,12 @@ function isValidParameter(arg, expectedType) {
124
85
  expectedType = expectedType.slice(0, -2);
125
86
  shouldBeArray = true;
126
87
  }
127
- /**
128
- * check type of each individual array element
129
- */
130
-
131
88
 
132
89
  if (shouldBeArray) {
133
90
  if (!Array.isArray(arg)) {
134
91
  return false;
135
92
  }
136
93
  } else {
137
- /**
138
- * transform to array to have a unified check
139
- */
140
94
  arg = [arg];
141
95
  }
142
96
 
@@ -150,18 +104,10 @@ function isValidParameter(arg, expectedType) {
150
104
 
151
105
  return true;
152
106
  }
153
- /**
154
- * get type of command argument
155
- */
156
-
157
107
 
158
108
  function getArgumentType(arg) {
159
109
  return arg === null ? 'null' : typeof arg;
160
110
  }
161
- /**
162
- * creates the base prototype for the webdriver monad
163
- */
164
-
165
111
 
166
112
  function getPrototype({
167
113
  isW3C,
@@ -171,30 +117,7 @@ function getPrototype({
171
117
  isSeleniumStandalone
172
118
  }) {
173
119
  const prototype = {};
174
- const ProtocolCommands = (0, _lodash.default)(
175
- /**
176
- * if mobile apply JSONWire and WebDriver protocol because
177
- * some legacy JSONWire commands are still used in Appium
178
- * (e.g. set/get geolocation)
179
- */
180
- isMobile ? (0, _lodash.default)({}, _jsonwp.default, _webdriver.default) : isW3C ? _webdriver.default : _jsonwp.default,
181
- /**
182
- * only apply mobile protocol if session is actually for mobile
183
- */
184
- isMobile ? (0, _lodash.default)({}, _mjsonwp.default, _appium.default) : {},
185
- /**
186
- * only apply special Chrome commands if session is using Chrome
187
- */
188
- isChrome ? _chromium.default : {},
189
- /**
190
- * only Sauce Labs specific vendor commands
191
- */
192
- isSauce ? _saucelabs.default : {},
193
- /**
194
- * only apply special commands when running tests using
195
- * Selenium Grid or Selenium Standalone server
196
- */
197
- isSeleniumStandalone ? _selenium.default : {});
120
+ const ProtocolCommands = (0, _lodash.default)(isMobile ? (0, _lodash.default)({}, _jsonwp.default, _webdriver.default) : isW3C ? _webdriver.default : _jsonwp.default, isMobile ? (0, _lodash.default)({}, _mjsonwp.default, _appium.default) : {}, isChrome ? _chromium.default : {}, isSauce ? _saucelabs.default : {}, isSeleniumStandalone ? _selenium.default : {});
198
121
 
199
122
  for (const [endpoint, methods] of Object.entries(ProtocolCommands)) {
200
123
  for (const [method, commandData] of Object.entries(methods)) {
@@ -206,11 +129,6 @@ function getPrototype({
206
129
 
207
130
  return prototype;
208
131
  }
209
- /**
210
- * get command call structure
211
- * (for logging purposes)
212
- */
213
-
214
132
 
215
133
  function commandCallStructure(commandName, args) {
216
134
  const callArgs = args.map(arg => {
@@ -230,108 +148,40 @@ function commandCallStructure(commandName, args) {
230
148
  }).join(', ');
231
149
  return `${commandName}(${callArgs})`;
232
150
  }
233
- /**
234
- * check if session is based on W3C protocol based on the /session response
235
- * @param {Object} capabilities caps of session response
236
- * @return {Boolean} true if W3C (browser)
237
- */
238
-
239
151
 
240
152
  function isW3C(capabilities) {
241
- /**
242
- * JSONWire protocol doesn't return a property `capabilities`.
243
- * Also check for Appium response as it is using JSONWire protocol for most of the part.
244
- */
245
153
  if (!capabilities) {
246
154
  return false;
247
155
  }
248
- /**
249
- * assume session to be a WebDriver session when
250
- * - capabilities are returned
251
- * (https://w3c.github.io/webdriver/#dfn-new-sessions)
252
- * - it is an Appium session (since Appium is full W3C compliant)
253
- */
254
-
255
156
 
256
157
  const isAppium = capabilities.automationName || capabilities.deviceName;
257
- const hasW3CCaps = capabilities.platformName && capabilities.browserVersion && (
258
- /**
259
- * local safari and BrowserStack don't provide platformVersion therefor
260
- * check also if setWindowRect is provided
261
- */
262
- capabilities.platformVersion || Object.prototype.hasOwnProperty.call(capabilities, 'setWindowRect'));
158
+ const hasW3CCaps = capabilities.platformName && capabilities.browserVersion && (capabilities.platformVersion || Object.prototype.hasOwnProperty.call(capabilities, 'setWindowRect'));
263
159
  return Boolean(hasW3CCaps || isAppium);
264
160
  }
265
- /**
266
- * check if session is run by Chromedriver
267
- * @param {Object} capabilities caps of session response
268
- * @return {Boolean} true if run by Chromedriver
269
- */
270
-
271
161
 
272
162
  function isChrome(caps) {
273
163
  return Boolean(caps.chrome) || Boolean(caps['goog:chromeOptions']);
274
164
  }
275
- /**
276
- * check if current platform is mobile device
277
- *
278
- * @param {Object} caps capabilities
279
- * @return {Boolean} true if platform is mobile device
280
- */
281
-
282
165
 
283
166
  function isMobile(caps) {
284
- return Boolean(typeof caps['appium-version'] !== 'undefined' || typeof caps['device-type'] !== 'undefined' || typeof caps['deviceType'] !== 'undefined' || typeof caps['device-orientation'] !== 'undefined' || typeof caps['deviceOrientation'] !== 'undefined' || typeof caps.deviceName !== 'undefined' || // Check browserName for specific values
285
- caps.browserName === '' || caps.browserName !== undefined && (caps.browserName.toLowerCase() === 'ipad' || caps.browserName.toLowerCase() === 'iphone' || caps.browserName.toLowerCase() === 'android'));
167
+ return Boolean(typeof caps['appium-version'] !== 'undefined' || typeof caps['device-type'] !== 'undefined' || typeof caps['deviceType'] !== 'undefined' || typeof caps['device-orientation'] !== 'undefined' || typeof caps['deviceOrientation'] !== 'undefined' || typeof caps.deviceName !== 'undefined' || caps.browserName === '' || caps.browserName !== undefined && (caps.browserName.toLowerCase() === 'ipad' || caps.browserName.toLowerCase() === 'iphone' || caps.browserName.toLowerCase() === 'android'));
286
168
  }
287
- /**
288
- * check if session is run on iOS device
289
- * @param {Object} capabilities caps of session response
290
- * @return {Boolean} true if run on iOS device
291
- */
292
-
293
169
 
294
170
  function isIOS(caps) {
295
171
  return Boolean(caps.platformName && caps.platformName.match(/iOS/i) || caps.deviceName && caps.deviceName.match(/(iPad|iPhone)/i));
296
172
  }
297
- /**
298
- * check if session is run on Android device
299
- * @param {Object} capabilities caps of session response
300
- * @return {Boolean} true if run on Android device
301
- */
302
-
303
173
 
304
174
  function isAndroid(caps) {
305
175
  return Boolean(caps.platformName && caps.platformName.match(/Android/i) || caps.browserName && caps.browserName.match(/Android/i));
306
176
  }
307
- /**
308
- * detects if session is run on Sauce with extended debugging enabled
309
- * @param {string} hostname hostname of session request
310
- * @param {object} capabilities session capabilities
311
- * @return {Boolean} true if session is running on Sauce with extended debugging enabled
312
- */
313
-
314
177
 
315
178
  function isSauce(hostname, caps) {
316
179
  return Boolean(caps.extendedDebugging || caps['sauce:options'] && caps['sauce:options'].extendedDebugging);
317
180
  }
318
- /**
319
- * detects if session is run using Selenium Standalone server
320
- * @param {object} capabilities session capabilities
321
- * @return {Boolean} true if session is run with Selenium Standalone Server
322
- */
323
-
324
181
 
325
182
  function isSeleniumStandalone(caps) {
326
183
  return Boolean(caps['webdriver.remote.sessionid']);
327
184
  }
328
- /**
329
- * returns information about the environment
330
- * @param {Object} hostname name of the host to run the session against
331
- * @param {Object} capabilities caps of session response
332
- * @return {Object} object with environment flags
333
- */
334
-
335
185
 
336
186
  function environmentDetector({
337
187
  hostname,
@@ -348,12 +198,6 @@ function environmentDetector({
348
198
  isSeleniumStandalone: isSeleniumStandalone(capabilities)
349
199
  };
350
200
  }
351
- /**
352
- * helper method to determine the error from webdriver response
353
- * @param {Object} body body object
354
- * @return {Object} error
355
- */
356
-
357
201
 
358
202
  function getErrorFromResponseBody(body) {
359
203
  if (!body) {
@@ -369,8 +213,7 @@ function getErrorFromResponseBody(body) {
369
213
  }
370
214
 
371
215
  return new CustomRequestError(body);
372
- } //Exporting for testability
373
-
216
+ }
374
217
 
375
218
  class CustomRequestError extends Error {
376
219
  constructor(body) {
@@ -384,11 +227,6 @@ class CustomRequestError extends Error {
384
227
  }
385
228
 
386
229
  }
387
- /**
388
- * overwrite native element commands with user defined
389
- * @param {object} propertiesObject propertiesObject
390
- */
391
-
392
230
 
393
231
  exports.CustomRequestError = CustomRequestError;
394
232
 
@@ -414,8 +252,7 @@ function overwriteElementCommands(propertiesObject) {
414
252
  const newCommand = function (...args) {
415
253
  const element = this;
416
254
  return userDefinedCommand.apply(element, [function origCommandFunction() {
417
- const context = this || element; // respect explicite context binding, use element as default
418
-
255
+ const context = this || element;
419
256
  return origCommand.apply(context, arguments);
420
257
  }, ...args]);
421
258
  };
@@ -431,13 +268,6 @@ function overwriteElementCommands(propertiesObject) {
431
268
  value: {}
432
269
  };
433
270
  }
434
- /**
435
- * return all supported flags and return them in a format so we can attach them
436
- * to the instance protocol
437
- * @param {Object} options driver instance or option object containing these flags
438
- * @return {Object} prototype object
439
- */
440
-
441
271
 
442
272
  function getEnvironmentVars({
443
273
  isW3C,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webdriver",
3
- "version": "5.11.10",
3
+ "version": "5.12.1",
4
4
  "description": "A Node.js bindings implementation for the W3C WebDriver and Mobile JSONWire Protocol",
5
5
  "author": "Christian Bromann <christian@saucelabs.com>",
6
6
  "homepage": "https://github.com/webdriverio/webdriverio/tree/master/packages/webdriver",
@@ -30,11 +30,11 @@
30
30
  "url": "https://github.com/webdriverio/webdriverio/issues"
31
31
  },
32
32
  "dependencies": {
33
- "@wdio/config": "^5.11.0",
34
- "@wdio/logger": "^5.11.0",
33
+ "@wdio/config": "^5.12.1",
34
+ "@wdio/logger": "^5.12.1",
35
35
  "deepmerge": "^4.0.0",
36
36
  "lodash.merge": "^4.6.1",
37
37
  "request": "^2.83.0"
38
38
  },
39
- "gitHead": "644a371a294292fae1d866d14d0e42dd75156c68"
39
+ "gitHead": "848151e5fdcb8b694c1a273b9b69852c22875687"
40
40
  }
@@ -1401,5 +1401,33 @@
1401
1401
  }
1402
1402
  }
1403
1403
  }
1404
+ },
1405
+ "/session/:sessionId/appium/execute_driver": {
1406
+ "POST": {
1407
+ "command": "driverScript",
1408
+ "description": "This command allows you to define a webdriverio script in a string and send it to the Appium server to be executed locally to the server itself, thus reducing latency that might otherwise occur along with each command.",
1409
+ "ref": "https://github.com/appium/appium/blob/master/docs/en/commands/session/execute-driver.md",
1410
+ "parameters": [{
1411
+ "name": "script",
1412
+ "type": "string",
1413
+ "description": "The script to execute. It has access to a 'driver' object which represents a webdriverio session attached to the current server.",
1414
+ "required": true
1415
+ }, {
1416
+ "name": "type",
1417
+ "type": "string",
1418
+ "description": "The language/framework used in the script. Currently, only 'webdriverio' is supported and is the default.",
1419
+ "required": false
1420
+ }, {
1421
+ "name": "timeout",
1422
+ "type": "number",
1423
+ "description": "The number of milliseconds the script should be allowed to run before being killed by the Appium server. Defaults to the equivalent of 1 hour.",
1424
+ "required": false
1425
+ }],
1426
+ "returns": {
1427
+ "type": "object",
1428
+ "name": "result",
1429
+ "description": "An object containing two fields: 'result', which is the return value of the script itself, and 'logs', which contains 3 inner fields, 'log', 'warn', and 'error', which hold an array of strings logged by console.log, console.warn, and console.error in the script's execution."
1430
+ }
1431
+ }
1404
1432
  }
1405
1433
  }
@@ -414,5 +414,36 @@
414
414
  "description": "The base64-encoded PNG image data comprising the screenshot of the visible region of an element’s bounding rectangle after it has been scrolled into view."
415
415
  }
416
416
  }
417
+ },
418
+ "/session/:sessionId/se/log/types": {
419
+ "GET": {
420
+ "command": "getLogTypes",
421
+ "description": "Get available log types.",
422
+ "ref": "https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#sessionsessionidlogtypes",
423
+ "parameters": [],
424
+ "returns": {
425
+ "type": "String[]",
426
+ "name": "logTypes",
427
+ "description": "The list of available log types, example: browser, driver."
428
+ }
429
+ }
430
+ },
431
+ "/session/:sessionId/se/log": {
432
+ "POST": {
433
+ "command": "getLogs",
434
+ "description": "Get the log for a given log type. Log buffer is reset after each request.",
435
+ "ref": "https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#sessionsessionidlog",
436
+ "parameters": [{
437
+ "name": "type",
438
+ "type": "string",
439
+ "description": "the log type",
440
+ "required": true
441
+ }],
442
+ "returns": {
443
+ "type": "Object[]",
444
+ "name": "logs",
445
+ "description": "The list of log entries."
446
+ }
447
+ }
417
448
  }
418
449
  }
package/webdriver.d.ts CHANGED
@@ -79,7 +79,7 @@ declare namespace WebDriver {
79
79
  args?: string[],
80
80
  profile?: string,
81
81
  log?: FirefoxLogObject,
82
- prefs: {
82
+ prefs?: {
83
83
  [name: string]: string | number | boolean;
84
84
  }
85
85
  }
@@ -213,6 +213,21 @@ declare namespace WebDriver {
213
213
  // wdio-sauce-service specific
214
214
  build?: string;
215
215
 
216
+ // Saucelabs w3c specific
217
+ 'sauce:options'?: {
218
+ [name: string]: any;
219
+ };
220
+
221
+ // Browserstack w3c specific
222
+ 'bstack:options'?: {
223
+ [name: string]: any;
224
+ };
225
+
226
+ // Testingbot w3c specific
227
+ 'tb:options'?: {
228
+ [name: string]: any;
229
+ };
230
+
216
231
  // Appium General Capabilities
217
232
  automationName?: string;
218
233
  platformVersion?: string;
@@ -369,19 +384,69 @@ declare namespace WebDriver {
369
384
  interface ClientOptions {
370
385
  capabilities: DesiredCapabilities;
371
386
  isW3C: boolean;
387
+ isChrome: boolean;
372
388
  isAndroid: boolean;
373
389
  isMobile: boolean;
374
390
  isIOS: boolean;
375
391
  sessionId: string;
376
392
  }
377
393
 
394
+ // object with no match
395
+ interface ProtocolCommandResponse {
396
+ [key: string]: any;
397
+ }
398
+
399
+ // webdriver.json
400
+ interface SessionReturn extends DesiredCapabilities, ProtocolCommandResponse { }
401
+
402
+ interface StatusReturn extends ProtocolCommandResponse {
403
+ ready?: boolean,
404
+ message?: string,
405
+ }
406
+
407
+ interface WindowHandle {
408
+ handle: string,
409
+ type: string
410
+ }
411
+
412
+ interface RectReturn {
413
+ x: number,
414
+ y: number,
415
+ width: number,
416
+ height: number
417
+ }
418
+
419
+ // appium.json
420
+ interface StringsReturn {
421
+ [key:string]: string
422
+ }
423
+
424
+ interface SettingsReturn extends ProtocolCommandResponse {
425
+ shouldUseCompactResponses?: boolean,
426
+ elementResponseAttributes?: string,
427
+ ignoreUnimportantViews?: boolean,
428
+ allowInvisibleElements?: boolean,
429
+ enableNotificationListener?: boolean,
430
+ actionAcknowledgmentTimeout?: number,
431
+ keyInjectionDelay?: number,
432
+ scrollAcknowledgmentTimeout?: number,
433
+ waitForIdleTimeout?: number,
434
+ waitForSelectorTimeout?: number,
435
+ normalizeTagNames?: boolean,
436
+ shutdownOnPowerDisconnect?: boolean,
437
+ mjpegServerScreenshotQuality?: number,
438
+ mjpegServerFramerate?: number,
439
+ screenshotQuality?: number,
440
+ mjpegScalingFactor?: number,
441
+ }
442
+
378
443
  // generated typings
379
444
  // webdriver types
380
445
  interface Client {
381
- newSession(capabilities: object): object;
446
+ newSession(capabilities: object): SessionReturn;
382
447
  deleteSession(): void;
383
- status(): object;
384
- getTimeouts(): object;
448
+ status(): StatusReturn;
449
+ getTimeouts(): Timeouts;
385
450
  setTimeouts(implicit?: number, pageLoad?: number, script?: number): void;
386
451
  getUrl(): string;
387
452
  navigateTo(url: string): string;
@@ -392,39 +457,39 @@ declare namespace WebDriver {
392
457
  getWindowHandle(): string;
393
458
  closeWindow(): void;
394
459
  switchToWindow(handle: string): void;
395
- createWindow(type: string): object;
460
+ createWindow(type: string): WindowHandle;
396
461
  getWindowHandles(): string[];
397
462
  switchToFrame(id: (number|string|object|null)): void;
398
463
  switchToParentFrame(): void;
399
- getWindowRect(): object;
400
- setWindowRect(x: (number|null), y: (number|null), width: (number|null), height: (number|null)): object;
401
- maximizeWindow(): object;
402
- minimizeWindow(): object;
403
- fullscreenWindow(): object;
464
+ getWindowRect(): RectReturn;
465
+ setWindowRect(x: (number|null), y: (number|null), width: (number|null), height: (number|null)): RectReturn;
466
+ maximizeWindow(): RectReturn;
467
+ minimizeWindow(): RectReturn;
468
+ fullscreenWindow(): RectReturn;
404
469
  findElement(using: string, value: string): string;
405
470
  findElements(using: string, value: string): string[];
406
- findElementFromElement(using: string, value: string): string;
407
- findElementsFromElement(using: string, value: string): string[];
471
+ findElementFromElement(elementId: string, using: string, value: string): string;
472
+ findElementsFromElement(elementId: string, using: string, value: string): string[];
408
473
  getActiveElement(): string;
409
- isElementSelected(): boolean;
410
- isElementDisplayed(): boolean;
411
- getElementAttribute(name: string): string;
412
- getElementProperty(name: string): string;
413
- getElementCSSValue(propertyName: string): string;
414
- getElementText(): string;
415
- getElementTagName(): string;
416
- getElementRect(): object;
417
- isElementEnabled(): boolean;
418
- elementClick(): void;
419
- elementClear(): void;
420
- elementSendKeys(text: string, value?: string[]): void;
474
+ isElementSelected(elementId: string): boolean;
475
+ isElementDisplayed(elementId: string): boolean;
476
+ getElementAttribute(elementId: string, name: string): string;
477
+ getElementProperty(elementId: string, name: string): string;
478
+ getElementCSSValue(elementId: string, propertyName: string): string;
479
+ getElementText(elementId: string): string;
480
+ getElementTagName(elementId: string): string;
481
+ getElementRect(elementId: string): RectReturn;
482
+ isElementEnabled(elementId: string): boolean;
483
+ elementClick(elementId: string): void;
484
+ elementClear(elementId: string): void;
485
+ elementSendKeys(elementId: string, text: string, value?: string[]): void;
421
486
  getPageSource(): string;
422
487
  executeScript(script: string, args?: (string|object|number|boolean|undefined)[]): any;
423
488
  executeAsyncScript(script: string, args: (string|object|number|boolean|undefined)[]): any;
424
489
  getAllCookies(): object[];
425
490
  addCookie(cookie: object): void;
426
491
  deleteAllCookies(): void;
427
- getNamedCookie(name: string): object;
492
+ getNamedCookie(name: string): Cookie;
428
493
  deleteCookie(name: string): void;
429
494
  performActions(actions: object[]): void;
430
495
  releaseActions(): void;
@@ -433,7 +498,7 @@ declare namespace WebDriver {
433
498
  getAlertText(): string;
434
499
  sendAlertText(text: string): void;
435
500
  takeScreenshot(): string;
436
- takeElementScreenshot(scroll?: boolean): string;
501
+ takeElementScreenshot(elementId: string, scroll?: boolean): string;
437
502
  }
438
503
 
439
504
  // appium types
@@ -479,10 +544,10 @@ declare namespace WebDriver {
479
544
  reset(): void;
480
545
  background(seconds: (number|null)): void;
481
546
  endCoverage(intent: string, path: string): void;
482
- getStrings(language?: string, stringFile?: string): object;
483
- setValueImmediate(value: string): void;
484
- replaceValue(value: string): void;
485
- getSettings(): object;
547
+ getStrings(language?: string, stringFile?: string): StringsReturn;
548
+ setValueImmediate(elementId: string, value: string): void;
549
+ replaceValue(elementId: string, value: string): void;
550
+ getSettings(): SettingsReturn;
486
551
  updateSettings(settings: object): void;
487
552
  receiveAsyncResponse(response: object): void;
488
553
  gsmCall(phoneNumber: string, action: string): void;
@@ -496,14 +561,15 @@ declare namespace WebDriver {
496
561
  getClipboard(contentType?: string): string;
497
562
  touchPerform(actions: object[]): void;
498
563
  multiTouchPerform(actions: object[]): void;
564
+ driverScript(script: string, type?: string, timeout?: number): ProtocolCommandResponse;
499
565
  }
500
566
 
501
567
  // jsonwp types
502
568
  interface Client {
503
- status(): object;
504
- newSession(desiredCapabilities: object, requiredCapabilities: object): object;
569
+ status(): StatusReturn;
570
+ newSession(desiredCapabilities: object, requiredCapabilities: object): SessionReturn;
505
571
  getSessions(): object[];
506
- getSession(): object;
572
+ getSession(): ProtocolCommandResponse;
507
573
  deleteSession(): void;
508
574
  setTimeouts(type: string, ms: number): void;
509
575
  setAsyncTimeout(ms: number): void;
@@ -520,31 +586,31 @@ declare namespace WebDriver {
520
586
  switchToWindow(name: string): void;
521
587
  switchToFrame(id: (string|number|object|null)): void;
522
588
  switchToParentFrame(): void;
523
- getWindowPosition(): object;
524
- setWindowPosition(x: number, y: number): object;
525
- _getWindowSize(): object;
589
+ getWindowPosition(): ProtocolCommandResponse;
590
+ setWindowPosition(x: number, y: number): ProtocolCommandResponse;
591
+ _getWindowSize(): ProtocolCommandResponse;
526
592
  _setWindowSize(width: number, height: number): void;
527
593
  maximizeWindow(): void;
528
594
  findElement(using: string, value: string): string;
529
595
  findElements(using: string, value: string): string[];
530
- findElementFromElement(using: string, value: string): string;
531
- findElementsFromElement(using: string, value: string): string[];
596
+ findElementFromElement(elementId: string, using: string, value: string): string;
597
+ findElementsFromElement(elementId: string, using: string, value: string): string[];
532
598
  getActiveElement(): string;
533
- isElementSelected(): boolean;
534
- isElementDisplayed(): boolean;
535
- getElementAttribute(name: string): string|null;
536
- getElementCSSValue(propertyName: string): string;
537
- getElementText(): string;
538
- getElementTagName(): string;
539
- getElementLocation(): object;
540
- getElementLocationInView(): object;
541
- getElementSize(): object;
542
- isElementEnabled(): boolean;
543
- elementClick(): void;
544
- elementEquals(otherElementId: string): boolean;
545
- elementSubmit(): void;
546
- elementClear(): void;
547
- elementSendKeys(value: string[]): void;
599
+ isElementSelected(elementId: string): boolean;
600
+ isElementDisplayed(elementId: string): boolean;
601
+ getElementAttribute(elementId: string, name: string): string|null;
602
+ getElementCSSValue(elementId: string, propertyName: string): string;
603
+ getElementText(elementId: string): string;
604
+ getElementTagName(elementId: string): string;
605
+ getElementLocation(elementId: string): ProtocolCommandResponse;
606
+ getElementLocationInView(elementId: string): ProtocolCommandResponse;
607
+ getElementSize(elementId: string): ProtocolCommandResponse;
608
+ isElementEnabled(elementId: string): boolean;
609
+ elementClick(elementId: string): void;
610
+ elementEquals(elementId: string, otherElementId: string): boolean;
611
+ elementSubmit(elementId: string): void;
612
+ elementClear(elementId: string): void;
613
+ elementSendKeys(elementId: string, value: string[]): void;
548
614
  sendKeys(value: string[]): void;
549
615
  getPageSource(): string;
550
616
  executeScript(script: string, args?: (string|object|number|boolean|undefined)[]): any;
@@ -578,7 +644,7 @@ declare namespace WebDriver {
578
644
  touchDoubleClick(element: string): void;
579
645
  touchLongClick(element: string): void;
580
646
  touchFlick(xoffset?: number, yoffset?: number, element?: string, speed?: number, xspeed?: number, yspeed?: number): void;
581
- getGeoLocation(): object;
647
+ getGeoLocation(): ProtocolCommandResponse;
582
648
  setGeoLocation(location: object): void;
583
649
  getLocalStorage(): string[];
584
650
  setLocalStorage(key: string, value: string): void;
@@ -616,10 +682,10 @@ declare namespace WebDriver {
616
682
  isAutoReporting(): boolean;
617
683
  setAutoReporting(enabled: boolean): object|null;
618
684
  isLoading(): boolean;
619
- takeHeapSnapshot(): object;
685
+ takeHeapSnapshot(): ProtocolCommandResponse;
620
686
  getNetworkConnection(): number;
621
687
  setNetworkConnection(parameters: object): number;
622
- getNetworkConditions(): object;
688
+ getNetworkConditions(): ProtocolCommandResponse;
623
689
  setNetworkConditions(network_conditions: object, network_name?: string): void;
624
690
  deleteNetworkConditions(): void;
625
691
  sendCommand(cmd: string, params: object): void;
@@ -627,18 +693,20 @@ declare namespace WebDriver {
627
693
  generateTestReport(message: string, group: string): void;
628
694
  file(file: string): string;
629
695
  launchApp(id: string): void;
630
- getElementValue(): string|null;
631
- elementHover(): void;
696
+ getElementValue(elementId: string): string|null;
697
+ elementHover(elementId: string): void;
632
698
  touchPinch(x: number, y: number, scale: number): void;
633
699
  freeze(): void;
634
700
  resume(): void;
635
701
  shutdown(): void;
636
- takeElementScreenshot(scroll?: boolean): string;
702
+ takeElementScreenshot(elementId: string, scroll?: boolean): string;
703
+ getLogTypes(): string[];
704
+ getLogs(type: string): object[];
637
705
  }
638
706
 
639
707
  // saucelabs types
640
708
  interface Client {
641
- getPageLogs(type: string): object;
709
+ getPageLogs(type: string): ProtocolCommandResponse;
642
710
  throttleNetwork(condition: (string|object)): void;
643
711
  throttleCPU(rate: number): void;
644
712
  interceptRequest(rule: object): void;
@@ -648,9 +716,9 @@ declare namespace WebDriver {
648
716
  // selenium types
649
717
  interface Client {
650
718
  file(file: string): string;
651
- getHubConfig(): object;
652
- gridTestSession(session: string): object;
653
- gridProxyDetails(id: string): object;
719
+ getHubConfig(): ProtocolCommandResponse;
720
+ gridTestSession(session: string): ProtocolCommandResponse;
721
+ gridProxyDetails(id: string): ProtocolCommandResponse;
654
722
  manageSeleniumHubLifecycle(action: string): void;
655
723
  }
656
724