selenium-webdriver 4.1.1 → 4.1.2

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/README.md CHANGED
@@ -33,10 +33,10 @@ The sample below and others are included in the `example` directory. You may
33
33
  also find the tests for selenium-webdriver informative.
34
34
 
35
35
  ```javascript
36
- const {Builder, By, Key, until} = require('selenium-webdriver');
36
+ const {Builder, Browser, By, Key, until} = require('selenium-webdriver');
37
37
 
38
38
  (async function example() {
39
- let driver = await new Builder().forBrowser('firefox').build();
39
+ let driver = await new Builder().forBrowser(Browser.FIREFOX).build();
40
40
  try {
41
41
  await driver.get('http://www.google.com/ncr');
42
42
  await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN);
@@ -60,7 +60,7 @@ const chrome = require('selenium-webdriver/chrome');
60
60
  const firefox = require('selenium-webdriver/firefox');
61
61
 
62
62
  let driver = new webdriver.Builder()
63
- .forBrowser('firefox')
63
+ .forBrowser(webdriver.Browser.FIREFOX)
64
64
  .setChromeOptions(/* ... */)
65
65
  .setFirefoxOptions(/* ... */)
66
66
  .build();
@@ -99,7 +99,7 @@ API:
99
99
 
100
100
  ```javascript
101
101
  let driver = new webdriver.Builder()
102
- .forBrowser('firefox')
102
+ .forBrowser(webdriver.Browser.FIREFOX)
103
103
  .usingServer('http://localhost:4444/wd/hub')
104
104
  .build();
