selenium-webdriver 4.4.0 → 4.6.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/util.js ADDED
@@ -0,0 +1,52 @@
1
+ // Licensed to the Software Freedom Conservancy (SFC) under one
2
+ // or more contributor license agreements. See the NOTICE file
3
+ // distributed with this work for additional information
4
+ // regarding copyright ownership. The SFC licenses this file
5
+ // to you under the Apache License, Version 2.0 (the
6
+ // "License"); you may not use this file except in compliance
7
+ // with the License. You may obtain a copy of the License at
8
+ //
9
+ // http://www.apache.org/licenses/LICENSE-2.0
10
+ //
11
+ // Unless required by applicable law or agreed to in writing,
12
+ // software distributed under the License is distributed on an
13
+ // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ // KIND, either express or implied. See the License for the
15
+ // specific language governing permissions and limitations
16
+ // under the License.
17
+
18
+ 'use strict'
19
+
20
+ /**
21
+ * Determines whether a {@code value} should be treated as an object.
22
+ * @param {?} value The value to test.
23
+ * @returns {boolean} Whether the value is an object.
24
+ */
25
+ function isObject(value) {
26
+ return Object.prototype.toString.call(value) === '[object Object]'
27
+ }
28
+
29
+ /**
30
+ * Determines whether a {@code value} should be treated as a promise.
31
+ * Any object whose "then" property is a function will be considered a promise.
32
+ *
33
+ * @param {?} value The value to test.
34
+ * @return {boolean} Whether the value is a promise.
35
+ */
36
+ function isPromise(value) {
37
+ try {
38
+ // Use array notation so the Closure compiler does not obfuscate away our
39
+ // contract.
40
+ return (
41
+ (typeof value === 'object' || typeof value === 'function') &&
42
+ typeof value['then'] === 'function'
43
+ )
44
+ } catch (ex) {
45
+ return false
46
+ }
47
+ }
48
+
49
+ module.exports = {
50
+ isObject,
51
+ isPromise,
52
+ }
@@ -17,30 +17,37 @@
17
17
 
18
18
  'use strict'
19
19
 
20
+ /**
21
+ * Protocol for virtual authenticators
22
+ * @enum {string}
23
+ */
24
+ const Protocol = {
25
+ CTAP2: 'ctap2',
26
+ U2F: 'ctap1/u2f',
27
+ }
28
+
29
+ /**
30
+ * AuthenticatorTransport values
31
+ * @enum {string}
32
+ */
33
+ const Transport = {
34
+ BLE: 'ble',
35
+ USB: 'usb',
36
+ NFC: 'nfc',
37
+ INTERNAL: 'internal',
38
+ }
39
+
20
40
  /**
21
41
  * Options for the creation of virtual authenticators.
22
42
  * @see http://w3c.github.io/webauthn/#sctn-automation
23
43
  */
