selenium-webdriver 4.17.0 → 4.18.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 +236 -196
- package/bidi/addInterceptParameters.js +86 -0
- package/bidi/browsingContext.js +144 -37
- package/bidi/browsingContextInspector.js +13 -40
- package/bidi/evaluateResult.js +4 -10
- package/bidi/filterBy.js +2 -6
- package/bidi/index.js +31 -29
- package/bidi/input.js +1 -4
- package/bidi/interceptPhase.js +24 -0
- package/bidi/logInspector.js +15 -20
- package/bidi/network.js +178 -0
- package/bidi/networkInspector.js +8 -2
- package/bidi/networkTypes.js +22 -49
- package/bidi/protocolType.js +3 -9
- package/bidi/protocolValue.js +6 -25
- package/bidi/realmInfo.js +2 -10
- package/bidi/scriptManager.js +20 -59
- package/bidi/urlPattern.js +58 -0
- 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 +1 -8
- package/chromium.js +27 -109
- package/common/driverFinder.js +1 -1
- package/common/seleniumManager.js +9 -18
- package/devtools/CDPConnection.js +1 -3
- package/edge.js +1 -3
- package/example/chrome_android.js +2 -5
- package/example/chrome_mobile_emulation.js +2 -4
- package/example/google_search.js +1 -3
- package/example/headless.js +4 -10
- package/example/logging.js +3 -9
- package/firefox.js +55 -109
- package/http/index.js +7 -10
- package/ie.js +5 -15
- package/index.js +7 -29
- package/io/exec.js +1 -2
- package/io/index.js +3 -3
- package/io/zip.js +8 -30
- package/lib/by.js +2 -9
- package/lib/capabilities.js +3 -9
- package/lib/command.js +3 -3
- package/lib/error.js +2 -9
- package/lib/http.js +34 -131
- package/lib/input.js +10 -34
- package/lib/logging.js +3 -11
- package/lib/promise.js +2 -7
- package/lib/select.js +3 -9
- package/lib/until.js +28 -49
- package/lib/util.js +1 -4
- package/lib/virtual_authenticator.js +4 -22
- package/lib/webdriver.js +118 -297
- package/lib/webelement.js +1 -5
- package/net/index.js +1 -4
- package/package.json +2 -1
- package/remote/index.js +9 -24
- package/remote/util.js +6 -19
- package/safari.js +3 -8
- package/testing/index.js +6 -11
package/io/index.js
CHANGED
|
@@ -293,7 +293,7 @@ function mkdirp(dir) {
|
|
|
293
293
|
.then(() => mkdirp(dir))
|
|
294
294
|
.then(
|
|
295
295
|
() => callback(null, dir),
|
|
296
|
-
(err) => callback(err)
|
|
296
|
+
(err) => callback(err),
|
|
297
297
|
)
|
|
298
298
|
default:
|
|
299
299
|
callback(err)
|
|
@@ -326,8 +326,8 @@ function walkDir(rootPath) {
|
|
|
326
326
|
})
|
|
327
327
|
return stats.isDirectory() && walk(file)
|
|
328
328
|
})
|
|
329
|
-
})
|
|
330
|
-
)
|
|
329
|
+
}),
|
|
330
|
+
),
|
|
331
331
|
)
|
|
332
332
|
})(rootPath).then(() => seen)
|
|
333
333
|
}
|
package/io/zip.js
CHANGED
|
@@ -46,19 +46,14 @@ class Zip {
|
|
|
46
46
|
addFile(filePath, zipPath = path.basename(filePath)) {
|
|
47
47
|
let add = io
|
|
48
48
|
.read(filePath)
|
|
49
|
-
.then((buffer) =>
|
|
50
|
-
this.z_.file(
|
|
51
|
-
/** @type {string} */ (zipPath.replace(/\\/g, '/')),
|
|
52
|
-
buffer
|
|
53
|
-
)
|
|
54
|
-
)
|
|
49
|
+
.then((buffer) => this.z_.file(/** @type {string} */ (zipPath.replace(/\\/g, '/')), buffer))
|
|
55
50
|
this.pendingAdds_.add(add)
|
|
56
51
|
return add.then(
|
|
57
52
|
() => this.pendingAdds_.delete(add),
|
|
58
53
|
(e) => {
|
|
59
54
|
this.pendingAdds_.delete(add)
|
|
60
55
|
throw e
|
|
61
|
-
}
|
|
56
|
+
},
|
|
62
57
|
)
|
|
63
58
|
}
|
|
64
59
|
|
|
@@ -83,12 +78,7 @@ class Zip {
|
|
|
83
78
|
if (spec.dir) {
|
|
84
79
|
archive.folder(spec.path)
|
|
85
80
|
} else {
|
|
86
|
-
files.push(
|
|
87
|
-
this.addFile(
|
|
88
|
-
path.join(dirPath, spec.path),
|
|
89
|
-
path.join(zipPath, spec.path)
|
|
90
|
-
)
|
|
91
|
-
)
|
|
81
|
+
files.push(this.addFile(path.join(dirPath, spec.path), path.join(zipPath, spec.path)))
|
|
92
82
|
}
|
|
93
83
|
})
|
|
94
84
|
|
|
@@ -118,15 +108,11 @@ class Zip {
|
|
|
118
108
|
getFile(path) {
|
|
119
109
|
let file = this.z_.file(path)
|
|
120
110
|
if (!file) {
|
|
121
|
-
return Promise.reject(
|
|
122
|
-
new InvalidArgumentError(`No such file in zip archive: ${path}`)
|
|
123
|
-
)
|
|
111
|
+
return Promise.reject(new InvalidArgumentError(`No such file in zip archive: ${path}`))
|
|
124
112
|
}
|
|
125
113
|
|
|
126
114
|
if (file.dir) {
|
|
127
|
-
return Promise.reject(
|
|
128
|
-
new InvalidArgumentError(`The requested file is a directory: ${path}`)
|
|
129
|
-
)
|
|
115
|
+
return Promise.reject(new InvalidArgumentError(`The requested file is a directory: ${path}`))
|
|
130
116
|
}
|
|
131
117
|
|
|
132
118
|
return Promise.resolve(file.async('nodebuffer'))
|
|
@@ -144,15 +130,9 @@ class Zip {
|
|
|
144
130
|
*/
|
|
145
131
|
toBuffer(compression = 'STORE') {
|
|
146
132
|
if (compression !== 'STORE' && compression !== 'DEFLATE') {
|
|
147
|
-
return Promise.reject(
|
|
148
|
-
new InvalidArgumentError(
|
|
149
|
-
`compression must be one of {STORE, DEFLATE}, got ${compression}`
|
|
150
|
-
)
|
|
151
|
-
)
|
|
133
|
+
return Promise.reject(new InvalidArgumentError(`compression must be one of {STORE, DEFLATE}, got ${compression}`))
|
|
152
134
|
}
|
|
153
|
-
return Promise.resolve(
|
|
154
|
-
this.z_.generateAsync({ compression, type: 'nodebuffer' })
|
|
155
|
-
)
|
|
135
|
+
return Promise.resolve(this.z_.generateAsync({ compression, type: 'nodebuffer' }))
|
|
156
136
|
}
|
|
157
137
|
}
|
|
158
138
|
|
|
@@ -210,9 +190,7 @@ function unzip(src, dst) {
|
|
|
210
190
|
}
|
|
211
191
|
|
|
212
192
|
function writeFile(relPath, file) {
|
|
213
|
-
return file
|
|
214
|
-
.async('nodebuffer')
|
|
215
|
-
.then((buffer) => io.write(path.join(dst, relPath), buffer))
|
|
193
|
+
return file.async('nodebuffer').then((buffer) => io.write(path.join(dst, relPath), buffer))
|
|
216
194
|
}
|
|
217
195
|
})
|
|
218
196
|
}
|
package/lib/by.js
CHANGED
|
@@ -396,11 +396,7 @@ class RelativeBy {
|
|
|
396
396
|
* strategy.
|
|
397
397
|
*/
|
|
398
398
|
function check(locator) {
|
|
399
|
-
if (
|
|
400
|
-
locator instanceof By ||
|
|
401
|
-
locator instanceof RelativeBy ||
|
|
402
|
-
typeof locator === 'function'
|
|
403
|
-
) {
|
|
399
|
+
if (locator instanceof By || locator instanceof RelativeBy || typeof locator === 'function') {
|
|
404
400
|
return locator
|
|
405
401
|
}
|
|
406
402
|
|
|
@@ -414,10 +410,7 @@ function check(locator) {
|
|
|
414
410
|
}
|
|
415
411
|
|
|
416
412
|
for (let key in locator) {
|
|
417
|
-
if (
|
|
418
|
-
Object.prototype.hasOwnProperty.call(locator, key) &&
|
|
419
|
-
Object.prototype.hasOwnProperty.call(By, key)
|
|
420
|
-
) {
|
|
413
|
+
if (Object.prototype.hasOwnProperty.call(locator, key) && Object.prototype.hasOwnProperty.call(By, key)) {
|
|
421
414
|
return By[key](locator[key])
|
|
422
415
|
}
|
|
423
416
|
}
|
package/lib/capabilities.js
CHANGED
|
@@ -210,8 +210,7 @@ const Capability = {
|
|
|
210
210
|
*/
|
|
211
211
|
STRICT_FILE_INTERACTABILITY: 'strictFileInteractability',
|
|
212
212
|
|
|
213
|
-
|
|
214
|
-
ENABLE_DOWNLOADS: "se:downloadsEnabled",
|
|
213
|
+
ENABLE_DOWNLOADS: 'se:downloadsEnabled',
|
|
215
214
|
}
|
|
216
215
|
|
|
217
216
|
/**
|
|
@@ -265,9 +264,7 @@ class Capabilities {
|
|
|
265
264
|
* @return {!Capabilities} A basic set of capabilities for Firefox.
|
|
266
265
|
*/
|
|
267
266
|
static firefox() {
|
|
268
|
-
return new Capabilities()
|
|
269
|
-
.setBrowserName(Browser.FIREFOX)
|
|
270
|
-
.set('moz:debuggerAddress', true)
|
|
267
|
+
return new Capabilities().setBrowserName(Browser.FIREFOX).set('moz:debuggerAddress', true)
|
|
271
268
|
}
|
|
272
269
|
|
|
273
270
|
/**
|
|
@@ -517,10 +514,7 @@ class Capabilities {
|
|
|
517
514
|
* Sets the boolean flag configuration for this instance.
|
|
518
515
|
*/
|
|
519
516
|
setStrictFileInteractability(strictFileInteractability) {
|
|
520
|
-
return this.set(
|
|
521
|
-
Capability.STRICT_FILE_INTERACTABILITY,
|
|
522
|
-
strictFileInteractability
|
|
523
|
-
)
|
|
517
|
+
return this.set(Capability.STRICT_FILE_INTERACTABILITY, strictFileInteractability)
|
|
524
518
|
}
|
|
525
519
|
|
|
526
520
|
enableDownloads() {
|
package/lib/command.js
CHANGED
|
@@ -182,9 +182,9 @@ const Name = {
|
|
|
182
182
|
ACTIONS: 'actions',
|
|
183
183
|
CLEAR_ACTIONS: 'clearActions',
|
|
184
184
|
|
|
185
|
-
GET_DOWNLOADABLE_FILES:
|
|
186
|
-
DOWNLOAD_FILE:
|
|
187
|
-
DELETE_DOWNLOADABLE_FILES:
|
|
185
|
+
GET_DOWNLOADABLE_FILES: 'getDownloadableFiles',
|
|
186
|
+
DOWNLOAD_FILE: 'downloadFile',
|
|
187
|
+
DELETE_DOWNLOADABLE_FILES: 'deleteDownloadableFiles',
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
/**
|
package/lib/error.js
CHANGED
|
@@ -484,10 +484,7 @@ ERROR_CODE_TO_TYPE.forEach((value, key) => {
|
|
|
484
484
|
*/
|
|
485
485
|
function encodeError(err) {
|
|
486
486
|
let type = WebDriverError
|
|
487
|
-
if (
|
|
488
|
-
err instanceof WebDriverError &&
|
|
489
|
-
TYPE_TO_ERROR_CODE.has(err.constructor)
|
|
490
|
-
) {
|
|
487
|
+
if (err instanceof WebDriverError && TYPE_TO_ERROR_CODE.has(err.constructor)) {
|
|
491
488
|
type = err.constructor
|
|
492
489
|
}
|
|
493
490
|
|
|
@@ -541,11 +538,7 @@ function throwDecodedError(data) {
|
|
|
541
538
|
*/
|
|
542
539
|
function checkLegacyResponse(responseObj) {
|
|
543
540
|
// Handle the legacy Selenium error response format.
|
|
544
|
-
if (
|
|
545
|
-
isObject(responseObj) &&
|
|
546
|
-
typeof responseObj.status === 'number' &&
|
|
547
|
-
responseObj.status !== 0
|
|
548
|
-
) {
|
|
541
|
+
if (isObject(responseObj) && typeof responseObj.status === 'number' && responseObj.status !== 0) {
|
|
549
542
|
const { status, value } = responseObj
|
|
550
543
|
|
|
551
544
|
let ctor = LEGACY_ERROR_CODE_TO_TYPE.get(status) || WebDriverError
|
package/lib/http.js
CHANGED
|
@@ -36,18 +36,9 @@ const { isObject } = require('./util')
|
|
|
36
36
|
|
|
37
37
|
const log_ = logging.getLogger(`${logging.Type.DRIVER}.http`)
|
|
38
38
|
|
|
39
|
-
const getAttribute = requireAtom(
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
)
|
|
43
|
-
const isDisplayed = requireAtom(
|
|
44
|
-
'is-displayed.js',
|
|
45
|
-
'//javascript/node/selenium-webdriver/lib/atoms:is-displayed.js'
|
|
46
|
-
)
|
|
47
|
-
const findElements = requireAtom(
|
|
48
|
-
'find-elements.js',
|
|
49
|
-
'//javascript/node/selenium-webdriver/lib/atoms:find-elements.js'
|
|
50
|
-
)
|
|
39
|
+
const getAttribute = requireAtom('get-attribute.js', '//javascript/node/selenium-webdriver/lib/atoms:get-attribute.js')
|
|
40
|
+
const isDisplayed = requireAtom('is-displayed.js', '//javascript/node/selenium-webdriver/lib/atoms:is-displayed.js')
|
|
41
|
+
const findElements = requireAtom('find-elements.js', '//javascript/node/selenium-webdriver/lib/atoms:find-elements.js')
|
|
51
42
|
|
|
52
43
|
/**
|
|
53
44
|
* @param {string} module
|
|
@@ -67,7 +58,7 @@ function requireAtom(module, bazelTarget) {
|
|
|
67
58
|
throw Error(
|
|
68
59
|
`Failed to import atoms module ${module}. If running in dev mode, you` +
|
|
69
60
|
` need to run \`bazel build ${bazelTarget}\` from the project` +
|
|
70
|
-
`root: ${ex}
|
|
61
|
+
`root: ${ex}`,
|
|
71
62
|
)
|
|
72
63
|
}
|
|
73
64
|
}
|
|
@@ -102,9 +93,7 @@ class Request {
|
|
|
102
93
|
this.method = /** string */ method
|
|
103
94
|
this.path = /** string */ path
|
|
104
95
|
this.data = /** Object */ opt_data
|
|
105
|
-
this.headers = /** !Map<string, string> */ new Map([
|
|
106
|
-
['Accept', 'application/json; charset=utf-8'],
|
|
107
|
-
])
|
|
96
|
+
this.headers = /** !Map<string, string> */ new Map([['Accept', 'application/json; charset=utf-8']])
|
|
108
97
|
}
|
|
109
98
|
|
|
110
99
|
/** @override */
|
|
@@ -189,13 +178,10 @@ function toExecuteAtomCommand(command, atom, name, ...params) {
|
|
|
189
178
|
|
|
190
179
|
return new cmd.Command(cmd.Name.EXECUTE_SCRIPT)
|
|
191
180
|
.setParameter('sessionId', command.getParameter('sessionId'))
|
|
192
|
-
.setParameter(
|
|
193
|
-
'script',
|
|
194
|
-
`/* ${name} */return (${atom}).apply(null, arguments)`
|
|
195
|
-
)
|
|
181
|
+
.setParameter('script', `/* ${name} */return (${atom}).apply(null, arguments)`)
|
|
196
182
|
.setParameter(
|
|
197
183
|
'args',
|
|
198
|
-
params.map((param) => command.getParameter(param))
|
|
184
|
+
params.map((param) => command.getParameter(param)),
|
|
199
185
|
)
|
|
200
186
|
}
|
|
201
187
|
|
|
@@ -255,69 +241,31 @@ const W3C_COMMAND_MAP = new Map([
|
|
|
255
241
|
[
|
|
256
242
|
cmd.Name.FIND_ELEMENTS_RELATIVE,
|
|
257
243
|
(cmd) => {
|
|
258
|
-
return toExecuteAtomCommand(
|
|
259
|
-
cmd,
|
|
260
|
-
Atom.FIND_ELEMENTS,
|
|
261
|
-
'findElements',
|
|
262
|
-
'args'
|
|
263
|
-
)
|
|
244
|
+
return toExecuteAtomCommand(cmd, Atom.FIND_ELEMENTS, 'findElements', 'args')
|
|
264
245
|
},
|
|
265
246
|
],
|
|
266
|
-
[
|
|
267
|
-
|
|
268
|
-
post('/session/:sessionId/element/:id/element'),
|
|
269
|
-
],
|
|
270
|
-
[
|
|
271
|
-
cmd.Name.FIND_CHILD_ELEMENTS,
|
|
272
|
-
post('/session/:sessionId/element/:id/elements'),
|
|
273
|
-
],
|
|
247
|
+
[cmd.Name.FIND_CHILD_ELEMENT, post('/session/:sessionId/element/:id/element')],
|
|
248
|
+
[cmd.Name.FIND_CHILD_ELEMENTS, post('/session/:sessionId/element/:id/elements')],
|
|
274
249
|
// Element interaction.
|
|
275
250
|
[cmd.Name.GET_ELEMENT_TAG_NAME, get('/session/:sessionId/element/:id/name')],
|
|
276
|
-
[
|
|
277
|
-
cmd.Name.GET_DOM_ATTRIBUTE,
|
|
278
|
-
get('/session/:sessionId/element/:id/attribute/:name'),
|
|
279
|
-
],
|
|
251
|
+
[cmd.Name.GET_DOM_ATTRIBUTE, get('/session/:sessionId/element/:id/attribute/:name')],
|
|
280
252
|
[
|
|
281
253
|
cmd.Name.GET_ELEMENT_ATTRIBUTE,
|
|
282
254
|
(cmd) => {
|
|
283
|
-
return toExecuteAtomCommand(
|
|
284
|
-
cmd,
|
|
285
|
-
Atom.GET_ATTRIBUTE,
|
|
286
|
-
'getAttribute',
|
|
287
|
-
'id',
|
|
288
|
-
'name'
|
|
289
|
-
)
|
|
255
|
+
return toExecuteAtomCommand(cmd, Atom.GET_ATTRIBUTE, 'getAttribute', 'id', 'name')
|
|
290
256
|
},
|
|
291
257
|
],
|
|
292
|
-
[
|
|
293
|
-
|
|
294
|
-
get('/session/:sessionId/element/:id/property/:name'),
|
|
295
|
-
],
|
|
296
|
-
[
|
|
297
|
-
cmd.Name.GET_ELEMENT_VALUE_OF_CSS_PROPERTY,
|
|
298
|
-
get('/session/:sessionId/element/:id/css/:propertyName'),
|
|
299
|
-
],
|
|
258
|
+
[cmd.Name.GET_ELEMENT_PROPERTY, get('/session/:sessionId/element/:id/property/:name')],
|
|
259
|
+
[cmd.Name.GET_ELEMENT_VALUE_OF_CSS_PROPERTY, get('/session/:sessionId/element/:id/css/:propertyName')],
|
|
300
260
|
[cmd.Name.GET_ELEMENT_RECT, get('/session/:sessionId/element/:id/rect')],
|
|
301
261
|
[cmd.Name.CLEAR_ELEMENT, post('/session/:sessionId/element/:id/clear')],
|
|
302
262
|
[cmd.Name.CLICK_ELEMENT, post('/session/:sessionId/element/:id/click')],
|
|
303
|
-
[
|
|
304
|
-
cmd.Name.SEND_KEYS_TO_ELEMENT,
|
|
305
|
-
post('/session/:sessionId/element/:id/value'),
|
|
306
|
-
],
|
|
263
|
+
[cmd.Name.SEND_KEYS_TO_ELEMENT, post('/session/:sessionId/element/:id/value')],
|
|
307
264
|
[cmd.Name.GET_ELEMENT_TEXT, get('/session/:sessionId/element/:id/text')],
|
|
308
|
-
[
|
|
309
|
-
|
|
310
|
-
get('/session/:sessionId/element/:id/computedrole'),
|
|
311
|
-
],
|
|
312
|
-
[
|
|
313
|
-
cmd.Name.GET_COMPUTED_LABEL,
|
|
314
|
-
get('/session/:sessionId/element/:id/computedlabel'),
|
|
315
|
-
],
|
|
265
|
+
[cmd.Name.GET_COMPUTED_ROLE, get('/session/:sessionId/element/:id/computedrole')],
|
|
266
|
+
[cmd.Name.GET_COMPUTED_LABEL, get('/session/:sessionId/element/:id/computedlabel')],
|
|
316
267
|
[cmd.Name.IS_ELEMENT_ENABLED, get('/session/:sessionId/element/:id/enabled')],
|
|
317
|
-
[
|
|
318
|
-
cmd.Name.IS_ELEMENT_SELECTED,
|
|
319
|
-
get('/session/:sessionId/element/:id/selected'),
|
|
320
|
-
],
|
|
268
|
+
[cmd.Name.IS_ELEMENT_SELECTED, get('/session/:sessionId/element/:id/selected')],
|
|
321
269
|
|
|
322
270
|
[
|
|
323
271
|
cmd.Name.IS_ELEMENT_DISPLAYED,
|
|
@@ -341,21 +289,12 @@ const W3C_COMMAND_MAP = new Map([
|
|
|
341
289
|
|
|
342
290
|
// Screenshots.
|
|
343
291
|
[cmd.Name.SCREENSHOT, get('/session/:sessionId/screenshot')],
|
|
344
|
-
[
|
|
345
|
-
cmd.Name.TAKE_ELEMENT_SCREENSHOT,
|
|
346
|
-
get('/session/:sessionId/element/:id/screenshot'),
|
|
347
|
-
],
|
|
292
|
+
[cmd.Name.TAKE_ELEMENT_SCREENSHOT, get('/session/:sessionId/element/:id/screenshot')],
|
|
348
293
|
|
|
349
294
|
// Shadow Root
|
|
350
295
|
[cmd.Name.GET_SHADOW_ROOT, get('/session/:sessionId/element/:id/shadow')],
|
|
351
|
-
[
|
|
352
|
-
|
|
353
|
-
post('/session/:sessionId/shadow/:id/element'),
|
|
354
|
-
],
|
|
355
|
-
[
|
|
356
|
-
cmd.Name.FIND_ELEMENTS_FROM_SHADOWROOT,
|
|
357
|
-
post('/session/:sessionId/shadow/:id/elements'),
|
|
358
|
-
],
|
|
296
|
+
[cmd.Name.FIND_ELEMENT_FROM_SHADOWROOT, post('/session/:sessionId/shadow/:id/element')],
|
|
297
|
+
[cmd.Name.FIND_ELEMENTS_FROM_SHADOWROOT, post('/session/:sessionId/shadow/:id/elements')],
|
|
359
298
|
// Log extensions.
|
|
360
299
|
[cmd.Name.GET_LOG, post('/session/:sessionId/se/log')],
|
|
361
300
|
[cmd.Name.GET_AVAILABLE_LOG_TYPES, get('/session/:sessionId/se/log/types')],
|
|
@@ -364,46 +303,20 @@ const W3C_COMMAND_MAP = new Map([
|
|
|
364
303
|
[cmd.Name.UPLOAD_FILE, post('/session/:sessionId/se/file')],
|
|
365
304
|
|
|
366
305
|
// Virtual Authenticator
|
|
367
|
-
[
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
],
|
|
371
|
-
[
|
|
372
|
-
cmd.Name.REMOVE_VIRTUAL_AUTHENTICATOR,
|
|
373
|
-
del('/session/:sessionId/webauthn/authenticator/:authenticatorId'),
|
|
374
|
-
],
|
|
375
|
-
[
|
|
376
|
-
cmd.Name.ADD_CREDENTIAL,
|
|
377
|
-
post(
|
|
378
|
-
'/session/:sessionId/webauthn/authenticator/:authenticatorId/credential'
|
|
379
|
-
),
|
|
380
|
-
],
|
|
381
|
-
[
|
|
382
|
-
cmd.Name.GET_CREDENTIALS,
|
|
383
|
-
get(
|
|
384
|
-
'/session/:sessionId/webauthn/authenticator/:authenticatorId/credentials'
|
|
385
|
-
),
|
|
386
|
-
],
|
|
306
|
+
[cmd.Name.ADD_VIRTUAL_AUTHENTICATOR, post('/session/:sessionId/webauthn/authenticator')],
|
|
307
|
+
[cmd.Name.REMOVE_VIRTUAL_AUTHENTICATOR, del('/session/:sessionId/webauthn/authenticator/:authenticatorId')],
|
|
308
|
+
[cmd.Name.ADD_CREDENTIAL, post('/session/:sessionId/webauthn/authenticator/:authenticatorId/credential')],
|
|
309
|
+
[cmd.Name.GET_CREDENTIALS, get('/session/:sessionId/webauthn/authenticator/:authenticatorId/credentials')],
|
|
387
310
|
[
|
|
388
311
|
cmd.Name.REMOVE_CREDENTIAL,
|
|
389
|
-
del(
|
|
390
|
-
'/session/:sessionId/webauthn/authenticator/:authenticatorId/credentials/:credentialId'
|
|
391
|
-
),
|
|
392
|
-
],
|
|
393
|
-
[
|
|
394
|
-
cmd.Name.REMOVE_ALL_CREDENTIALS,
|
|
395
|
-
del(
|
|
396
|
-
'/session/:sessionId/webauthn/authenticator/:authenticatorId/credentials'
|
|
397
|
-
),
|
|
398
|
-
],
|
|
399
|
-
[
|
|
400
|
-
cmd.Name.SET_USER_VERIFIED,
|
|
401
|
-
post('/session/:sessionId/webauthn/authenticator/:authenticatorId/uv'),
|
|
312
|
+
del('/session/:sessionId/webauthn/authenticator/:authenticatorId/credentials/:credentialId'),
|
|
402
313
|
],
|
|
314
|
+
[cmd.Name.REMOVE_ALL_CREDENTIALS, del('/session/:sessionId/webauthn/authenticator/:authenticatorId/credentials')],
|
|
315
|
+
[cmd.Name.SET_USER_VERIFIED, post('/session/:sessionId/webauthn/authenticator/:authenticatorId/uv')],
|
|
403
316
|
|
|
404
317
|
[cmd.Name.GET_DOWNLOADABLE_FILES, get('/session/:sessionId/se/files')],
|
|
405
318
|
[cmd.Name.DOWNLOAD_FILE, post(`/session/:sessionId/se/files`)],
|
|
406
|
-
[cmd.Name.DELETE_DOWNLOADABLE_FILES, del(`/session/:sessionId/se/files`)]
|
|
319
|
+
[cmd.Name.DELETE_DOWNLOADABLE_FILES, del(`/session/:sessionId/se/files`)],
|
|
407
320
|
])
|
|
408
321
|
|
|
409
322
|
/**
|
|
@@ -446,9 +359,7 @@ function buildRequest(customCommands, command) {
|
|
|
446
359
|
} else if (spec) {
|
|
447
360
|
return toHttpRequest(spec)
|
|
448
361
|
}
|
|
449
|
-
throw new error.UnknownCommandError(
|
|
450
|
-
'Unrecognized command: ' + command.getName()
|
|
451
|
-
)
|
|
362
|
+
throw new error.UnknownCommandError('Unrecognized command: ' + command.getName())
|
|
452
363
|
|
|
453
364
|
/**
|
|
454
365
|
* @param {CommandSpec} resource
|
|
@@ -462,8 +373,7 @@ function buildRequest(customCommands, command) {
|
|
|
462
373
|
}
|
|
463
374
|
}
|
|
464
375
|
|
|
465
|
-
const CLIENTS =
|
|
466
|
-
/** !WeakMap<!Executor, !(Client|IThenable<!Client>)> */ new WeakMap()
|
|
376
|
+
const CLIENTS = /** !WeakMap<!Executor, !(Client|IThenable<!Client>)> */ new WeakMap()
|
|
467
377
|
|
|
468
378
|
/**
|
|
469
379
|
* A command executor that communicates with the server using JSON over HTTP.
|
|
@@ -534,9 +444,7 @@ class Executor {
|
|
|
534
444
|
|
|
535
445
|
if (command.getName() === cmd.Name.NEW_SESSION) {
|
|
536
446
|
if (!value || !value.sessionId) {
|
|
537
|
-
throw new error.WebDriverError(
|
|
538
|
-
`Unable to parse new session response: ${response.body}`
|
|
539
|
-
)
|
|
447
|
+
throw new error.WebDriverError(`Unable to parse new session response: ${response.body}`)
|
|
540
448
|
}
|
|
541
449
|
|
|
542
450
|
// The remote end is a W3C compliant server if there is no `status`
|
|
@@ -547,10 +455,7 @@ class Executor {
|
|
|
547
455
|
|
|
548
456
|
// No implementations use the `capabilities` key yet...
|
|
549
457
|
let capabilities = value.capabilities || value.value
|
|
550
|
-
return new Session(
|
|
551
|
-
/** @type {{sessionId: string}} */ (value).sessionId,
|
|
552
|
-
capabilities
|
|
553
|
-
)
|
|
458
|
+
return new Session(/** @type {{sessionId: string}} */ (value).sessionId, capabilities)
|
|
554
459
|
}
|
|
555
460
|
|
|
556
461
|
return typeof value === 'undefined' ? null : value
|
|
@@ -649,9 +554,7 @@ function buildPath(path, parameters) {
|
|
|
649
554
|
path = path.replace(pathParameters[i], '/' + value)
|
|
650
555
|
delete parameters[key]
|
|
651
556
|
} else {
|
|
652
|
-
throw new error.InvalidArgumentError(
|
|
653
|
-
'Missing required parameter: ' + key
|
|
654
|
-
)
|
|
557
|
+
throw new error.InvalidArgumentError('Missing required parameter: ' + key)
|
|
655
558
|
}
|
|
656
559
|
}
|
|
657
560
|
}
|
package/lib/input.js
CHANGED
|
@@ -256,9 +256,7 @@ function checkCodePoint(key) {
|
|
|
256
256
|
|
|
257
257
|
key = key.normalize()
|
|
258
258
|
if (Array.from(key).length !== 1) {
|
|
259
|
-
throw new InvalidArgumentError(
|
|
260
|
-
`key input is not a single code point: ${key}`
|
|
261
|
-
)
|
|
259
|
+
throw new InvalidArgumentError(`key input is not a single code point: ${key}`)
|
|
262
260
|
}
|
|
263
261
|
return key
|
|
264
262
|
}
|
|
@@ -333,10 +331,7 @@ class Pointer extends Device {
|
|
|
333
331
|
|
|
334
332
|
/** @override */
|
|
335
333
|
toJSON() {
|
|
336
|
-
return Object.assign(
|
|
337
|
-
{ parameters: { pointerType: this.pointerType_ } },
|
|
338
|
-
super.toJSON()
|
|
339
|
-
)
|
|
334
|
+
return Object.assign({ parameters: { pointerType: this.pointerType_ } }, super.toJSON())
|
|
340
335
|
}
|
|
341
336
|
|
|
342
337
|
/**
|
|
@@ -371,7 +366,7 @@ class Pointer extends Device {
|
|
|
371
366
|
tiltY = 0,
|
|
372
367
|
twist = 0,
|
|
373
368
|
altitudeAngle = 0,
|
|
374
|
-
azimuthAngle = 0
|
|
369
|
+
azimuthAngle = 0,
|
|
375
370
|
) {
|
|
376
371
|
return {
|
|
377
372
|
type: Action.Type.POINTER_DOWN,
|
|
@@ -814,10 +809,7 @@ class Actions {
|
|
|
814
809
|
for (const key of keys) {
|
|
815
810
|
if (typeof key === 'string') {
|
|
816
811
|
for (const symbol of key) {
|
|
817
|
-
actions.push(
|
|
818
|
-
this.keyboard_.keyDown(symbol),
|
|
819
|
-
this.keyboard_.keyUp(symbol)
|
|
820
|
-
)
|
|
812
|
+
actions.push(this.keyboard_.keyDown(symbol), this.keyboard_.keyUp(symbol))
|
|
821
813
|
}
|
|
822
814
|
} else {
|
|
823
815
|
actions.push(this.keyboard_.keyDown(key), this.keyboard_.keyUp(key))
|
|
@@ -857,10 +849,7 @@ class Actions {
|
|
|
857
849
|
* @returns {!Actions} An action to scroll with this device.
|
|
858
850
|
*/
|
|
859
851
|
scroll(x, y, targetDeltaX, targetDeltaY, origin, duration) {
|
|
860
|
-
return this.insert(
|
|
861
|
-
this.wheel_,
|
|
862
|
-
this.wheel_.scroll(x, y, targetDeltaX, targetDeltaY, origin, duration)
|
|
863
|
-
)
|
|
852
|
+
return this.insert(this.wheel_, this.wheel_.scroll(x, y, targetDeltaX, targetDeltaY, origin, duration))
|
|
864
853
|
}
|
|
865
854
|
|
|
866
855
|
/**
|
|
@@ -885,10 +874,7 @@ class Actions {
|
|
|
885
874
|
* @return {!Actions} a self reference.
|
|
886
875
|
*/
|
|
887
876
|
move({ x = 0, y = 0, duration = 100, origin = Origin.VIEWPORT } = {}) {
|
|
888
|
-
return this.insert(
|
|
889
|
-
this.mouse_,
|
|
890
|
-
this.mouse_.move({ x, y, duration, origin })
|
|
891
|
-
)
|
|
877
|
+
return this.insert(this.mouse_, this.mouse_.move({ x, y, duration, origin }))
|
|
892
878
|
}
|
|
893
879
|
|
|
894
880
|
/**
|
|
@@ -953,13 +939,8 @@ class Actions {
|
|
|
953
939
|
dragAndDrop(from, to) {
|
|
954
940
|
// Do not require up top to avoid a cycle that breaks static analysis.
|
|
955
941
|
const { WebElement } = require('./webdriver')
|
|
956
|
-
if (
|
|
957
|
-
|
|
958
|
-
(!to || typeof to.x !== 'number' || typeof to.y !== 'number')
|
|
959
|
-
) {
|
|
960
|
-
throw new InvalidArgumentError(
|
|
961
|
-
'Invalid drag target; must specify a WebElement or {x, y} offset'
|
|
962
|
-
)
|
|
942
|
+
if (!(to instanceof WebElement) && (!to || typeof to.x !== 'number' || typeof to.y !== 'number')) {
|
|
943
|
+
throw new InvalidArgumentError('Invalid drag target; must specify a WebElement or {x, y} offset')
|
|
963
944
|
}
|
|
964
945
|
|
|
965
946
|
this.move({ origin: from }).press()
|
|
@@ -1003,9 +984,7 @@ class Actions {
|
|
|
1003
984
|
return Promise.resolve()
|
|
1004
985
|
}
|
|
1005
986
|
|
|
1006
|
-
await this.executor_.execute(
|
|
1007
|
-
new Command(Name.ACTIONS).setParameter('actions', _actions)
|
|
1008
|
-
)
|
|
987
|
+
await this.executor_.execute(new Command(Name.ACTIONS).setParameter('actions', _actions))
|
|
1009
988
|
}
|
|
1010
989
|
|
|
1011
990
|
getSequences() {
|
|
@@ -1026,10 +1005,7 @@ class Actions {
|
|
|
1026
1005
|
* @return {boolean}
|
|
1027
1006
|
*/
|
|
1028
1007
|
function isIdle(actions) {
|
|
1029
|
-
return (
|
|
1030
|
-
actions.length === 0 ||
|
|
1031
|
-
actions.every((a) => a.type === Action.Type.PAUSE && !a.duration)
|
|
1032
|
-
)
|
|
1008
|
+
return actions.length === 0 || actions.every((a) => a.type === Action.Type.PAUSE && !a.duration)
|
|
1033
1009
|
}
|
|
1034
1010
|
|
|
1035
1011
|
/**
|
package/lib/logging.js
CHANGED
|
@@ -220,8 +220,7 @@ class Entry {
|
|
|
220
220
|
constructor(level, message, opt_timestamp, opt_type) {
|
|
221
221
|
this.level = level instanceof Level ? level : getLevel(level)
|
|
222
222
|
this.message = message
|
|
223
|
-
this.timestamp =
|
|
224
|
-
typeof opt_timestamp === 'number' ? opt_timestamp : Date.now()
|
|
223
|
+
this.timestamp = typeof opt_timestamp === 'number' ? opt_timestamp : Date.now()
|
|
225
224
|
this.type = opt_type || ''
|
|
226
225
|
}
|
|
227
226
|
|
|
@@ -311,10 +310,7 @@ class Logger {
|
|
|
311
310
|
* by this instance.
|
|
312
311
|
*/
|
|
313
312
|
isLoggable(level) {
|
|
314
|
-
return (
|
|
315
|
-
level.value !== Level.OFF.value &&
|
|
316
|
-
level.value >= this.getEffectiveLevel().value
|
|
317
|
-
)
|
|
313
|
+
return level.value !== Level.OFF.value && level.value >= this.getEffectiveLevel().value
|
|
318
314
|
}
|
|
319
315
|
|
|
320
316
|
/**
|
|
@@ -358,11 +354,7 @@ class Logger {
|
|
|
358
354
|
if (!this.isLoggable(level)) {
|
|
359
355
|
return
|
|
360
356
|
}
|
|
361
|
-
let message =
|
|
362
|
-
'[' +
|
|
363
|
-
this.name_ +
|
|
364
|
-
'] ' +
|
|
365
|
-
(typeof loggable === 'function' ? loggable() : loggable)
|
|
357
|
+
let message = '[' + this.name_ + '] ' + (typeof loggable === 'function' ? loggable() : loggable)
|
|
366
358
|
let entry = new Entry(level, message, Date.now())
|
|
367
359
|
for (let logger = this; logger; logger = logger.parent_) {
|
|
368
360
|
if (logger.handlers_) {
|
package/lib/promise.js
CHANGED
|
@@ -173,9 +173,7 @@ async function filter(array, fn, self = undefined) {
|
|
|
173
173
|
const values = []
|
|
174
174
|
|
|
175
175
|
for (const [index, item] of arr.entries()) {
|
|
176
|
-
const isConditionTrue = await Promise.resolve(
|
|
177
|
-
fn.call(self, item, index, arr)
|
|
178
|
-
)
|
|
176
|
+
const isConditionTrue = await Promise.resolve(fn.call(self, item, index, arr))
|
|
179
177
|
if (isConditionTrue) {
|
|
180
178
|
values.push(item)
|
|
181
179
|
}
|
|
@@ -247,10 +245,7 @@ async function fullyResolveKeys(obj) {
|
|
|
247
245
|
|
|
248
246
|
const forEachKey = isArray ? forEachElement : forEachProperty
|
|
249
247
|
await forEachKey(obj, async function (partialValue, key) {
|
|
250
|
-
if (
|
|
251
|
-
!Array.isArray(partialValue) &&
|
|
252
|
-
(!partialValue || typeof partialValue !== 'object')
|
|
253
|
-
) {
|
|
248
|
+
if (!Array.isArray(partialValue) && (!partialValue || typeof partialValue !== 'object')) {
|
|
254
249
|
return
|
|
255
250
|
}
|
|
256
251
|
obj[key] = await fullyResolved(partialValue)
|
package/lib/select.js
CHANGED
|
@@ -184,9 +184,7 @@ class Select {
|
|
|
184
184
|
|
|
185
185
|
if (options.length - 1 < index) {
|
|
186
186
|
throw new Error(
|
|
187
|
-
`Option with index "${index}" not found. Select element only contains ${
|
|
188
|
-
options.length - 1
|
|
189
|
-
} option elements`
|
|
187
|
+
`Option with index "${index}" not found. Select element only contains ${options.length - 1} option elements`,
|
|
190
188
|
)
|
|
191
189
|
}
|
|
192
190
|
|
|
@@ -408,9 +406,7 @@ class Select {
|
|
|
408
406
|
|
|
409
407
|
if (options.length - 1 < index) {
|
|
410
408
|
throw new Error(
|
|
411
|
-
`Option with index "${index}" not found. Select element only contains ${
|
|
412
|
-
options.length - 1
|
|
413
|
-
} option elements`
|
|
409
|
+
`Option with index "${index}" not found. Select element only contains ${options.length - 1} option elements`,
|
|
414
410
|
)
|
|
415
411
|
}
|
|
416
412
|
|
|
@@ -454,9 +450,7 @@ class Select {
|
|
|
454
450
|
async setSelected(option) {
|
|
455
451
|
if (!(await option.isSelected())) {
|
|
456
452
|
if (!(await option.isEnabled())) {
|
|
457
|
-
throw new error.UnsupportedOperationError(
|
|
458
|
-
`You may not select a disabled option`
|
|
459
|
-
)
|
|
453
|
+
throw new error.UnsupportedOperationError(`You may not select a disabled option`)
|
|
460
454
|
}
|
|
461
455
|
await option.click()
|
|
462
456
|
}
|