105
105
  ```
package/chromium.js CHANGED
@@ -92,6 +92,7 @@ const Command = {
92
92
  LAUNCH_APP: 'launchApp',
93
93
  GET_NETWORK_CONDITIONS: 'getNetworkConditions',
94
94
  SET_NETWORK_CONDITIONS: 'setNetworkConditions',
95
+ DELETE_NETWORK_CONDITIONS: 'deleteNetworkConditions',
95
96
  SEND_DEVTOOLS_COMMAND: 'sendDevToolsCommand',
96
97
  SEND_AND_GET_DEVTOOLS_COMMAND: 'sendAndGetDevToolsCommand',
97
98
  SET_PERMISSION: 'setPermission',
@@ -137,6 +138,11 @@ function configureExecutor(executor, vendorPrefix) {
137
138
  'POST',
138
139
  '/session/:sessionId/chromium/network_conditions'
139
140
  )
141
+ executor.defineCommand(
142
+ Command.DELETE_NETWORK_CONDITIONS,
143
+ 'DELETE',
144
+ '/session/:sessionId/chromium/network_conditions'
145
+ )
140
146
  executor.defineCommand(
141
147
  Command.SEND_DEVTOOLS_COMMAND,
142
148
  'POST',
@@ -655,14 +661,12 @@ class Driver extends webdriver.WebDriver {
655
661
  */
656
662
  static createSession(caps, opt_serviceExecutor) {
657
663
  let executor
658
- let onQuit
659
664
  if (opt_serviceExecutor instanceof http.Executor) {
660
665
  executor = opt_serviceExecutor
661
666
  configureExecutor(executor, this.VENDOR_COMMAND_PREFIX)
662
667
  } else {
663
668
  let service = opt_serviceExecutor || this.getDefaultService()
664
669
  executor = createExecutor(service.start(), this.VENDOR_COMMAND_PREFIX)
665
- onQuit = () => service.kill()
666
670
  }
667
671
 
668
672
  // W3C spec requires noProxy value to be an array of strings, but Chromium
@@ -675,7 +679,7 @@ class Driver extends webdriver.WebDriver {
675
679
  }
676
680
  }
677
681
 
678
- return /** @type {!Driver} */ (super.createSession(executor, caps, onQuit))
682
+ return /** @type {!Driver} */ (super.createSession(executor, caps))
679
683
  }
680
684
 
681
685
  /**
@@ -706,6 +710,15 @@ class Driver extends webdriver.WebDriver {
706
710
  return this.execute(new command.Command(Command.GET_NETWORK_CONDITIONS))
707
711
  }
708
712
 
713
+ /**
714
+ * Schedules a command to delete Chromium network emulation settings.
715
+ * @return {!Promise} A promise that will be resolved when network
716
+ * emulation settings have been deleted.
717
+ */
718
+ deleteNetworkConditions() {
719
+ return this.execute(new command.Command(Command.DELETE_NETWORK_CONDITIONS))
720
+ }
721
+
709
722
  /**
710
723
  * Schedules a command to set Chromium network emulation settings.
711
724
  *
package/edge.js CHANGED
@@ -94,7 +94,7 @@ let defaultService = null
94
94
 
95
95
  /**
96
96
  * Creates {@link selenium-webdriver/remote.DriverService} instances that manage
97
- * a [ChromeDriver](https://chromedriver.chromium.org/)
97
+ * a [MSEdgeDriver](https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/)
98
98
  * server in a child process.
99
99
  */
100
100
  class ServiceBuilder extends chromium.ServiceBuilder {
@@ -130,7 +130,7 @@ class Options extends chromium.Options {
130
130
  * The binary path be absolute or relative to the msedgedriver server
131
131
  * executable, but it must exist on the machine that will launch edge chromium.
132
132
  *
133
- * @param {string} path The path to the edgedriver binary to use.
133
+ * @param {string} path The path to the msedgedriver binary to use.
134
134
  * @return {!Options} A self reference.
135
135
  */
136
136
  setEdgeChromiumBinaryPath(path) {
package/lib/by.js CHANGED
@@ -225,7 +225,7 @@ class By {
225
225
  * @return {!By} The new locator.
226
226
  */
227
227
  static tagName(name) {
228
- return By.css(name)
228
+ return new By('tag name', name)
229
229
  }
230
230
 
231
231
  /**
package/lib/http.js CHANGED
@@ -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
  }
@@ -197,7 +197,6 @@ function toExecuteAtomCommand(command, atom, ...params) {
197
197
 
198
198
  /** @const {!Map<string, (CommandSpec|CommandTransformer)>} */
199
199
  const W3C_COMMAND_MAP = new Map([
200
-
201
200
  // Session management.
202
201
  [cmd.Name.NEW_SESSION, post('/session')],
203
202
  [cmd.Name.QUIT, del('/session/:sessionId')],
@@ -245,7 +244,6 @@ const W3C_COMMAND_MAP = new Map([
245
244
  [cmd.Name.CLEAR_ACTIONS, del('/session/:sessionId/actions')],
246
245
  [cmd.Name.PRINT_PAGE, post('/session/:sessionId/print')],
247
246
 
248
-
249
247
  // Locating elements.
250
248
  [cmd.Name.GET_ACTIVE_ELEMENT, get('/session/:sessionId/element/active')],
251
249
  [cmd.Name.FIND_ELEMENT, post('/session/:sessionId/element')],
@@ -266,7 +264,10 @@ const W3C_COMMAND_MAP = new Map([
266
264
  ],
267
265
  // Element interaction.
268
266
  [cmd.Name.GET_ELEMENT_TAG_NAME, get('/session/:sessionId/element/:id/name')],
269
- [cmd.Name.GET_DOM_ATTRIBUTE, get('/session/:sessionId/element/:id/attribute/:name')],
267
+ [
268
+ cmd.Name.GET_DOM_ATTRIBUTE,
269
+ get('/session/:sessionId/element/:id/attribute/:name'),
270
+ ],
270
271
  [
271
272
  cmd.Name.GET_ELEMENT_ATTRIBUTE,
272
273
  (cmd) => {
@@ -363,7 +364,7 @@ class Client {
363
364
  * @return {!Promise<Response>} A promise that will be fulfilled with the
364
365
  * server's response.
365
366
  */
366
- send(httpRequest) { } // eslint-disable-line
367
+ send(httpRequest) {} // eslint-disable-line
367
368
  }
368
369
 
369
370
  /**
@@ -609,5 +610,5 @@ module.exports = {
609
610
  Request: Request,
610
611
  Response: Response,
611
612
  // Exported for testing.
612
- buildPath: buildPath
613
+ buildPath: buildPath,
613
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
  /**
@@ -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/webdriver.js CHANGED
@@ -1197,14 +1197,25 @@ class WebDriver {
1197
1197
  * @return {!Promise<resolved>} A new CDP instance.
1198
1198
  */
1199
1199
  async createCDPConnection(target) {
1200
+ let debuggerUrl = null
1201
+
1200
1202
  const caps = await this.getCapabilities()
1201
- const seCdp = caps['map_'].get('se:cdp')
1202
- const vendorInfo =
1203
- caps['map_'].get(this.VENDOR_COMMAND_PREFIX + ':chromeOptions') ||
1204
- caps['map_'].get(this.VENDOR_CAPABILITY_PREFIX + ':edgeOptions') ||
1205
- caps['map_'].get('moz:debuggerAddress') ||
1206
- new Map()
1207
- const debuggerUrl = seCdp || vendorInfo['debuggerAddress'] || vendorInfo
1203
+
1204
+ if (process.env.SELENIUM_REMOTE_URL) {
1205
+ const host = new URL(process.env.SELENIUM_REMOTE_URL).host
1206
+ const sessionId = await this.getSession().then((session) =>
1207
+ session.getId()
1208
+ )
1209
+ debuggerUrl = `ws://${host}/session/${sessionId}/se/cdp`
1210
+ } else {
1211
+ const seCdp = caps['map_'].get('se:cdp')
1212
+ const vendorInfo =
1213
+ caps['map_'].get(this.VENDOR_COMMAND_PREFIX + ':chromeOptions') ||
1214
+ caps['map_'].get(this.VENDOR_CAPABILITY_PREFIX + ':edgeOptions') ||
1215
+ caps['map_'].get('moz:debuggerAddress') ||
1216
+ new Map()
1217
+ debuggerUrl = seCdp || vendorInfo['debuggerAddress'] || vendorInfo
1218
+ }
1208
1219
  this._wsUrl = await this.getWsUrl(debuggerUrl, target, caps)
