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/CHANGES.md +58 -0
- package/README.md +29 -29
- package/bin/linux/selenium-manager +0 -0
- package/bin/macos/selenium-manager +0 -0
- package/bin/windows/selenium-manager.exe +0 -0
- package/chrome.js +21 -5
- package/chromium.js +1 -1
- package/common/seleniumManager.js +91 -0
- package/edge.js +15 -0
- package/firefox.js +18 -6
- package/index.js +2 -0
- package/io/exec.js +7 -4
- package/lib/by.js +1 -2
- package/lib/command.js +3 -3
- package/lib/error.js +8 -8
- package/lib/http.js +11 -13
- package/lib/input.js +10 -1
- package/lib/promise.js +2 -11
- package/lib/select.js +466 -0
- package/lib/until.js +46 -21
- package/lib/util.js +52 -0
- package/lib/virtual_authenticator.js +53 -29
- package/lib/webdriver.js +31 -42
- package/lib/webelement.js +66 -0
- package/net/index.js +1 -5
- package/package.json +2 -2
- package/remote/index.js +1 -1
- package/testing/index.js +1 -1
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 =
|
|
43
|
-
this._transport =
|
|
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
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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(
|
|
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(
|
|
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')
|
|
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
|
|
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
|
|
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
|
-
*
|
|
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
|
|
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:
|
|
622
|
-
* scale:
|
|
623
|
-
* background:
|
|
624
|
-
* width:
|
|
625
|
-
* height:
|
|
626
|
-
* top:
|
|
627
|
-
* bottom:
|
|
628
|
-
* left:
|
|
629
|
-
* right:
|
|
630
|
-
* shrinkToFit:
|
|
631
|
-
* pageRanges:
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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[
|
|
2996
|
-
return obj[
|
|
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[
|
|
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
|
|
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
|
-
|
|
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.
|
|
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": ">=
|
|
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}[]
|
|
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']
|