24
44
  class VirtualAuthenticatorOptions {
25
-
26
- static Protocol = {
27
- "CTAP2": 'ctap2',
28
- "U2F": 'ctap1/u2f',
29
- }
30
-
31
- static Transport = {
32
- "BLE": 'ble',
33
- "USB": 'usb',
34
- "NFC": 'nfc',
35
- "INTERNAL": 'internal',
36
- }
37
-
38
45
  /**
39
46
  * Constructor to initialise VirtualAuthenticatorOptions object.
40
47
  */
41
48
  constructor() {
42
- this._protocol = VirtualAuthenticatorOptions.Protocol["CTAP2"]
43
- this._transport = VirtualAuthenticatorOptions.Transport["USB"]
49
+ this._protocol = Protocol['CTAP2']
50
+ this._transport = Transport['USB']
44
51
  this._hasResidentKey = false
45
52
  this._hasUserVerification = false
46
53
  this._isUserConsenting = true
@@ -97,13 +104,12 @@ class VirtualAuthenticatorOptions {
97
104
 
98
105
  toDict() {
99
106
  return {
100
- "protocol": this.getProtocol(),
101
- "transport": this.getTransport(),
102
- "hasResidentKey": this.getHasResidentKey(),
103
- "hasUserVerification": this.getHasUserVerification(),
104
- "isUserConsenting": this.getIsUserConsenting(),
105
- "isUserVerified": this.getIsUserVerified(),
106
-
107
+ protocol: this.getProtocol(),
108
+ transport: this.getTransport(),
109
+ hasResidentKey: this.getHasResidentKey(),
110
+ hasUserVerification: this.getHasUserVerification(),
111
+ isUserConsenting: this.getIsUserConsenting(),
112
+ isUserVerified: this.getIsUserVerified(),
107
113
  }
108
114
  }
109
115
  }
@@ -163,35 +169,47 @@ class Credential {
163
169
  * @param userHandle userHandle associated to the credential. Must be Base64 encoded string.
164
170
  * @param privateKey Base64 encoded PKCS
165
171
  * @param signCount initial value for a signature counter.
172
+ * @deprecated This method has been made static. Call it with class name. Example, Credential.createResidentCredential()
166
173
  * @returns A resident credential
167
174
  */
168
175
  createResidentCredential(id, rpId, userHandle, privateKey, signCount) {
169
176
  return new Credential(id, true, rpId, userHandle, privateKey, signCount)
170
177
  }
171
178
 
179
+ static createResidentCredential(id, rpId, userHandle, privateKey, signCount) {
180
+ return new Credential(id, true, rpId, userHandle, privateKey, signCount)
181
+ }
182
+
172
183
  /**
173
184
  * Creates a non-resident (i.e. stateless) credential.
174
185
  * @param id Unique base64 encoded string.
175
186
  * @param rpId Relying party identifier.
176
187
  * @param privateKey Base64 encoded PKCS
177
188
  * @param signCount initial value for a signature counter.
189
+ * @deprecated This method has been made static. Call it with class name. Example, Credential.createNonResidentCredential()
178
190
  * @returns A non-resident credential
179
191
  */
180
192
  createNonResidentCredential(id, rpId, privateKey, signCount) {
181
193
  return new Credential(id, false, rpId, null, privateKey, signCount)
182
194
  }
183
195
 
196
+ static createNonResidentCredential(id, rpId, privateKey, signCount) {
197
+ return new Credential(id, false, rpId, null, privateKey, signCount)
198
+ }
199
+
184
200
  toDict() {
185
201
  let credentialData = {
186
- 'credentialId': Buffer.from(this._id).toString('base64url'),
187
- 'isResidentCredential': this._isResidentCredential,
188
- 'rpId': this._rpId,
189
- 'privateKey': Buffer.from(this._privateKey, 'binary').toString('base64url'),
190
- 'signCount': this._signCount,
202
+ credentialId: Buffer.from(this._id).toString('base64url'),
203
+ isResidentCredential: this._isResidentCredential,
204
+ rpId: this._rpId,
205
+ privateKey: Buffer.from(this._privateKey, 'binary').toString('base64url'),
206
+ signCount: this._signCount,
191
207
  }
192
208
 
193
209
  if (this.userHandle() != null) {
194
- credentialData['userHandle'] = Buffer.from(this._userHandle).toString('base64url')
210
+ credentialData['userHandle'] = Buffer.from(this._userHandle).toString(
211
+ 'base64url'
212
+ )
195
213
  }
196
214
 
197
215
  return credentialData
@@ -204,7 +222,9 @@ class Credential {
204
222
  let id = new Uint8Array(Buffer.from(data['credentialId'], 'base64url'))
205
223
  let isResidentCredential = data['isResidentCredential']
206
224
  let rpId = data['rpId']
207
- let privateKey = Buffer.from(data['privateKey'], 'base64url').toString('binary')
225
+ let privateKey = Buffer.from(data['privateKey'], 'base64url').toString(
226
+ 'binary'
227
+ )
208
228
  let signCount = data['signCount']
209
229
  let userHandle
210
230
 
@@ -224,7 +244,11 @@ class Credential {
224
244
  }
225
245
  }
226
246
 
247
+ // PUBLIC API
248
+
227
249
  module.exports = {
228
250
  Credential,
229
251
  VirtualAuthenticatorOptions,
252
+ Transport,
253
+ Protocol,
230
254
  }
package/lib/webdriver.js CHANGED
@@ -37,7 +37,9 @@ const { Capabilities } = require('./capabilities')
37
37
  const path = require('path')
38
38
  const { NoSuchElementError } = require('./error')
39
39
  const cdpTargets = ['page', 'browser']
40
- const Credential = require('./virtual_authenticator').Credential
40
+ const { Credential } = require('./virtual_authenticator')
41
+ const webElement = require('./webelement')
42
+ const { isObject } = require('./util')
41
43
 
42
44
  // Capability names that are defined in the W3C spec.
43
45
  const W3C_CAPABILITY_NAMES = new Set([
@@ -213,7 +215,7 @@ function fromWireValue(driver, value) {
213
215
  } else if (ShadowRoot.isId(value)) {
214
216
  let id = ShadowRoot.extractId(value)
215
217
  value = new ShadowRoot(driver, id)
216
- } else if (value && typeof value === 'object') {
218
+ } else if (isObject(value)) {
217
219
  let result = {}
218
220
  for (let key in value) {
219
221
  if (Object.prototype.hasOwnProperty.call(value, key)) {
@@ -272,7 +274,7 @@ class IWebDriver {
272
274
 
273
275
  /**
274
276
  * @return {!Promise<!Capabilities>} A promise that will resolve with
275
- * the this instance's capabilities.
277
+ * the instance's capabilities.
276
278
  */
277
279
  getCapabilities() {}
278
280
 
@@ -453,7 +455,7 @@ class IWebDriver {
453
455
  * @return {!(IThenable<T>|WebElementPromise)} A promise that will be
454
456
  * resolved with the first truthy value returned by the condition
455
457
  * function, or rejected if the condition times out. If the input
456
- * input condition is an instance of a {@link WebElementCondition},
458
+ * condition is an instance of a {@link WebElementCondition},
457
459
  * the returned value will be a {@link WebElementPromise}.
458
460
  * @throws {TypeError} if the provided `condition` is not a valid type.
459
461
  * @template T
@@ -584,7 +586,7 @@ class IWebDriver {
584
586
  findElements(locator) {} // eslint-disable-line
585
587
 
586
588
  /**
587
- * Takes a screenshot of the current page. The driver makes a best effort to
589
+ * Takes a screenshot of the current page. The driver makes the best effort to
588
590
  * return a screenshot of the following, in order of preference:
589
591
  *
590
592
  * 1. Entire page
@@ -618,17 +620,17 @@ class IWebDriver {
618
620
  * Takes a PDF of the current page. The driver makes a best effort to
619
621
  * return a PDF based on the provided parameters.
620
622
  *
621
- * @param {{orientation: (string|undefined),
622
- * scale: (number|undefined),
623
- * background: (boolean|undefined)
624
- * width: (number|undefined)
625
- * height: (number|undefined)
626
- * top: (number|undefined)
627
- * bottom: (number|undefined)
628
- * left: (number|undefined)
629
- * right: (number|undefined)
630
- * shrinkToFit: (boolean|undefined)
631
- * pageRanges: (<Array>|undefined)}} options.
623
+ * @param {{orientation:(string|undefined),
624
+ * scale:(number|undefined),
625
+ * background:(boolean|undefined),
626
+ * width:(number|undefined),
627
+ * height:(number|undefined),
628
+ * top:(number|undefined),
629
+ * bottom:(number|undefined),
630
+ * left:(number|undefined),
631
+ * right:(number|undefined),
632
+ * shrinkToFit:(boolean|undefined),
633
+ * pageRanges:(Array|undefined)}} options
632
634
  */
633
635
  printPage(options) {} // eslint-disable-line
634
636
  }
@@ -713,10 +715,9 @@ class WebDriver {
713
715
  static createSession(executor, capabilities, onQuit = undefined) {
714
716
  let cmd = new command.Command(command.Name.NEW_SESSION)
715
717
 
716
- // For OSS remote ends.
717
- cmd.setParameter('desiredCapabilities', capabilities)
718
718
  // For W3C remote ends.
719
719
  cmd.setParameter('capabilities', {
720
+ firstMatch: [{}],
720
721
  alwaysMatch: filterNonW3CCaps(capabilities),
721
722
  })
722
723
 
@@ -1311,7 +1312,7 @@ class WebDriver {
1311
1312
 
1312
1313
  /**
1313
1314
  * Sets a listener for Fetch.authRequired event from CDP
1314
- * If event is triggered, it enter username and password
1315
+ * If event is triggered, it enters username and password
1315
1316
  * and allows the test to move forward
1316
1317
  * @param {string} username
1317
1318
  * @param {string} password
@@ -1530,7 +1531,7 @@ class WebDriver {
1530
1531
 
1531
1532
  /**
1532
1533
  * Adds a virtual authenticator with the given options.
1533
- * @param options VirtualAuthenticatorOptions object to set authenticator optons.
1534
+ * @param options VirtualAuthenticatorOptions object to set authenticator options.
1534
1535
  */
1535
1536
  async addVirtualAuthenticator(options) {
1536
1537
  this.authenticatorId_ = await this.execute(
@@ -2058,7 +2059,7 @@ class Window {
2058
2059
  }
2059
2060
 
2060
2061
  /**
2061
- * Retrieves the a rect describing the current top-level window's size and
2062
+ * Retrieves a rect describing the current top-level window's size and
2062
2063
  * position.
2063
2064
  *
2064
2065
  * @return {!Promise<{x: number, y: number, width: number, height: number}>}
@@ -2382,7 +2383,7 @@ class TargetLocator {
2382
2383
 
2383
2384
  const LEGACY_ELEMENT_ID_KEY = 'ELEMENT'
2384
2385
  const ELEMENT_ID_KEY = 'element-6066-11e4-a52e-4f735466cecf'
2385
- const SHADOWROOT_ID_KEY = 'shadow-6066-11e4-a52e-4f735466cecf'
2386
+ const SHADOW_ROOT_ID_KEY = 'shadow-6066-11e4-a52e-4f735466cecf'
2386
2387
 
2387
2388
  /**
2388
2389
  * Represents a DOM element. WebElements can be found by searching from the
@@ -2427,14 +2428,7 @@ class WebElement {
2427
2428
  * @throws {TypeError} if the object is not a valid encoded ID.
2428
2429
  */
2429
2430
  static extractId(obj) {
2430
- if (obj && typeof obj === 'object') {
2431
- if (typeof obj[ELEMENT_ID_KEY] === 'string') {
2432
- return obj[ELEMENT_ID_KEY]
2433
- } else if (typeof obj[LEGACY_ELEMENT_ID_KEY] === 'string') {
2434
- return obj[LEGACY_ELEMENT_ID_KEY]
2435
- }
2436
- }
2437
- throw new TypeError('object is not a WebElement ID')
2431
+ return webElement.extractId(obj)
2438
2432
  }
2439
2433
 
2440
2434
  /**
@@ -2442,12 +2436,7 @@ class WebElement {
2442
2436
  * @return {boolean} whether the object is a valid encoded WebElement ID.
2443
2437
  */
2444
2438
  static isId(obj) {
2445
- return (
2446
- obj &&
2447
- typeof obj === 'object' &&
2448
- (typeof obj[ELEMENT_ID_KEY] === 'string' ||
2449
- typeof obj[LEGACY_ELEMENT_ID_KEY] === 'string')
2450
- )
2439
+ return webElement.isId(obj)
2451
2440
  }
2452
2441
 
2453
2442
  /**
@@ -2550,7 +2539,7 @@ class WebElement {
2550
2539
  }
2551
2540
 
2552
2541
  /**
2553
- * Locates all of the descendants of this element that match the given search
2542
+ * Locates all the descendants of this element that match the given search
2554
2543
  * criteria.
2555
2544
  *
2556
2545
  * @param {!(by.By|Function)} locator The locator strategy to use when
@@ -2717,7 +2706,7 @@ class WebElement {
2717
2706
  * the value of the property with the same name is returned. If neither value
2718
2707
  * is set, null is returned (for example, the "value" property of a textarea
2719
2708
  * element). The "style" attribute is converted as best can be to a
2720
- * text representation with a trailing semi-colon. The following are deemed to
2709
+ * text representation with a trailing semicolon. The following are deemed to
2721
2710
  * be "boolean" attributes and will return either "true" or null:
2722
2711
  *
2723
2712
  * async, autofocus, autoplay, checked, compact, complete, controls, declare,
@@ -2992,8 +2981,8 @@ class ShadowRoot {
2992
2981
  */
2993
2982
  static extractId(obj) {
2994
2983
  if (obj && typeof obj === 'object') {
2995
- if (typeof obj[SHADOWROOT_ID_KEY] === 'string') {
2996
- return obj[SHADOWROOT_ID_KEY]
2984
+ if (typeof obj[SHADOW_ROOT_ID_KEY] === 'string') {
2985
+ return obj[SHADOW_ROOT_ID_KEY]
2997
2986
  }
2998
2987
  }
2999
2988
  throw new TypeError('object is not a ShadowRoot ID')
@@ -3007,7 +2996,7 @@ class ShadowRoot {
3007
2996
  return (
3008
2997
  obj &&
3009
2998
  typeof obj === 'object' &&
3010
- typeof obj[SHADOWROOT_ID_KEY] === 'string'
2999
+ typeof obj[SHADOW_ROOT_ID_KEY] === 'string'
3011
3000
  )
3012
3001
  }
3013
3002
 
@@ -3083,7 +3072,7 @@ class ShadowRoot {
3083
3072
  }
3084
3073
 
3085
3074
  /**
3086
- * Locates all of the descendants of this element that match the given search
3075
+ * Locates all the descendants of this element that match the given search
3087
3076
  * criteria.
3088
3077
  *
3089
3078
  * @param {!(by.By|Function)} locator The locator strategy to use when
@@ -0,0 +1,66 @@
1
+ // Licensed to the Software Freedom Conservancy (SFC) under one
2
+ // or more contributor license agreements. See the NOTICE file
3
+ // distributed with this work for additional information
4
+ // regarding copyright ownership. The SFC licenses this file
5
+ // to you under the Apache License, Version 2.0 (the
6
+ // "License"); you may not use this file except in compliance
7
+ // with the License. You may obtain a copy of the License at
8
+ //
9
+ // http://www.apache.org/licenses/LICENSE-2.0
10
+ //
11
+ // Unless required by applicable law or agreed to in writing,
12
+ // software distributed under the License is distributed on an
13
+ // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ // KIND, either express or implied. See the License for the
15
+ // specific language governing permissions and limitations
16
+ // under the License.
17
+
18
+ 'use strict'
19
+ const { isObject } = require('./util')
20
+
21
+ /**
22
+ * @fileoverview Defines some common methods used for WebElements.
23
+ */
24
+
25
+ const LEGACY_ELEMENT_ID_KEY = 'ELEMENT'
26
+ const ELEMENT_ID_KEY = 'element-6066-11e4-a52e-4f735466cecf'
27
+
28
+ /**
29
+ * Contains logic about WebElements.
30
+ */
31
+ /**
32
+ * @param {?} obj the object to test.
33
+ * @return {boolean} whether the object is a valid encoded WebElement ID.
34
+ */
35
+ function isId(obj) {
36
+ return (
37
+ isObject(obj) &&
38
+ (typeof obj[ELEMENT_ID_KEY] === 'string' ||
39
+ typeof obj[LEGACY_ELEMENT_ID_KEY] === 'string')
40
+ )
41
+ }
42
+
43
+ /**
44
+ * Extracts the encoded WebElement ID from the object.
45
+ *
46
+ * @param {?} obj The object to extract the ID from.
47
+ * @return {string} the extracted ID.
48
+ * @throws {TypeError} if the object is not a valid encoded ID.
49
+ */
50
+ function extractId(obj) {
51
+ if (isObject(obj)) {
52
+ if (typeof obj[ELEMENT_ID_KEY] === 'string') {
53
+ return obj[ELEMENT_ID_KEY]
54
+ } else if (typeof obj[LEGACY_ELEMENT_ID_KEY] === 'string') {
55
+ return obj[LEGACY_ELEMENT_ID_KEY]
56
+ }
57
+ }
58
+ throw new TypeError('object is not a WebElement ID')
59
+ }
60
+
61
+ // PUBLIC API
62
+
63
+ module.exports = {
64
+ isId,
65
+ extractId,
66
+ }
package/net/index.js CHANGED
@@ -76,11 +76,7 @@ function getAddress(family = 'IPv4') {
76
76
  * @return {(string|undefined)} The IP address or undefined if not available.
77
77
  */
78
78
  function getLoopbackAddress(family = 'IPv4') {
79
- let address = getIPAddress(true, family)
80
- if (address === '127.0.0.1') {
81
- address = 'localhost'
82
- }
83
- return address
79
+ return getIPAddress(true, family)
84
80
  }
85
81
 
86
82
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "selenium-webdriver",
3
- "version": "4.4.0",
3
+ "version": "4.6.0",
4
4
  "description": "The official WebDriver JavaScript bindings from the Selenium project",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
@@ -20,7 +20,7 @@
20
20
  "url": "https://github.com/SeleniumHQ/selenium.git"
21
21
  },
22
22
  "engines": {
23
- "node": ">= 10.15.0"
23
+ "node": ">= 14.20.0"
24
24
  },
25
25
  "dependencies": {
26
26
  "jszip": "^3.10.0",
package/remote/index.js CHANGED
@@ -23,7 +23,7 @@ const url = require('url')
23
23
 
24
24
  const httpUtil = require('../http/util')
25
25
  const io = require('../io')
26
- const exec = require('../io/exec')
26
+ const { exec } = require('../io/exec')
27
27
  const { Zip } = require('../io/zip')
28
28
  const cmd = require('../lib/command')
29
29
  const input = require('../lib/input')
package/testing/index.js CHANGED
@@ -88,7 +88,7 @@ function warn(msg) {
88
88
  * Extracts the browsers for a test suite to target from the `SELENIUM_BROWSER`
89
89
  * environment variable.
90
90
  *
91
- * @return {{name: string, version: string, platform: string}[]} the browsers to target.
91
+ * @return {{name: string, version: string, platform: string}}[] the browsers to target.
92
92
  */
93
93
  function getBrowsersToTestFromEnv() {
94
94
  let browsers = process.env['SELENIUM_BROWSER']