selenium-webdriver 4.0.0-alpha.7 → 4.0.0-alpha.8

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/lib/http.js CHANGED
@@ -23,21 +23,28 @@
23
23
  * the {@link Executor} to send commands to the remote end.
24
24
  */
25
25
 
26
- 'use strict';
26
+ 'use strict'
27
27
 
28
- const cmd = require('./command');
29
- const error = require('./error');
30
- const logging = require('./logging');
31
- const promise = require('./promise');
32
- const {Session} = require('./session');
33
- const {WebElement} = require('./webdriver');
28
+ const path = require('path')
29
+ const cmd = require('./command')
30
+ const error = require('./error')
31
+ const logging = require('./logging')
32
+ const promise = require('./promise')
33
+ const { Session } = require('./session')
34
+ const { WebElement } = require('./webdriver')
34
35
 
35
36
  const getAttribute = requireAtom(
36
- 'get-attribute.js',
37
- '//javascript/node/selenium-webdriver/lib/atoms:get-attribute.js');
37
+ 'get-attribute.js',
38
+ '//javascript/node/selenium-webdriver/lib/atoms:get-attribute.js'
39
+ )
38
40
  const isDisplayed = requireAtom(
39
- 'is-displayed.js',
40
- '//javascript/node/selenium-webdriver/lib/atoms:is-displayed.js');
41
+ 'is-displayed.js',
42
+ '//javascript/node/selenium-webdriver/lib/atoms:is-displayed.js'
43
+ )
44
+ const findElements = requireAtom(
45
+ 'find-elements.js',
46
+ '//javascript/node/selenium-webdriver/lib/atoms:find-elements.js'
47
+ )
41
48
 
42
49
  /**
43
50
  * @param {string} module
@@ -46,36 +53,36 @@ const isDisplayed = requireAtom(
46
53
  */
47
54
  function requireAtom(module, bazelTarget) {
48
55
  try {
49
- return require('./atoms/' + module);
56
+ return require('./atoms/' + module)
50
57
  } catch (ex) {
51
58
  try {
52
- const file = bazelTarget.slice(2).replace(':', '/');
53
- return require(`../../../../bazel-genfiles/${file}`);
59
+ const file = bazelTarget.slice(2).replace(':', '/')
60
+ console.log(`../../../bazel-bin/${file}`)
61
+ return require(path.resolve(`../../../bazel-bin/${file}`))
54
62
  } catch (ex2) {
55
- console.log(ex2);
63
+ console.log(ex2)
56
64
  throw Error(
57
- `Failed to import atoms module ${module}. If running in dev mode, you`
58
- + ` need to run \`bazel build ${bazelTarget}\` from the project`
59
- + `root: ${ex}`);
65
+ `Failed to import atoms module ${module}. If running in dev mode, you` +
66
+ ` need to run \`bazel build ${bazelTarget}\` from the project` +
67
+ `root: ${ex}`
68
+ )
60
69
  }
61
70
  }
62
71
  }
63
72
 
64
-
65
73
  /**
66
74
  * Converts a headers map to a HTTP header block string.
67
75
  * @param {!Map<string, string>} headers The map to convert.
68
76
  * @return {string} The headers as a string.
69
77
  */
70
78
  function headersToString(headers) {
71
- let ret = [];
72
- headers.forEach(function(value, name) {
73
- ret.push(`${name.toLowerCase()}: ${value}`);
74
- });
75
- return ret.join('\n');
79
+ let ret = []
80
+ headers.forEach(function (value, name) {
81
+ ret.push(`${name.toLowerCase()}: ${value}`)
82
+ })
83
+ return ret.join('\n')
76
84
  }
77
85
 
78
-
79
86
  /**
80
87
  * Represents a HTTP request message. This class is a "partial" request and only
81
88
  * defines the path on the server to send a request to. It is each client's
@@ -89,25 +96,25 @@ class Request {
89
96
  * @param {Object=} opt_data This request's non-serialized JSON payload data.
90
97
  */
91
98
  constructor(method, path, opt_data) {
92
- this.method = /** string */method;
93
- this.path = /** string */path;
94
- this.data = /** Object */opt_data;
95
- this.headers = /** !Map<string, string> */new Map(
96
- [['Accept', 'application/json; charset=utf-8']]);
99
+ this.method = /** string */ method
100
+ this.path = /** string */ path
101
+ this.data = /** Object */ opt_data
102
+ this.headers = /** !Map<string, string> */ new Map([
103
+ ['Accept', 'application/json; charset=utf-8'],
104
+ ])
97
105
  }
98
106
 
99
107
  /** @override */
100
108
  toString() {
101
- let ret = `${this.method} ${this.path} HTTP/1.1\n`;
102
- ret += headersToString(this.headers) + '\n\n';
109
+ let ret = `${this.method} ${this.path} HTTP/1.1\n`
110
+ ret += headersToString(this.headers) + '\n\n'
103
111
  if (this.data) {
104
- ret += JSON.stringify(this.data);
112
+ ret += JSON.stringify(this.data)
105
113
  }
106
- return ret;
114
+ return ret
107
115
  }
108
116
  }
109
117
 
110
-
111
118
  /**
112
119
  * Represents a HTTP response message.
113
120
  * @final
@@ -120,54 +127,54 @@ class Response {
120
127
  * @param {string} body The response body.
121
128
  */
