selenium-webdriver 4.1.0 → 4.2.0

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/error.js CHANGED
@@ -217,7 +217,7 @@ class NoSuchElementError extends WebDriverError {
217
217
  class NoSuchShadowRootError extends WebDriverError {
218
218
  /** @param {string=} opt_error the error message, if any. */
219
219
  constructor(opt_error) {
220
- super(opt_error);
220
+ super(opt_error)
221
221
  }
222
222
  }
223
223
 
@@ -495,23 +495,6 @@ function encodeError(err) {
495
495
  return { error: code, message: message }
496
496
  }
497
497
 
498
- /**
499
- * Checks a response object from a server that adheres to the W3C WebDriver
500
- * protocol.
501
- * @param {*} data The response data to check.
502
- * @return {*} The response data if it was not an encoded error.
503
- * @throws {WebDriverError} the decoded error, if present in the data object.
504
- * @deprecated Use {@link #throwDecodedError(data)} instead.
505
- * @see https://w3c.github.io/webdriver/webdriver-spec.html#protocol
506
- */
507
- function checkResponse(data) {
508
- if (data && typeof data.error === 'string') {
509
- let ctor = ERROR_CODE_TO_TYPE.get(data.error) || WebDriverError
510
- throw new ctor(data.message)
511
- }
512
- return data
513
- }
514
-
515
498
  /**
516
499
  * Tests if the given value is a valid error response object according to the
517
500
  * W3C WebDriver spec.
@@ -620,8 +603,6 @@ module.exports = {
620
603
  UnknownCommandError,
621
604
  UnknownMethodError,
622
605
  UnsupportedOperationError,
623
-
624
- checkResponse,
625
606
  checkLegacyResponse,
626
607
  encodeError,
627
608
  isErrorResponse,
package/lib/http.js CHANGED
@@ -31,7 +31,7 @@ const error = require('./error')
31
31
  const logging = require('./logging')
32
32
  const promise = require('./promise')
33
33
  const { Session } = require('./session')
34
- const { WebElement, ShadowRoot } = require('./webdriver')
34
+ const { WebElement } = require('./webdriver')
35
35
 
36
36
  const getAttribute = requireAtom(
37
37
  'get-attribute.js',
@@ -63,8 +63,8 @@ function requireAtom(module, bazelTarget) {
63
63
  console.log(ex2)
64
64
  throw Error(
65
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}`
66
+ ` need to run \`bazel build ${bazelTarget}\` from the project` +
67
+ `root: ${ex}`
68
68
  )
69
69
  }
70
70
  }
@@ -173,12 +173,13 @@ var CommandSpec // eslint-disable-line
173
173
  /** @typedef {function(!cmd.Command): !cmd.Command} */
174
174
  var CommandTransformer // eslint-disable-line
175
175
 
176
- class InternalTypeError extends TypeError { }
176
+ class InternalTypeError extends TypeError {}
177
177
 
178
178
  /**
179
179
  * @param {!cmd.Command} command The initial command.
180
180
  * @param {Atom} atom The name of the atom to execute.
181
- * @return {!cmd.Command} The transformed command to execute.
181
+ * @param params
182
+ * @return {!Command} The transformed command to execute.
182
183
  */
183
184
  function toExecuteAtomCommand(command, atom, ...params) {
184
185
  if (typeof atom !== 'function') {
@@ -194,143 +195,38 @@ function toExecuteAtomCommand(command, atom, ...params) {
194
195
  )
195
196
  }
196
197
 
197
- /** @const {!Map<string, CommandSpec>} */
198
- const COMMAND_MAP = new Map([
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
- [
238
- cmd.Name.GET_COMPUTED_ROLE,
239
- get('/session/:sessionId/element/:id/computedrole'),
240
- ],
241
- [
242
- cmd.Name.GET_COMPUTED_LABEL,
243
- get('/session/:sessionId/element/:id/computedlabel'),
244
- ],
245
- [cmd.Name.GET_ELEMENT_TAG_NAME, get('/session/:sessionId/element/:id/name')],
246
- [
247
- cmd.Name.IS_ELEMENT_SELECTED,
248
- get('/session/:sessionId/element/:id/selected'),
249
- ],
250
- [cmd.Name.IS_ELEMENT_ENABLED, get('/session/:sessionId/element/:id/enabled')],
251
- [
252
- cmd.Name.IS_ELEMENT_DISPLAYED,
253
- get('/session/:sessionId/element/:id/displayed'),
254
- ],
255
- [
256
- cmd.Name.GET_ELEMENT_LOCATION,
257
- get('/session/:sessionId/element/:id/location'),
258
- ],
259
- [cmd.Name.GET_ELEMENT_SIZE, get('/session/:sessionId/element/:id/size')],
260
- [
261
- cmd.Name.GET_ELEMENT_ATTRIBUTE,
262
- get('/session/:sessionId/element/:id/attribute/:name'),
263
- ],
264
- [
265
- cmd.Name.GET_ELEMENT_PROPERTY,
266
- get('/session/:sessionId/element/:id/property/:name'),
267
- ],
268
- [
269
- cmd.Name.GET_ELEMENT_VALUE_OF_CSS_PROPERTY,
270
- get('/session/:sessionId/element/:id/css/:propertyName'),
271
- ],
272
- [
273
- cmd.Name.TAKE_ELEMENT_SCREENSHOT,
274
- get('/session/:sessionId/element/:id/screenshot'),
275
- ],
276
- [cmd.Name.SWITCH_TO_WINDOW, post('/session/:sessionId/window')],
277
- [
278
- cmd.Name.MAXIMIZE_WINDOW,
279
- post('/session/:sessionId/window/current/maximize'),
280
- ],
281
- [
282
- cmd.Name.GET_WINDOW_POSITION,
283
- get('/session/:sessionId/window/current/position'),
284
- ],
285
- [
286
- cmd.Name.SET_WINDOW_POSITION,
287
- post('/session/:sessionId/window/current/position'),
288
- ],
289
- [cmd.Name.GET_WINDOW_SIZE, get('/session/:sessionId/window/current/size')],
290
- [cmd.Name.SET_WINDOW_SIZE, post('/session/:sessionId/window/current/size')],
291
- [cmd.Name.SWITCH_TO_FRAME, post('/session/:sessionId/frame')],
292
- [cmd.Name.SWITCH_TO_FRAME_PARENT, post('/session/:sessionId/frame/parent')],
293
- [cmd.Name.GET_PAGE_SOURCE, get('/session/:sessionId/source')],
294
- [cmd.Name.GET_TITLE, get('/session/:sessionId/title')],
295
- [cmd.Name.EXECUTE_SCRIPT, post('/session/:sessionId/execute')],
296
- [cmd.Name.EXECUTE_ASYNC_SCRIPT, post('/session/:sessionId/execute_async')],
297
- [cmd.Name.SCREENSHOT, get('/session/:sessionId/screenshot')],
298
- [cmd.Name.GET_TIMEOUT, get('/session/:sessionId/timeouts')],
299
- [cmd.Name.SET_TIMEOUT, post('/session/:sessionId/timeouts')],
300
- [cmd.Name.ACCEPT_ALERT, post('/session/:sessionId/accept_alert')],
301
- [cmd.Name.DISMISS_ALERT, post('/session/:sessionId/dismiss_alert')],
302
- [cmd.Name.GET_ALERT_TEXT, get('/session/:sessionId/alert_text')],
303
- [cmd.Name.SET_ALERT_TEXT, post('/session/:sessionId/alert_text')],
304
- [cmd.Name.GET_LOG, post('/session/:sessionId/log')],
305
- [cmd.Name.GET_AVAILABLE_LOG_TYPES, get('/session/:sessionId/log/types')],
306
- [cmd.Name.GET_SESSION_LOGS, post('/logs')],
307
- [cmd.Name.UPLOAD_FILE, post('/session/:sessionId/se/file')],
308
- ])
309
-
310
198
  /** @const {!Map<string, (CommandSpec|CommandTransformer)>} */
311
199
  const W3C_COMMAND_MAP = new Map([
312
- // Server status.
313
- [cmd.Name.GET_SERVER_STATUS, get('/status')],
314
200
  // Session management.
315
201
  [cmd.Name.NEW_SESSION, post('/session')],
316
202
  [cmd.Name.QUIT, del('/session/:sessionId')],
203
+
204
+ // Server status.
205
+ [cmd.Name.GET_SERVER_STATUS, get('/status')],
206
+
207
+ // timeouts
317
208
  [cmd.Name.GET_TIMEOUT, get('/session/:sessionId/timeouts')],
318
209
  [cmd.Name.SET_TIMEOUT, post('/session/:sessionId/timeouts')],
210
+
319
211
  // Navigation.
320
212
  [cmd.Name.GET_CURRENT_URL, get('/session/:sessionId/url')],
321
213
  [cmd.Name.GET, post('/session/:sessionId/url')],
322
214
  [cmd.Name.GO_BACK, post('/session/:sessionId/back')],
323
215
  [cmd.Name.GO_FORWARD, post('/session/:sessionId/forward')],
324
216
  [cmd.Name.REFRESH, post('/session/:sessionId/refresh')],
217
+
325
218
  // Page inspection.
326
219
  [cmd.Name.GET_PAGE_SOURCE, get('/session/:sessionId/source')],
327
220
  [cmd.Name.GET_TITLE, get('/session/:sessionId/title')],
221
+
328
222
  // Script execution.
329
223
  [cmd.Name.EXECUTE_SCRIPT, post('/session/:sessionId/execute/sync')],
330
224
  [cmd.Name.EXECUTE_ASYNC_SCRIPT, post('/session/:sessionId/execute/async')],
225
+
331
226
  // Frame selection.
332
227
  [cmd.Name.SWITCH_TO_FRAME, post('/session/:sessionId/frame')],
333
228
  [cmd.Name.SWITCH_TO_FRAME_PARENT, post('/session/:sessionId/frame/parent')],
229
+
334
230
  // Window management.
335
231
  [cmd.Name.GET_CURRENT_WINDOW_HANDLE, get('/session/:sessionId/window')],
336
232
  [cmd.Name.CLOSE, del('/session/:sessionId/window')],
@@ -342,9 +238,12 @@ const W3C_COMMAND_MAP = new Map([
342
238
  [cmd.Name.MAXIMIZE_WINDOW, post('/session/:sessionId/window/maximize')],
343
239
  [cmd.Name.MINIMIZE_WINDOW, post('/session/:sessionId/window/minimize')],
344
240
  [cmd.Name.FULLSCREEN_WINDOW, post('/session/:sessionId/window/fullscreen')],
241
+
345
242
  // Actions.
346
243
  [cmd.Name.ACTIONS, post('/session/:sessionId/actions')],
347
244
  [cmd.Name.CLEAR_ACTIONS, del('/session/:sessionId/actions')],
245
+ [cmd.Name.PRINT_PAGE, post('/session/:sessionId/print')],
246
+
348
247
  // Locating elements.
349
248
  [cmd.Name.GET_ACTIVE_ELEMENT, get('/session/:sessionId/element/active')],
350
249
  [cmd.Name.FIND_ELEMENT, post('/session/:sessionId/element')],
@@ -365,6 +264,16 @@ const W3C_COMMAND_MAP = new Map([
365
264
  ],
366
265
  // Element interaction.
367
266
  [cmd.Name.GET_ELEMENT_TAG_NAME, get('/session/:sessionId/element/:id/name')],
267
+ [
268
+ cmd.Name.GET_DOM_ATTRIBUTE,
269
+ get('/session/:sessionId/element/:id/attribute/:name'),
270
+ ],
271
+ [
272
+ cmd.Name.GET_ELEMENT_ATTRIBUTE,
273
+ (cmd) => {
274
+ return toExecuteAtomCommand(cmd, Atom.GET_ATTRIBUTE, 'id', 'name')
275
+ },
276
+ ],
368
277
  [
369
278
  cmd.Name.GET_ELEMENT_PROPERTY,
370
279
  get('/session/:sessionId/element/:id/property/:name'),
@@ -391,43 +300,53 @@ const W3C_COMMAND_MAP = new Map([
391
300
  ],
392
301
  [cmd.Name.IS_ELEMENT_ENABLED, get('/session/:sessionId/element/:id/enabled')],
393
302
  [
394
- cmd.Name.GET_ELEMENT_ATTRIBUTE,
395
- (cmd) => {
396
- return toExecuteAtomCommand(cmd, Atom.GET_ATTRIBUTE, 'id', 'name')
397
- },
303
+ cmd.Name.IS_ELEMENT_SELECTED,
304
+ get('/session/:sessionId/element/:id/selected'),
398
305
  ],
306
+
399
307
  [
400
308
  cmd.Name.IS_ELEMENT_DISPLAYED,
401
309
  (cmd) => {
402
310
  return toExecuteAtomCommand(cmd, Atom.IS_DISPLAYED, 'id')
403
311
  },
404
312
  ],
313
+
405
314
  // Cookie management.
406
315
  [cmd.Name.GET_ALL_COOKIES, get('/session/:sessionId/cookie')],
407
316
  [cmd.Name.ADD_COOKIE, post('/session/:sessionId/cookie')],
408
317
  [cmd.Name.DELETE_ALL_COOKIES, del('/session/:sessionId/cookie')],
409
318
  [cmd.Name.GET_COOKIE, get('/session/:sessionId/cookie/:name')],
410
319
  [cmd.Name.DELETE_COOKIE, del('/session/:sessionId/cookie/:name')],
320
+
411
321
  // Alert management.
412
322
  [cmd.Name.ACCEPT_ALERT, post('/session/:sessionId/alert/accept')],
413
323
  [cmd.Name.DISMISS_ALERT, post('/session/:sessionId/alert/dismiss')],
414
324
  [cmd.Name.GET_ALERT_TEXT, get('/session/:sessionId/alert/text')],
415
325
  [cmd.Name.SET_ALERT_TEXT, post('/session/:sessionId/alert/text')],
326
+
416
327
  // Screenshots.
417
328
  [cmd.Name.SCREENSHOT, get('/session/:sessionId/screenshot')],
418
329
  [
419
330
  cmd.Name.TAKE_ELEMENT_SCREENSHOT,
420
331
  get('/session/:sessionId/element/:id/screenshot'),
421
332
  ],
422
- // print page.
423
- [cmd.Name.PRINT_PAGE, post('/session/:sessionId/print')],
333
+
424
334
  // Shadow Root
425
335
  [cmd.Name.GET_SHADOW_ROOT, get('/session/:sessionId/element/:id/shadow')],
426
- [cmd.Name.FIND_ELEMENT_FROM_SHADOWROOT, post('/session/:sessionId/shadow/:id/element')],
427
- [cmd.Name.FIND_ELEMENTS_FROM_SHADOWROOT, post('/session/:sessionId/shadow/:id/elements')],
336
+ [
337
+ cmd.Name.FIND_ELEMENT_FROM_SHADOWROOT,
338
+ post('/session/:sessionId/shadow/:id/element'),
339
+ ],
340
+ [
341
+ cmd.Name.FIND_ELEMENTS_FROM_SHADOWROOT,
342
+ post('/session/:sessionId/shadow/:id/elements'),
343
+ ],
428
344
  // Log extensions.
429
345
  [cmd.Name.GET_LOG, post('/session/:sessionId/se/log')],
430
346
  [cmd.Name.GET_AVAILABLE_LOG_TYPES, get('/session/:sessionId/se/log/types')],
347
+
348
+ // Server Extensions
349
+ [cmd.Name.UPLOAD_FILE, post('/session/:sessionId/se/file')],
431
350
  ])
432
351
 
433
352
  /**
@@ -445,37 +364,29 @@ class Client {
445
364
  * @return {!Promise<Response>} A promise that will be fulfilled with the
446
365
  * server's response.
447
366
  */
448
- send(httpRequest) { } // eslint-disable-line
367
+ send(httpRequest) {} // eslint-disable-line
449
368
  }
450
369
 
451
370
  /**
452
371
  * @param {Map<string, CommandSpec>} customCommands
453
372
  * A map of custom command definitions.
454
- * @param {boolean} w3c Whether to use W3C command mappings.
455
373
  * @param {!cmd.Command} command The command to resolve.
456
374
  * @return {!Request} A promise that will resolve with the
457
375
  * command to execute.
458
376
  */
459
- function buildRequest(customCommands, w3c, command) {
377
+ function buildRequest(customCommands, command) {
460
378
  LOG.finest(() => `Translating command: ${command.getName()}`)
461
379
  let spec = customCommands && customCommands.get(command.getName())
462
380
  if (spec) {
463
381
  return toHttpRequest(spec)
464
382
  }
465
383
 
466
- if (w3c) {
467
- spec = W3C_COMMAND_MAP.get(command.getName())
468
- if (typeof spec === 'function') {
469
- LOG.finest(() => `Transforming command for W3C: ${command.getName()}`)
470
- let newCommand = spec(command)
471
- return buildRequest(customCommands, w3c, newCommand)
472
- } else if (spec) {
473
- return toHttpRequest(spec)
474
- }
475
- }
476
-
477
- spec = COMMAND_MAP.get(command.getName())
478
- if (spec) {
384
+ spec = W3C_COMMAND_MAP.get(command.getName())
385
+ if (typeof spec === 'function') {
386
+ LOG.finest(() => `Transforming command for W3C: ${command.getName()}`)
387
+ let newCommand = spec(command)
388
+ return buildRequest(customCommands, newCommand)
389
+ } else if (spec) {
479
390
  return toHttpRequest(spec)
480
391
  }
481
392
  throw new error.UnknownCommandError(
@@ -519,15 +430,6 @@ class Executor {
519
430
  constructor(client) {
520
431
  CLIENTS.set(this, client)
521
432
 
522
- /**
523
- * Whether this executor should use the W3C wire protocol. The executor
524
- * will automatically switch if the remote end sends a compliant response
525
- * to a new session command, however, this property may be directly set to
526
- * `true` to force the executor into W3C mode.
527
- * @type {boolean}
528
- */
529
- this.w3c = false
530
-
531
433
  /** @private {Map<string, CommandSpec>} */
532
434
  this.customCommands_ = null
533
435
 
@@ -557,7 +459,7 @@ class Executor {
557
459
 
558
460
  /** @override */
559
461
  async execute(command) {
560
- let request = buildRequest(this.customCommands_, this.w3c, command)
462
+ let request = buildRequest(this.customCommands_, command)
561
463
  this.log_.finer(() => `>>> ${request.method} ${request.path}`)
562
464
 
563
465
  let client = CLIENTS.get(this)
@@ -588,7 +490,7 @@ class Executor {
588
490
  // No implementations use the `capabilities` key yet...
589
491
  let capabilities = value.capabilities || value.value
590
492
  return new Session(
591
- /** @type {{sessionId: string}} */(value).sessionId,
493
+ /** @type {{sessionId: string}} */ (value).sessionId,
592
494
  capabilities
593
495
  )
594
496
  }
@@ -658,7 +560,7 @@ function parseHttpResponse(command, httpResponse) {
658
560
 
659
561
  // 404 represents an unknown command; anything else > 399 is a generic unknown
660
562
  // error.
661
- if (httpResponse.status == 404) {
563
+ if (httpResponse.status === 404) {
662
564
  throw new error.UnsupportedOperationError(command.getName() + ': ' + value)
663
565
  } else if (httpResponse.status >= 400) {
664
566
  throw new error.WebDriverError(value)
@@ -702,8 +604,11 @@ function buildPath(path, parameters) {
702
604
 
703
605
  // PUBLIC API
704
606
 
705
- exports.Executor = Executor
706
- exports.Client = Client
707
- exports.Request = Request
708
- exports.Response = Response
709
- exports.buildPath = buildPath // Exported for testing.
607
+ module.exports = {
608
+ Executor: Executor,
609
+ Client: Client,
610
+ Request: Request,
611
+ Response: Response,
612
+ // Exported for testing.
613
+ buildPath: buildPath,
614
+ }
package/lib/input.js CHANGED
@@ -200,6 +200,7 @@ Action.Type = {
200
200
  POINTER_UP: 'pointerUp',
201
201
  POINTER_MOVE: 'pointerMove',
202
202
  POINTER_CANCEL: 'pointerCancel',
203
+ SCROLL: 'scroll',
203
204
  }
204
205
 
205
206
  /**
@@ -233,6 +234,7 @@ Device.Type = {
233
234
  KEY: 'key',
234
235
  NONE: 'none',
235
236
  POINTER: 'pointer',
237
+ WHEEL: 'wheel',
236
238
  }
237
239
 
238
240
  /**
@@ -250,7 +252,7 @@ function checkCodePoint(key) {
250
252
  }
251
253
 
252
254
  key = key.normalize()
253
- if (Array.from(key).length != 1) {
255
+ if (Array.from(key).length !== 1) {
254
256
  throw new InvalidArgumentError(
255
257
  `key input is not a single code point: ${key}`
256
258
  )
@@ -347,8 +349,14 @@ class Pointer extends Device {
347
349
  * @return {!Action} An action to press the specified button with this device.
348
350
  * @package
349
351
  */
350
- press(button = Button.LEFT) {
351
- return { type: Action.Type.POINTER_DOWN, button }
352
+ press(button = Button.LEFT, width = 0, height = 0, pressure = 0,
353
+ tangentialPressure = 0, tiltX = 0, tiltY = 0, twist = 0,
354
+ altitudeAngle = 0, azimuthAngle = 0) {
355
+ return {
356
+ type: Action.Type.POINTER_DOWN, button, width, height,
357
+ pressure, tangentialPressure, tiltX, tiltY, twist,
358
+ altitudeAngle, azimuthAngle
359
+ }
352
360
  }
353
361
 
354
362
  /**
@@ -377,8 +385,16 @@ class Pointer extends Device {
377
385
  * @return {!Action} The new action.
378
386
  * @package
379
387
  */
380
- move({ x = 0, y = 0, duration = 100, origin = Origin.VIEWPORT }) {
381
- return { type: Action.Type.POINTER_MOVE, origin, duration, x, y }
388
+ move({ x = 0, y = 0, duration = 100, origin = Origin.VIEWPORT,
389
+ width = 0, height = 0, pressure = 0,
390
+ tangentialPressure = 0, tiltX = 0, tiltY = 0, twist = 0,
391
+ altitudeAngle = 0, azimuthAngle = 0
392
+ }) {
393
+ return {
394
+ type: Action.Type.POINTER_MOVE, origin, duration, x, y,
395
+ width, height, pressure, tangentialPressure, tiltX, tiltY, twist,
396
+ altitudeAngle, azimuthAngle
397
+ }
382
398
  }
383
399
  }
384
400
 
@@ -392,6 +408,34 @@ Pointer.Type = {
392
408
  TOUCH: 'touch',
393
409
  }
394
410
 
411
+ class Wheel extends Device {
412
+ /**
413
+ * @param {string} id the device ID.
414
+ * @param {Pointer.Type} type the pointer type.
415
+ */
416
+ constructor(id, type) {
417
+ super(Device.Type.WHEEL, id)
418
+ }
419
+
420
+ /**
421
+ * Scrolls a page via the coordinates given
422
+ * @param {number} x starting x coordinate
423
+ * @param {number} y starting y coordinate
424
+ * @param {number} deltaX Delta X to scroll to target
425
+ * @param {number} deltaY Delta Y to scroll to target
426
+ * @param {number} duration duration ratio be the ratio of time delta and duration
427
+ * @returns {!Action} An action to scroll with this device.
428
+ */
429
+ scroll(x, y, deltaX, deltaY, origin, duration) {
430
+ return {
431
+ type: Action.Type.SCROLL,
432
+ duration: duration, x: x, y: y,
433
+ deltaX: deltaX, deltaY: deltaY,
434
+ origin: origin
435
+ }
436
+ }
437
+ }
438
+
395
439
  /**
396
440
  * User facing API for generating complex user gestures. This class should not
397
441
  * be instantiated directly. Instead, users should create new instances by
@@ -509,10 +553,14 @@ class Actions {
509
553
  /** @private @const */
510
554
  this.mouse_ = new Pointer('default mouse', Pointer.Type.MOUSE)
511
555
 
556
+ /** @private @const */
557
+ this.wheel_ = new Wheel('default wheel')
558
+
512
559
  /** @private @const {!Map<!Device, !Array<!Action>>} */
513
560
  this.sequences_ = new Map([
514
561
  [this.keyboard_, []],
515
562
  [this.mouse_, []],
563
+ [this.wheel_, []],
516
564
  ])
517
565
  }
518
566
 
@@ -526,6 +574,11 @@ class Actions {
526
574
  return this.mouse_
527
575
  }
528
576
 
577
+ /** @return {!Wheel} the wheel device handle. */
578
+ wheel() {
579
+ return this.wheel_
580
+ }
581
+
529
582
  /**
530
583
  * @param {!Device} device
531
584
  * @return {!Array<!Action>}
@@ -735,6 +788,19 @@ class Actions {
735
788
  return this.insert(this.mouse_, this.mouse_.release(button))
736
789
  }
737
790
 
791
+ /**
792
+ * scrolls a page via the coordinates given
793
+ * @param {number} x starting x coordinate
794
+ * @param {number} y starting y coordinate
795
+ * @param {number} deltax delta x to scroll to target
796
+ * @param {number} deltay delta y to scroll to target
797
+ * @param {number} duration duration ratio be the ratio of time delta and duration
798
+ * @returns {!Action} An action to scroll with this device.
799
+ */
800
+ scroll(x, y, targetDeltaX, targetDeltaY, origin, duration) {
801
+ return this.insert(this.wheel_, this.wheel_.scroll(x, y, targetDeltaX, targetDeltaY, origin, duration))
802
+ }
803
+
738
804
  /**
739
805
  * Inserts an action for moving the mouse `x` and `y` pixels relative to the
740
806
  * specified `origin`. The `origin` may be defined as the mouse's
package/lib/promise.js CHANGED
@@ -142,14 +142,12 @@ async function map(array, fn, self = undefined) {
142
142
  }
143
143
 
144
144
  const arr = /** @type {!Array} */ (v)
145
- const n = arr.length
146
- const values = new Array(n)
145
+ const values = []
147
146
 
148
- for (let i = 0; i < n; i++) {
149
- if (i in arr) {
150
- values[i] = await Promise.resolve(fn.call(self, arr[i], i, arr))
151
- }
147
+ for (const [index, item] of arr.entries()) {
148
+ values.push(await Promise.resolve(fn.call(self, item, index, arr)))
152
149
  }
150
+
153
151
  return values
154
152
  }
155
153
 
@@ -181,19 +179,17 @@ async function filter(array, fn, self = undefined) {
181
179
  }
182
180
 
183
181
  const arr = /** @type {!Array} */ (v)
184
- const n = arr.length
185
182
  const values = []
186
- let valuesLength = 0
187
183
 
188
- for (let i = 0; i < n; i++) {
189
- if (i in arr) {
190
- const value = arr[i]
191
- const include = await fn.call(self, value, i, arr)
192
- if (include) {
193
- values[valuesLength++] = value
194
- }
184
+ for (const [index, item] of arr.entries()) {
185
+ const isConditionTrue = await Promise.resolve(
186
+ fn.call(self, item, index, arr)
187
+ )
188
+ if (isConditionTrue) {
189
+ values.push(item)
195
190
  }
196
191
  }
192
+
197
193
  return values
198
194
  }
199
195
 
@@ -266,8 +262,7 @@ async function fullyResolveKeys(obj) {
266
262
  ) {
267
263
  return
268
264
  }
269
- let resolvedValue = await fullyResolved(partialValue)
270
- obj[key] = resolvedValue
265
+ obj[key] = await fullyResolved(partialValue)
271
266
  })
272
267
  return obj
273
268
  }
package/lib/proxy.js CHANGED
@@ -130,7 +130,7 @@ ManualConfig.prototype.socksVersion
130
130
  * Configures WebDriver to bypass all browser proxies.
131
131
  * @return {!Config} A new proxy configuration object.
132
132
  */
133
- exports.direct = function () {
133
+ function direct() {
134
134
  return { proxyType: Type.DIRECT }
135
135
  }
136
136
 
@@ -155,7 +155,7 @@ exports.direct = function () {
155
155
  * configuration options.
156
156
  * @return {!ManualConfig} A new proxy configuration object.
157
157
  */
158
- exports.manual = function ({ ftp, http, https, bypass }) {
158
+ function manual({ ftp, http, https, bypass }) {
159
159
  return {
160
160
  proxyType: Type.MANUAL,
161
161
  ftpProxy: ftp,
@@ -185,7 +185,7 @@ exports.manual = function ({ ftp, http, https, bypass }) {
185
185
  * @return {!ManualConfig} A new proxy configuration object.
186
186
  * @see https://en.wikipedia.org/wiki/SOCKS
187
187
  */
188
- exports.socks = function (socksProxy, socksVersion = undefined) {
188
+ function socks(socksProxy, socksVersion = undefined) {
189
189
  return /** @type {!Config} */ ({
190
190
  proxyType: Type.MANUAL,
191
191
  socksProxy,
@@ -199,7 +199,7 @@ exports.socks = function (socksProxy, socksVersion = undefined) {
199
199
  * @param {string} proxyAutoconfigUrl URL for the PAC proxy to use.
200
200
  * @return {!PacConfig} A new proxy configuration object.
201
201
  */
202
- exports.pac = function (proxyAutoconfigUrl) {
202
+ function pac(proxyAutoconfigUrl) {
203
203
  return { proxyType: Type.PAC, proxyAutoconfigUrl }
204
204
  }
205
205
 
@@ -207,6 +207,16 @@ exports.pac = function (proxyAutoconfigUrl) {
207
207
  * Configures WebDriver to use the current system's proxy.
208
208
  * @return {!Config} A new proxy configuration object.
209
209
  */
210
- exports.system = function () {
210
+ function system() {
211
211
  return { proxyType: Type.SYSTEM }
212
212
  }
213
+
214
+ // PUBLIC API
215
+
216
+ module.exports = {
217
+ system,
218
+ pac,
219
+ socks,
220
+ manual,
221
+ direct,
222
+ }
package/lib/session.js CHANGED
@@ -74,4 +74,4 @@ class Session {
74
74
 
75
75
  // PUBLIC API
76
76
 
77
- module.exports = { Session: Session }
77
+ module.exports = { Session }