1209
1220
  return new Promise((resolve, reject) => {
1210
1221
  try {
@@ -1945,14 +1956,10 @@ class Window {
1945
1956
  * @return {!Promise<{x: number, y: number, width: number, height: number}>}
1946
1957
  * A promise that will resolve to the window rect of the current window.
1947
1958
  */
1948
- async getRect() {
1949
- try {
1950
- return await this.driver_.execute(
1951
- new command.Command(command.Name.GET_WINDOW_RECT)
1952
- )
1953
- } catch (ex) {
1954
- throw ex
1955
- }
1959
+ getRect() {
1960
+ return this.driver_.execute(
1961
+ new command.Command(command.Name.GET_WINDOW_RECT)
1962
+ )
1956
1963
  }
1957
1964
 
1958
1965
  /**
@@ -1969,19 +1976,15 @@ class Window {
1969
1976
  * A promise that will resolve to the current window's updated window
1970
1977
  * rect.
1971
1978
  */
1972
- async setRect({ x, y, width, height }) {
1973
- try {
1974
- return await this.driver_.execute(
1975
- new command.Command(command.Name.SET_WINDOW_RECT).setParameters({
1976
- x,
1977
- y,
1978
- width,
1979
- height,
1980
- })
1981
- )
1982
- } catch (ex) {
1983
- throw ex
1984
- }
1979
+ setRect({ x, y, width, height }) {
1980
+ return this.driver_.execute(
1981
+ new command.Command(command.Name.SET_WINDOW_RECT).setParameters({
1982
+ x,
1983
+ y,
1984
+ width,
1985
+ height,
1986
+ })
1987
+ )
1985
1988
  }
1986
1989
 
1987
1990
  /**
@@ -2522,12 +2525,12 @@ class WebElement {
2522
2525
  if (type === 'number') {
2523
2526
  key = String(key)
2524
2527
  } else if (type !== 'string') {
2525
- throw TypeError('each key must be a number of string; got ' + type)
2528
+ throw TypeError('each key must be a number or string; got ' + type)
2526
2529
  }
2527
2530
 
2528
2531
  // The W3C protocol requires keys to be specified as an array where
2529
2532
  // each element is a single key.
2530
- keys.push(...key.split(''))
2533
+ keys.push(...key)
2531
2534
  })
2532
2535
 
2533
2536
  if (!this.driver_.fileDetector_) {
@@ -2544,7 +2547,10 @@ class WebElement {
2544
2547
  keys.join('')
2545
2548
  )
2546
2549
  } catch (ex) {
2547
- console.log('Error trying parse string as a file with file detector; sending keys instead' + ex)
2550
+ console.log(
2551
+ 'Error trying parse string as a file with file detector; sending keys instead' +
2552
+ ex
2553
+ )
2548
2554
  }
2549
2555
 
2550
2556
  return this.execute_(
@@ -2715,14 +2721,8 @@ class WebElement {
2715
2721
  * @return {!Promise<{width: number, height: number, x: number, y: number}>}
2716
2722
  * A promise that will resolve with the element's rect.
2717
2723
  */
2718
- async getRect() {
2719
- try {
2720
- return await this.execute_(
2721
- new command.Command(command.Name.GET_ELEMENT_RECT)
2722
- )
2723
- } catch (err) {
2724
- throw err;
2725
- }
2724
+ getRect() {
2725
+ return this.execute_(new command.Command(command.Name.GET_ELEMENT_RECT))
2726
2726
  }
2727
2727
 
2728
2728
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "selenium-webdriver",
3
- "version": "4.1.1",
3
+ "version": "4.1.2",
4
4
  "description": "The official WebDriver JavaScript bindings from the Selenium project",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
@@ -35,7 +35,7 @@
35
35
  "eslint-plugin-prettier": "^3.4.0",
36
36
  "express": "^4.17.1",
37
37
  "jasmine": "^3.8.0",
38
- "mocha": "^8.1.0",
38
+ "mocha": "^9.2.2",
39
39
  "multer": "^1.4.2",
40
40
  "prettier": "^2.3.0",
41
41
  "serve-index": "^1.9.1",