122
129
  constructor(status, headers, body) {
123
- this.status = /** number */status;
124
- this.body = /** string */body;
125
- this.headers = /** !Map<string, string>*/new Map;
130
+ this.status = /** number */ status
131
+ this.body = /** string */ body
132
+ this.headers = /** !Map<string, string>*/ new Map()
126
133
  for (let header in headers) {
127
- this.headers.set(header.toLowerCase(), headers[header]);
134
+ this.headers.set(header.toLowerCase(), headers[header])
128
135
  }
129
136
  }
130
137
 
131
138
  /** @override */
132
139
  toString() {
133
- let ret = `HTTP/1.1 ${this.status}\n${headersToString(this.headers)}\n\n`;
140
+ let ret = `HTTP/1.1 ${this.status}\n${headersToString(this.headers)}\n\n`
134
141
  if (this.body) {
135
- ret += this.body;
142
+ ret += this.body
136
143
  }
137
- return ret;
144
+ return ret
138
145
  }
139
146
  }
140
147
 
141
-
142
- const DEV_ROOT = '../../../../buck-out/gen/javascript/';
143
-
144
148
  /** @enum {!Function} */
145
149
  const Atom = {
146
150
  GET_ATTRIBUTE: getAttribute,
147
- IS_DISPLAYED: isDisplayed
148
- };
149
-
150
-
151
- const LOG = logging.getLogger('webdriver.http');
152
-
151
+ IS_DISPLAYED: isDisplayed,
152
+ FIND_ELEMENTS: findElements,
153
+ }
153
154
 
154
- function post(path) { return resource('POST', path); }
155
- function del(path) { return resource('DELETE', path); }
156
- function get(path) { return resource('GET', path); }
157
- function resource(method, path) { return {method: method, path: path}; }
155
+ const LOG = logging.getLogger('webdriver.http')
158
156
 
157
+ function post(path) {
158
+ return resource('POST', path)
159
+ }
160
+ function del(path) {
161
+ return resource('DELETE', path)
162
+ }
163
+ function get(path) {
164
+ return resource('GET', path)
165
+ }
166
+ function resource(method, path) {
167
+ return { method: method, path: path }
168
+ }
159
169
 
160
170
  /** @typedef {{method: string, path: string}} */
161
- var CommandSpec;
162
-
171
+ var CommandSpec // eslint-disable-line
163
172
 
164
173
  /** @typedef {function(!cmd.Command): !cmd.Command} */
165
- var CommandTransformer;
166
-
174
+ var CommandTransformer // eslint-disable-line
167
175
 
168
176
  class InternalTypeError extends TypeError {}
169
177
 
170
-
171
178
  /**
172
179
  * @param {!cmd.Command} command The initial command.
173
180
  * @param {Atom} atom The name of the atom to execute.
@@ -175,94 +182,151 @@ class InternalTypeError extends TypeError {}
175
182
  */
176
183
  function toExecuteAtomCommand(command, atom, ...params) {
177
184
  if (typeof atom !== 'function') {
178
- throw new InternalTypeError('atom is not a function: ' + typeof atom);
185
+ throw new InternalTypeError('atom is not a function: ' + typeof atom)
179
186
  }
180
187
 
181
188
  return new cmd.Command(cmd.Name.EXECUTE_SCRIPT)
182
- .setParameter('sessionId', command.getParameter('sessionId'))
183
- .setParameter('script', `return (${atom}).apply(null, arguments)`)
184
- .setParameter('args', params.map(param => command.getParameter(param)));
189
+ .setParameter('sessionId', command.getParameter('sessionId'))
190
+ .setParameter('script', `return (${atom}).apply(null, arguments)`)
191
+ .setParameter(
192
+ 'args',
193
+ params.map((param) => command.getParameter(param))
194
+ )
185
195
  }
186
196
 
187
-
188
-
189
197
  /** @const {!Map<string, CommandSpec>} */
190
198
  const COMMAND_MAP = new Map([
191
- [cmd.Name.GET_SERVER_STATUS, get('/status')],
192
- [cmd.Name.NEW_SESSION, post('/session')],
193
- [cmd.Name.GET_SESSIONS, get('/sessions')],
194
- [cmd.Name.QUIT, del('/session/:sessionId')],
195
- [cmd.Name.CLOSE, del('/session/:sessionId/window')],
196
- [cmd.Name.GET_CURRENT_WINDOW_HANDLE, get('/session/:sessionId/window_handle')],
197
- [cmd.Name.GET_WINDOW_HANDLES, get('/session/:sessionId/window_handles')],
198
- [cmd.Name.GET_CURRENT_URL, get('/session/:sessionId/url')],
199
- [cmd.Name.GET, post('/session/:sessionId/url')],
200
- [cmd.Name.GO_BACK, post('/session/:sessionId/back')],
201
- [cmd.Name.GO_FORWARD, post('/session/:sessionId/forward')],
202
- [cmd.Name.REFRESH, post('/session/:sessionId/refresh')],
203
- [cmd.Name.ADD_COOKIE, post('/session/:sessionId/cookie')],
204
- [cmd.Name.GET_ALL_COOKIES, get('/session/:sessionId/cookie')],
205
- [cmd.Name.DELETE_ALL_COOKIES, del('/session/:sessionId/cookie')],
206
- [cmd.Name.DELETE_COOKIE, del('/session/:sessionId/cookie/:name')],
207
- [cmd.Name.FIND_ELEMENT, post('/session/:sessionId/element')],
208
- [cmd.Name.FIND_ELEMENTS, post('/session/:sessionId/elements')],
209
- [cmd.Name.GET_ACTIVE_ELEMENT, post('/session/:sessionId/element/active')],
210
- [cmd.Name.FIND_CHILD_ELEMENT, post('/session/:sessionId/element/:id/element')],
211
- [cmd.Name.FIND_CHILD_ELEMENTS, post('/session/:sessionId/element/:id/elements')],
212
- [cmd.Name.CLEAR_ELEMENT, post('/session/:sessionId/element/:id/clear')],
213
- [cmd.Name.CLICK_ELEMENT, post('/session/:sessionId/element/:id/click')],
214
- [cmd.Name.SEND_KEYS_TO_ELEMENT, post('/session/:sessionId/element/:id/value')],
215
- [cmd.Name.SUBMIT_ELEMENT, post('/session/:sessionId/element/:id/submit')],
216
- [cmd.Name.GET_ELEMENT_TEXT, get('/session/:sessionId/element/:id/text')],
217
- [cmd.Name.GET_ELEMENT_TAG_NAME, get('/session/:sessionId/element/:id/name')],
218
- [cmd.Name.IS_ELEMENT_SELECTED, get('/session/:sessionId/element/:id/selected')],
219
- [cmd.Name.IS_ELEMENT_ENABLED, get('/session/:sessionId/element/:id/enabled')],
220
- [cmd.Name.IS_ELEMENT_DISPLAYED, get('/session/:sessionId/element/:id/displayed')],
221
- [cmd.Name.GET_ELEMENT_LOCATION, get('/session/:sessionId/element/:id/location')],
222
- [cmd.Name.GET_ELEMENT_SIZE, get('/session/:sessionId/element/:id/size')],
223
- [cmd.Name.GET_ELEMENT_ATTRIBUTE, get('/session/:sessionId/element/:id/attribute/:name')],
224
- [cmd.Name.GET_ELEMENT_PROPERTY, get('/session/:sessionId/element/:id/property/:name')],
225
- [cmd.Name.GET_ELEMENT_VALUE_OF_CSS_PROPERTY, get('/session/:sessionId/element/:id/css/:propertyName')],
226
- [cmd.Name.TAKE_ELEMENT_SCREENSHOT, get('/session/:sessionId/element/:id/screenshot')],
227
- [cmd.Name.SWITCH_TO_WINDOW, post('/session/:sessionId/window')],
228
- [cmd.Name.MAXIMIZE_WINDOW, post('/session/:sessionId/window/current/maximize')],
229
- [cmd.Name.GET_WINDOW_POSITION, get('/session/:sessionId/window/current/position')],
230
- [cmd.Name.SET_WINDOW_POSITION, post('/session/:sessionId/window/current/position')],
231
- [cmd.Name.GET_WINDOW_SIZE, get('/session/:sessionId/window/current/size')],
232
- [cmd.Name.SET_WINDOW_SIZE, post('/session/:sessionId/window/current/size')],
233
- [cmd.Name.SWITCH_TO_FRAME, post('/session/:sessionId/frame')],
234
- [cmd.Name.SWITCH_TO_FRAME_PARENT, post('/session/:sessionId/frame/parent')],
235
- [cmd.Name.GET_PAGE_SOURCE, get('/session/:sessionId/source')],
236
- [cmd.Name.GET_TITLE, get('/session/:sessionId/title')],
237
- [cmd.Name.EXECUTE_SCRIPT, post('/session/:sessionId/execute')],
238
- [cmd.Name.EXECUTE_ASYNC_SCRIPT, post('/session/:sessionId/execute_async')],
239
- [cmd.Name.SCREENSHOT, get('/session/:sessionId/screenshot')],
240
- [cmd.Name.GET_TIMEOUT, get('/session/:sessionId/timeouts')],
241
- [cmd.Name.SET_TIMEOUT, post('/session/:sessionId/timeouts')],
242
- [cmd.Name.ACCEPT_ALERT, post('/session/:sessionId/accept_alert')],
243
- [cmd.Name.DISMISS_ALERT, post('/session/:sessionId/dismiss_alert')],
244
- [cmd.Name.GET_ALERT_TEXT, get('/session/:sessionId/alert_text')],
245
- [cmd.Name.SET_ALERT_TEXT, post('/session/:sessionId/alert_text')],
246
- [cmd.Name.GET_LOG, post('/session/:sessionId/log')],
247
- [cmd.Name.GET_AVAILABLE_LOG_TYPES, get('/session/:sessionId/log/types')],
248
- [cmd.Name.GET_SESSION_LOGS, post('/logs')],
249
- [cmd.Name.UPLOAD_FILE, post('/session/:sessionId/file')],
250
- [cmd.Name.LEGACY_ACTION_CLICK, post('/session/:sessionId/click')],
251
- [cmd.Name.LEGACY_ACTION_DOUBLE_CLICK, post('/session/:sessionId/doubleclick')],
252
- [cmd.Name.LEGACY_ACTION_MOUSE_DOWN, post('/session/:sessionId/buttondown')],
253
- [cmd.Name.LEGACY_ACTION_MOUSE_UP, post('/session/:sessionId/buttonup')],
254
- [cmd.Name.LEGACY_ACTION_MOUSE_MOVE, post('/session/:sessionId/moveto')],
255
- [cmd.Name.LEGACY_ACTION_SEND_KEYS, post('/session/:sessionId/keys')],
256
- [cmd.Name.LEGACY_ACTION_TOUCH_DOWN, post('/session/:sessionId/touch/down')],
257
- [cmd.Name.LEGACY_ACTION_TOUCH_UP, post('/session/:sessionId/touch/up')],
258
- [cmd.Name.LEGACY_ACTION_TOUCH_MOVE, post('/session/:sessionId/touch/move')],
259
- [cmd.Name.LEGACY_ACTION_TOUCH_SCROLL, post('/session/:sessionId/touch/scroll')],
260
- [cmd.Name.LEGACY_ACTION_TOUCH_LONG_PRESS, post('/session/:sessionId/touch/longclick')],
261
- [cmd.Name.LEGACY_ACTION_TOUCH_FLICK, post('/session/:sessionId/touch/flick')],
262
- [cmd.Name.LEGACY_ACTION_TOUCH_SINGLE_TAP, post('/session/:sessionId/touch/click')],
263
- [cmd.Name.LEGACY_ACTION_TOUCH_DOUBLE_TAP, post('/session/:sessionId/touch/doubleclick')],
264
- ]);
265
-
199
+ [cmd.Name.GET_SERVER_STATUS, get('/status')],
200
+ [cmd.Name.NEW_SESSION, post('/session')],
201
+ [cmd.Name.GET_SESSIONS, get('/sessions')],
202
+ [cmd.Name.QUIT, del('/session/:sessionId')],
203
+ [cmd.Name.CLOSE, del('/session/:sessionId/window')],
204
+ [
205
+ cmd.Name.GET_CURRENT_WINDOW_HANDLE,
206
+ get('/session/:sessionId/window_handle'),
207
+ ],
208
+ [cmd.Name.GET_WINDOW_HANDLES, get('/session/:sessionId/window_handles')],
209
+ [cmd.Name.GET_CURRENT_URL, get('/session/:sessionId/url')],
210
+ [cmd.Name.GET, post('/session/:sessionId/url')],
211
+ [cmd.Name.GO_BACK, post('/session/:sessionId/back')],
212
+ [cmd.Name.GO_FORWARD, post('/session/:sessionId/forward')],
213
+ [cmd.Name.REFRESH, post('/session/:sessionId/refresh')],
214
+ [cmd.Name.ADD_COOKIE, post('/session/:sessionId/cookie')],
215
+ [cmd.Name.GET_ALL_COOKIES, get('/session/:sessionId/cookie')],
216
+ [cmd.Name.DELETE_ALL_COOKIES, del('/session/:sessionId/cookie')],
217
+ [cmd.Name.DELETE_COOKIE, del('/session/:sessionId/cookie/:name')],
218
+ [cmd.Name.FIND_ELEMENT, post('/session/:sessionId/element')],
219
+ [cmd.Name.FIND_ELEMENTS, post('/session/:sessionId/elements')],
220
+ [cmd.Name.GET_ACTIVE_ELEMENT, post('/session/:sessionId/element/active')],
221
+ [
222
+ cmd.Name.FIND_CHILD_ELEMENT,
223
+ post('/session/:sessionId/element/:id/element'),
224
+ ],
225
+ [
226
+ cmd.Name.FIND_CHILD_ELEMENTS,
227
+ post('/session/:sessionId/element/:id/elements'),
228
+ ],
229
+ [cmd.Name.CLEAR_ELEMENT, post('/session/:sessionId/element/:id/clear')],
230
+ [cmd.Name.CLICK_ELEMENT, post('/session/:sessionId/element/:id/click')],
231
+ [
232
+ cmd.Name.SEND_KEYS_TO_ELEMENT,
233
+ post('/session/:sessionId/element/:id/value'),
234
+ ],
235
+ [cmd.Name.SUBMIT_ELEMENT, post('/session/:sessionId/element/:id/submit')],
236
+ [cmd.Name.GET_ELEMENT_TEXT, get('/session/:sessionId/element/:id/text')],
237
+ [cmd.Name.GET_ELEMENT_TAG_NAME, get('/session/:sessionId/element/:id/name')],
238
+ [
239
+ cmd.Name.IS_ELEMENT_SELECTED,
240
+ get('/session/:sessionId/element/:id/selected'),
241
+ ],
242
+ [cmd.Name.IS_ELEMENT_ENABLED, get('/session/:sessionId/element/:id/enabled')],
243
+ [
244
+ cmd.Name.IS_ELEMENT_DISPLAYED,
245
+ get('/session/:sessionId/element/:id/displayed'),
246
+ ],
247
+ [
248
+ cmd.Name.GET_ELEMENT_LOCATION,
249
+ get('/session/:sessionId/element/:id/location'),
250
+ ],
251
+ [cmd.Name.GET_ELEMENT_SIZE, get('/session/:sessionId/element/:id/size')],
252
+ [
253
+ cmd.Name.GET_ELEMENT_ATTRIBUTE,
254
+ get('/session/:sessionId/element/:id/attribute/:name'),
255
+ ],
256
+ [
257
+ cmd.Name.GET_ELEMENT_PROPERTY,
258
+ get('/session/:sessionId/element/:id/property/:name'),
259
+ ],
260
+ [
261
+ cmd.Name.GET_ELEMENT_VALUE_OF_CSS_PROPERTY,
262
+ get('/session/:sessionId/element/:id/css/:propertyName'),
263
+ ],
264
+ [
265
+ cmd.Name.TAKE_ELEMENT_SCREENSHOT,
266
+ get('/session/:sessionId/element/:id/screenshot'),
267
+ ],
268
+ [cmd.Name.SWITCH_TO_WINDOW, post('/session/:sessionId/window')],
269
+ [
270
+ cmd.Name.MAXIMIZE_WINDOW,
271
+ post('/session/:sessionId/window/current/maximize'),
272
+ ],
273
+ [
274
+ cmd.Name.GET_WINDOW_POSITION,
275
+ get('/session/:sessionId/window/current/position'),
276
+ ],
277
+ [
278
+ cmd.Name.SET_WINDOW_POSITION,
279
+ post('/session/:sessionId/window/current/position'),
280
+ ],
281
+ [cmd.Name.GET_WINDOW_SIZE, get('/session/:sessionId/window/current/size')],
282
+ [cmd.Name.SET_WINDOW_SIZE, post('/session/:sessionId/window/current/size')],
283
+ [cmd.Name.SWITCH_TO_FRAME, post('/session/:sessionId/frame')],
284
+ [cmd.Name.SWITCH_TO_FRAME_PARENT, post('/session/:sessionId/frame/parent')],
285
+ [cmd.Name.GET_PAGE_SOURCE, get('/session/:sessionId/source')],
286
+ [cmd.Name.GET_TITLE, get('/session/:sessionId/title')],
287
+ [cmd.Name.EXECUTE_SCRIPT, post('/session/:sessionId/execute')],
288
+ [cmd.Name.EXECUTE_ASYNC_SCRIPT, post('/session/:sessionId/execute_async')],
289
+ [cmd.Name.SCREENSHOT, get('/session/:sessionId/screenshot')],
290
+ [cmd.Name.GET_TIMEOUT, get('/session/:sessionId/timeouts')],
291
+ [cmd.Name.SET_TIMEOUT, post('/session/:sessionId/timeouts')],
292
+ [cmd.Name.ACCEPT_ALERT, post('/session/:sessionId/accept_alert')],
293
+ [cmd.Name.DISMISS_ALERT, post('/session/:sessionId/dismiss_alert')],
294
+ [cmd.Name.GET_ALERT_TEXT, get('/session/:sessionId/alert_text')],
295
+ [cmd.Name.SET_ALERT_TEXT, post('/session/:sessionId/alert_text')],
296
+ [cmd.Name.GET_LOG, post('/session/:sessionId/log')],
297
+ [cmd.Name.GET_AVAILABLE_LOG_TYPES, get('/session/:sessionId/log/types')],
298
+ [cmd.Name.GET_SESSION_LOGS, post('/logs')],
299
+ [cmd.Name.UPLOAD_FILE, post('/session/:sessionId/se/file')],
300
+ [cmd.Name.LEGACY_ACTION_CLICK, post('/session/:sessionId/click')],
301
+ [
302
+ cmd.Name.LEGACY_ACTION_DOUBLE_CLICK,
303
+ post('/session/:sessionId/doubleclick'),
304
+ ],
305
+ [cmd.Name.LEGACY_ACTION_MOUSE_DOWN, post('/session/:sessionId/buttondown')],
306
+ [cmd.Name.LEGACY_ACTION_MOUSE_UP, post('/session/:sessionId/buttonup')],
307
+ [cmd.Name.LEGACY_ACTION_MOUSE_MOVE, post('/session/:sessionId/moveto')],
308
+ [cmd.Name.LEGACY_ACTION_SEND_KEYS, post('/session/:sessionId/keys')],
309
+ [cmd.Name.LEGACY_ACTION_TOUCH_DOWN, post('/session/:sessionId/touch/down')],
310
+ [cmd.Name.LEGACY_ACTION_TOUCH_UP, post('/session/:sessionId/touch/up')],
311
+ [cmd.Name.LEGACY_ACTION_TOUCH_MOVE, post('/session/:sessionId/touch/move')],
312
+ [
313
+ cmd.Name.LEGACY_ACTION_TOUCH_SCROLL,
314
+ post('/session/:sessionId/touch/scroll'),
315
+ ],
316
+ [
317
+ cmd.Name.LEGACY_ACTION_TOUCH_LONG_PRESS,
318
+ post('/session/:sessionId/touch/longclick'),
319
+ ],
320
+ [cmd.Name.LEGACY_ACTION_TOUCH_FLICK, post('/session/:sessionId/touch/flick')],
321
+ [
322
+ cmd.Name.LEGACY_ACTION_TOUCH_SINGLE_TAP,
323
+ post('/session/:sessionId/touch/click'),
324
+ ],
325
+ [
326
+ cmd.Name.LEGACY_ACTION_TOUCH_DOUBLE_TAP,
327
+ post('/session/:sessionId/touch/doubleclick'),
328
+ ],
329
+ ])
266
330
 
267
331
  /** @const {!Map<string, (CommandSpec|CommandTransformer)>} */
268
332
  const W3C_COMMAND_MAP = new Map([
@@ -306,24 +370,51 @@ const W3C_COMMAND_MAP = new Map([
306
370
  [cmd.Name.GET_ACTIVE_ELEMENT, get('/session/:sessionId/element/active')],
307
371
  [cmd.Name.FIND_ELEMENT, post('/session/:sessionId/element')],
308
372
  [cmd.Name.FIND_ELEMENTS, post('/session/:sessionId/elements')],
309
- [cmd.Name.FIND_CHILD_ELEMENT, post('/session/:sessionId/element/:id/element')],
310
- [cmd.Name.FIND_CHILD_ELEMENTS, post('/session/:sessionId/element/:id/elements')],
373
+ [
374
+ cmd.Name.FIND_ELEMENTS_RELATIVE,
375
+ (cmd) => {
376
+ return toExecuteAtomCommand(cmd, Atom.FIND_ELEMENTS, 'args')
377
+ },
378
+ ],
379
+ [
380
+ cmd.Name.FIND_CHILD_ELEMENT,
381
+ post('/session/:sessionId/element/:id/element'),
382
+ ],
383
+ [
384
+ cmd.Name.FIND_CHILD_ELEMENTS,
385
+ post('/session/:sessionId/element/:id/elements'),
386
+ ],
311
387
  // Element interaction.
312
388
  [cmd.Name.GET_ELEMENT_TAG_NAME, get('/session/:sessionId/element/:id/name')],
313
- [cmd.Name.GET_ELEMENT_PROPERTY, get('/session/:sessionId/element/:id/property/:name')],
314
- [cmd.Name.GET_ELEMENT_VALUE_OF_CSS_PROPERTY, get('/session/:sessionId/element/:id/css/:propertyName')],
389
+ [
390
+ cmd.Name.GET_ELEMENT_PROPERTY,
391
+ get('/session/:sessionId/element/:id/property/:name'),
392
+ ],
393
+ [
394
+ cmd.Name.GET_ELEMENT_VALUE_OF_CSS_PROPERTY,
395
+ get('/session/:sessionId/element/:id/css/:propertyName'),
396
+ ],
315
397
  [cmd.Name.GET_ELEMENT_RECT, get('/session/:sessionId/element/:id/rect')],
316
398
  [cmd.Name.CLEAR_ELEMENT, post('/session/:sessionId/element/:id/clear')],
317
399
  [cmd.Name.CLICK_ELEMENT, post('/session/:sessionId/element/:id/click')],
318
- [cmd.Name.SEND_KEYS_TO_ELEMENT, post('/session/:sessionId/element/:id/value')],
400
+ [
401
+ cmd.Name.SEND_KEYS_TO_ELEMENT,
402
+ post('/session/:sessionId/element/:id/value'),
403
+ ],
319
404
  [cmd.Name.GET_ELEMENT_TEXT, get('/session/:sessionId/element/:id/text')],
320
405
  [cmd.Name.IS_ELEMENT_ENABLED, get('/session/:sessionId/element/:id/enabled')],
321
- [cmd.Name.GET_ELEMENT_ATTRIBUTE, (cmd) => {
322
- return toExecuteAtomCommand(cmd, Atom.GET_ATTRIBUTE, 'id', 'name');
323
- }],
324
- [cmd.Name.IS_ELEMENT_DISPLAYED, (cmd) => {
325
- return toExecuteAtomCommand(cmd, Atom.IS_DISPLAYED, 'id');
326
- }],
406
+ [
407
+ cmd.Name.GET_ELEMENT_ATTRIBUTE,
408
+ (cmd) => {
409
+ return toExecuteAtomCommand(cmd, Atom.GET_ATTRIBUTE, 'id', 'name')
410
+ },
411
+ ],
412
+ [
413
+ cmd.Name.IS_ELEMENT_DISPLAYED,
414
+ (cmd) => {
415
+ return toExecuteAtomCommand(cmd, Atom.IS_DISPLAYED, 'id')
416
+ },
417
+ ],
327
418
  // Cookie management.
328
419
  [cmd.Name.GET_ALL_COOKIES, get('/session/:sessionId/cookie')],
329
420
  [cmd.Name.ADD_COOKIE, post('/session/:sessionId/cookie')],
@@ -337,12 +428,16 @@ const W3C_COMMAND_MAP = new Map([
337
428
  [cmd.Name.SET_ALERT_TEXT, post('/session/:sessionId/alert/text')],
338
429
  // Screenshots.
339
430
  [cmd.Name.SCREENSHOT, get('/session/:sessionId/screenshot')],
340
- [cmd.Name.TAKE_ELEMENT_SCREENSHOT, get('/session/:sessionId/element/:id/screenshot')],
431
+ [
432
+ cmd.Name.TAKE_ELEMENT_SCREENSHOT,
433
+ get('/session/:sessionId/element/:id/screenshot'),
434
+ ],
435
+ // print page.
436
+ [cmd.Name.PRINT_PAGE, post('/session/:sessionId/print')],
341
437
  // Log extensions.
342
438
  [cmd.Name.GET_LOG, post('/session/:sessionId/se/log')],
343
439
  [cmd.Name.GET_AVAILABLE_LOG_TYPES, get('/session/:sessionId/se/log/types')],
344
- ]);
345
-
440
+ ])
346
441
 
347
442
  /**
348
443
  * Handles sending HTTP messages to a remote end.
@@ -350,7 +445,6 @@ const W3C_COMMAND_MAP = new Map([
350
445
  * @interface
351
446
  */
352
447
  class Client {
353
-
354
448
  /**
355
449
  * Sends a request to the server. The client will automatically follow any
356
450
  * redirects returned by the server, fulfilling the returned promise with the
@@ -360,11 +454,9 @@ class Client {
360
454
  * @return {!Promise<Response>} A promise that will be fulfilled with the
361
455
  * server's response.
362
456
  */
363
- send(httpRequest) {}
457
+ send(httpRequest) {} // eslint-disable-line
364
458
  }
365
459
 
366
-
367
-
368
460
  /**
369
461
  * @param {Map<string, CommandSpec>} customCommands
370
462
  * A map of custom command definitions.
@@ -374,46 +466,44 @@ class Client {
374
466
  * command to execute.
375
467
  */
376
468
  function buildRequest(customCommands, w3c, command) {
377
- LOG.finest(() => `Translating command: ${command.getName()}`);
378
- let spec = customCommands && customCommands.get(command.getName());
469
+ LOG.finest(() => `Translating command: ${command.getName()}`)
470
+ let spec = customCommands && customCommands.get(command.getName())
379
471
  if (spec) {
380
- return toHttpRequest(spec);
472
+ return toHttpRequest(spec)
381
473
  }
382
474
 
383
475
  if (w3c) {
384
- spec = W3C_COMMAND_MAP.get(command.getName());
476
+ spec = W3C_COMMAND_MAP.get(command.getName())
385
477
  if (typeof spec === 'function') {
386
- LOG.finest(() => `Transforming command for W3C: ${command.getName()}`);
387
- let newCommand = spec(command);
388
- return buildRequest(customCommands, w3c, newCommand);
478
+ LOG.finest(() => `Transforming command for W3C: ${command.getName()}`)
479
+ let newCommand = spec(command)
480
+ return buildRequest(customCommands, w3c, newCommand)
389
481
  } else if (spec) {
390
- return toHttpRequest(spec);
482
+ return toHttpRequest(spec)
391
483
  }
392
484
  }
393
485
 
394
- spec = COMMAND_MAP.get(command.getName());
486
+ spec = COMMAND_MAP.get(command.getName())
395
487
  if (spec) {
396
- return toHttpRequest(spec);
488
+ return toHttpRequest(spec)
397
489
  }
398
490
  throw new error.UnknownCommandError(
399
- 'Unrecognized command: ' + command.getName());
491
+ 'Unrecognized command: ' + command.getName()
492
+ )
400
493
 
401
494
  /**
402
495
  * @param {CommandSpec} resource
403
496
  * @return {!Request}
404
497
  */
405
498
  function toHttpRequest(resource) {
406
- LOG.finest(() => `Building HTTP request: ${JSON.stringify(resource)}`);
407
- let parameters = command.getParameters();
408
- let path = buildPath(resource.path, parameters);
409
- return new Request(resource.method, path, parameters);
499
+ LOG.finest(() => `Building HTTP request: ${JSON.stringify(resource)}`)
500
+ let parameters = command.getParameters()
501
+ let path = buildPath(resource.path, parameters)
502
+ return new Request(resource.method, path, parameters)
410
503
  }
411
504
  }
412
505
 
413
-
414
- const CLIENTS =
415
- /** !WeakMap<!Executor, !(Client|IThenable<!Client>)> */new WeakMap;
416
-
506
+ const CLIENTS = /** !WeakMap<!Executor, !(Client|IThenable<!Client>)> */ new WeakMap()
417
507
 
418
508
  /**
419
509
  * A command executor that communicates with the server using JSON over HTTP.
@@ -435,7 +525,7 @@ class Executor {
435
525
  * to the client.
436
526
  */
437
527
  constructor(client) {
438
- CLIENTS.set(this, client);
528
+ CLIENTS.set(this, client)
439
529
 
440
530
  /**
441
531
  * Whether this executor should use the W3C wire protocol. The executor
@@ -444,13 +534,13 @@ class Executor {
444
534
  * `true` to force the executor into W3C mode.
445
535
  * @type {boolean}
446
536
  */
447
- this.w3c = false;
537
+ this.w3c = false
448
538
 
449
539
  /** @private {Map<string, CommandSpec>} */
450
- this.customCommands_ = null;
540
+ this.customCommands_ = null
451
541
 
452
542
  /** @private {!logging.Logger} */
453
- this.log_ = logging.getLogger('webdriver.http.Executor');
543
+ this.log_ = logging.getLogger('webdriver.http.Executor')
454
544
  }
455
545
 
456
546
  /**
@@ -468,64 +558,65 @@ class Executor {
468
558
  */
469
559
  defineCommand(name, method, path) {
470
560
  if (!this.customCommands_) {
471
- this.customCommands_ = new Map;
561
+ this.customCommands_ = new Map()
472
562
  }
473
- this.customCommands_.set(name, {method, path});
563
+ this.customCommands_.set(name, { method, path })
474
564
  }
475
565
 
476
566
  /** @override */
477
567
  async execute(command) {
478
- let request = buildRequest(this.customCommands_, this.w3c, command);
479
- this.log_.finer(() => `>>> ${request.method} ${request.path}`);
568
+ let request = buildRequest(this.customCommands_, this.w3c, command)
569
+ this.log_.finer(() => `>>> ${request.method} ${request.path}`)
480
570
 
481
- let client = CLIENTS.get(this);
571
+ let client = CLIENTS.get(this)
482
572
  if (promise.isPromise(client)) {
483
- client = await client;
484
- CLIENTS.set(this, client);
573
+ client = await client
574
+ CLIENTS.set(this, client)
485
575
  }
486
576
 
487
- let response = await client.send(request);
488
- this.log_.finer(() => `>>>\n${request}\n<<<\n${response}`);
577
+ let response = await client.send(request)
578
+ this.log_.finer(() => `>>>\n${request}\n<<<\n${response}`)
489
579
 
490
- let httpResponse = /** @type {!Response} */(response);
491
- let {isW3C, value} = parseHttpResponse(command, httpResponse);
580
+ let httpResponse = /** @type {!Response} */ (response)
581
+ let { isW3C, value } = parseHttpResponse(command, httpResponse)
492
582
 
493
583
  if (command.getName() === cmd.Name.NEW_SESSION) {
494
584
  if (!value || !value.sessionId) {
495
585
  throw new error.WebDriverError(
496
- `Unable to parse new session response: ${response.body}`);
586
+ `Unable to parse new session response: ${response.body}`
587
+ )
497
588
  }
498
589
 
499
590
  // The remote end is a W3C compliant server if there is no `status`
500
591
  // field in the response.
501
592
  if (command.getName() === cmd.Name.NEW_SESSION) {
502
- this.w3c = this.w3c || isW3C;
593
+ this.w3c = this.w3c || isW3C
503
594
  }
504
595
 
505
596
  // No implementations use the `capabilities` key yet...
506
- let capabilities = value.capabilities || value.value;
597
+ let capabilities = value.capabilities || value.value
507
598
  return new Session(
508
- /** @type {{sessionId: string}} */(value).sessionId, capabilities);
599
+ /** @type {{sessionId: string}} */ (value).sessionId,
600
+ capabilities
601
+ )
509
602
  }
510
603
 
511
- return typeof value === 'undefined' ? null : value;
604
+ return typeof value === 'undefined' ? null : value
512
605
  }
513
606
  }
514
607
 
515
-
516
608
  /**
517
609
  * @param {string} str .
518
610
  * @return {?} .
519
611
  */
520
612
  function tryParse(str) {
521
613
  try {
522
- return JSON.parse(str);
614
+ return JSON.parse(str)
523
615
  } catch (ignored) {
524
616
  // Do nothing.
525
617
  }
526
618
  }
527
619
 
528
-
529
620
  /**
530
621
  * Callback used to parse {@link Response} objects from a
531
622
  * {@link HttpClient}.
@@ -541,51 +632,49 @@ function tryParse(str) {
541
632
  function parseHttpResponse(command, httpResponse) {
542
633
  if (httpResponse.status < 200) {
543
634
  // This should never happen, but throw the raw response so users report it.
544
- throw new error.WebDriverError(
545
- `Unexpected HTTP response:\n${httpResponse}`);
635
+ throw new error.WebDriverError(`Unexpected HTTP response:\n${httpResponse}`)
546
636
  }
547
637
 
548
- let parsed = tryParse(httpResponse.body);
638
+ let parsed = tryParse(httpResponse.body)
549
639
  if (parsed && typeof parsed === 'object') {
550
- let value = parsed.value;
640
+ let value = parsed.value
551
641
  let isW3C =
552
- value !== null && typeof value === 'object'
553
- && typeof parsed.status === 'undefined';
642
+ value !== null &&
643
+ typeof value === 'object' &&
644
+ typeof parsed.status === 'undefined'
554
645
 
555
646
  if (!isW3C) {
556
- error.checkLegacyResponse(parsed);
647
+ error.checkLegacyResponse(parsed)
557
648
 
558
649
  // Adjust legacy new session responses to look like W3C to simplify
559
650
  // later processing.
560
651
  if (command.getName() === cmd.Name.NEW_SESSION) {
561
- value = parsed;
652
+ value = parsed
562
653
  }
563
-
564
654
  } else if (httpResponse.status > 399) {
565
- error.throwDecodedError(value);
655
+ error.throwDecodedError(value)
566
656
  }
567
657
 
568
- return {isW3C, value};
658
+ return { isW3C, value }
569
659
  }
570
660
 
571
661
  if (parsed !== undefined) {
572
- return {isW3C: false, value: parsed};
662
+ return { isW3C: false, value: parsed }
573
663
  }
574
664
 
575
- let value = httpResponse.body.replace(/\r\n/g, '\n');
665
+ let value = httpResponse.body.replace(/\r\n/g, '\n')
576
666
 
577
667
  // 404 represents an unknown command; anything else > 399 is a generic unknown
578
668
  // error.
579
669
  if (httpResponse.status == 404) {
580
- throw new error.UnsupportedOperationError(command.getName() + ': ' + value);
670
+ throw new error.UnsupportedOperationError(command.getName() + ': ' + value)
581
671
  } else if (httpResponse.status >= 400) {
582
- throw new error.WebDriverError(value);
672
+ throw new error.WebDriverError(value)
583
673
  }
584
674
 
585
- return {isW3C: false, value: value || null};
675
+ return { isW3C: false, value: value || null }
586
676
  }
587
677
 
588
-
589
678
  /**
590
679
  * Builds a fully qualified path using the given set of command parameters. Each
591
680
  * path segment prefixed with ':' will be replaced by the value of the
@@ -596,33 +685,33 @@ function parseHttpResponse(command, httpResponse) {
596
685
  * @return {string} The modified path.
597
686
  */
598
687
  function buildPath(path, parameters) {
599
- let pathParameters = path.match(/\/:(\w+)\b/g);
688
+ let pathParameters = path.match(/\/:(\w+)\b/g)
600
689
  if (pathParameters) {
601
690
  for (let i = 0; i < pathParameters.length; ++i) {
602
- let key = pathParameters[i].substring(2); // Trim the /:
691
+ let key = pathParameters[i].substring(2) // Trim the /:
603
692
  if (key in parameters) {
604
- let value = parameters[key];
693
+ let value = parameters[key]
605
694
  if (WebElement.isId(value)) {
606
695
  // When inserting a WebElement into the URL, only use its ID value,
607
696
  // not the full JSON.
608
- value = WebElement.extractId(value);
697
+ value = WebElement.extractId(value)
609
698
  }
610
- path = path.replace(pathParameters[i], '/' + value);
611
- delete parameters[key];
699
+ path = path.replace(pathParameters[i], '/' + value)
700
+ delete parameters[key]
612
701
  } else {
613
702
  throw new error.InvalidArgumentError(
614
- 'Missing required parameter: ' + key);
703
+ 'Missing required parameter: ' + key
704
+ )
615
705
  }
616
706
  }
617
707
  }
618
- return path;
708
+ return path
619
709
  }
620
710
 
621
-
622
711
  // PUBLIC API
623
712
 
624
- exports.Executor = Executor;
625
- exports.Client = Client;
626
- exports.Request = Request;
627
- exports.Response = Response;
628
- exports.buildPath = buildPath; // Exported for testing.
713
+ exports.Executor = Executor
714
+ exports.Client = Client
715
+ exports.Request = Request
716
+ exports.Response = Response
717
+ exports.buildPath = buildPath // Exported for testing.