selenium-webdriver 4.0.0-alpha.8 → 4.0.0-beta.4
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 +41 -1
- package/LICENSE +202 -0
- package/NOTICE +2 -0
- package/README.md +0 -0
- package/chrome.js +0 -0
- package/chromium.js +23 -202
- package/devtools/CDPConnection.js +16 -18
- package/edge.js +89 -130
- package/example/chrome_android.js +45 -0
- package/{lib/atoms/make-atoms-module.js → example/chrome_mobile_emulation.js} +26 -15
- package/example/firefox_channels.js +84 -0
- package/example/google_search.js +50 -0
- package/example/google_search_test.js +70 -0
- package/example/headless.js +63 -0
- package/example/logging.js +64 -0
- package/firefox.js +10 -9
- package/http/index.js +0 -0
- package/http/util.js +3 -3
- package/ie.js +0 -0
- package/index.js +2 -2
- package/io/exec.js +3 -3
- package/io/index.js +12 -13
- package/io/zip.js +5 -6
- package/lib/atoms/find-elements.js +78 -78
- package/lib/atoms/get-attribute.js +64 -68
- package/lib/atoms/is-displayed.js +27 -27
- package/lib/atoms/mutation-listener.js +55 -0
- package/lib/by.js +1 -1
- package/lib/capabilities.js +2 -3
- package/lib/command.js +2 -15
- package/lib/error.js +0 -0
- package/lib/http.js +17 -30
- package/lib/input.js +2 -286
- package/lib/logging.js +0 -0
- package/lib/promise.js +4 -16
- package/lib/proxy.js +0 -0
- package/lib/session.js +0 -0
- package/lib/symbols.js +0 -0
- package/lib/until.js +17 -15
- package/lib/webdriver.js +336 -16
- package/net/index.js +0 -0
- package/net/portprober.js +8 -8
- package/opera.js +0 -0
- package/package.json +13 -13
- package/proxy.js +0 -0
- package/remote/index.js +6 -7
- package/safari.js +0 -0
- package/testing/index.js +504 -0
- package/.eslintrc.js +0 -27
- package/.prettierrc +0 -4
- package/devtools/generator/protocol-dts-generator.js +0 -429
- package/lib/README +0 -5
- package/lib/actions.js +0 -626
package/lib/webdriver.js
CHANGED
|
@@ -29,7 +29,14 @@ const input = require('./input')
|
|
|
29
29
|
const logging = require('./logging')
|
|
30
30
|
const promise = require('./promise')
|
|
31
31
|
const Symbols = require('./symbols')
|
|
32
|
+
const cdpTargets = ['page', 'browser']
|
|
33
|
+
const cdp = require('../devtools/CDPConnection')
|
|
34
|
+
const WebSocket = require('ws')
|
|
35
|
+
const http = require('../http/index')
|
|
36
|
+
const fs = require('fs')
|
|
32
37
|
const { Capabilities } = require('./capabilities')
|
|
38
|
+
const path = require('path')
|
|
39
|
+
const { NoSuchElementError } = require('./error')
|
|
33
40
|
|
|
34
41
|
// Capability names that are defined in the W3C spec.
|
|
35
42
|
const W3C_CAPABILITY_NAMES = new Set([
|
|
@@ -239,14 +246,14 @@ class IWebDriver {
|
|
|
239
246
|
* result.
|
|
240
247
|
* @template T
|
|
241
248
|
*/
|
|
242
|
-
execute(command) {} // eslint-disable-line
|
|
249
|
+
execute(command) { } // eslint-disable-line
|
|
243
250
|
|
|
244
251
|
/**
|
|
245
252
|
* Sets the {@linkplain input.FileDetector file detector} that should be
|
|
246
253
|
* used with this instance.
|
|
247
254
|
* @param {input.FileDetector} detector The detector to use or `null`.
|
|
248
255
|
*/
|
|
249
|
-
setFileDetector(detector) {} // eslint-disable-line
|
|
256
|
+
setFileDetector(detector) { } // eslint-disable-line
|
|
250
257
|
|
|
251
258
|
/**
|
|
252
259
|
* @return {!command.Executor} The command executor used by this instance.
|
|
@@ -285,7 +292,7 @@ class IWebDriver {
|
|
|
285
292
|
* for details).
|
|
286
293
|
* @return {!input.Actions} A new action sequence for this instance.
|
|
287
294
|
*/
|
|
288
|
-
actions(options) {} // eslint-disable-line
|
|
295
|
+
actions(options) { } // eslint-disable-line
|
|
289
296
|
|
|
290
297
|
/**
|
|
291
298
|
* Executes a snippet of JavaScript in the context of the currently selected
|
|
@@ -323,7 +330,7 @@ class IWebDriver {
|
|
|
323
330
|
* scripts return value.
|
|
324
331
|
* @template T
|
|
325
332
|
*/
|
|
326
|
-
executeScript(script, ...args) {} // eslint-disable-line
|
|
333
|
+
executeScript(script, ...args) { } // eslint-disable-line
|
|
327
334
|
|
|
328
335
|
/**
|
|
329
336
|
* Executes a snippet of asynchronous JavaScript in the context of the
|
|
@@ -400,7 +407,7 @@ class IWebDriver {
|
|
|
400
407
|
* value.
|
|
401
408
|
* @template T
|
|
402
409
|
*/
|
|
403
|
-
executeAsyncScript(script, ...args) {} // eslint-disable-line
|
|
410
|
+
executeAsyncScript(script, ...args) { } // eslint-disable-line
|
|
404
411
|
|
|
405
412
|
/**
|
|
406
413
|
* Waits for a condition to evaluate to a "truthy" value. The condition may be
|
|
@@ -460,7 +467,7 @@ class IWebDriver {
|
|
|
460
467
|
* @return {!Promise<void>} A promise that will be resolved when the sleep has
|
|
461
468
|
* finished.
|
|
462
469
|
*/
|
|
463
|
-
sleep(ms) {} // eslint-disable-line
|
|
470
|
+
sleep(ms) { } // eslint-disable-line
|
|
464
471
|
|
|
465
472
|
/**
|
|
466
473
|
* Retrieves the current window handle.
|
|
@@ -503,7 +510,7 @@ class IWebDriver {
|
|
|
503
510
|
* @return {!Promise<void>} A promise that will be resolved when the document
|
|
504
511
|
* has finished loading.
|
|
505
512
|
*/
|
|
506
|
-
get(url) {} // eslint-disable-line
|
|
513
|
+
get(url) { } // eslint-disable-line
|
|
507
514
|
|
|
508
515
|
/**
|
|
509
516
|
* Retrieves the URL for the current page.
|
|
@@ -559,7 +566,7 @@ class IWebDriver {
|
|
|
559
566
|
* commands against the located element. If the element is not found, the
|
|
560
567
|
* element will be invalidated and all scheduled commands aborted.
|
|
561
568
|
*/
|
|
562
|
-
findElement(locator) {} // eslint-disable-line
|
|
569
|
+
findElement(locator) { } // eslint-disable-line
|
|
563
570
|
|
|
564
571
|
/**
|
|
565
572
|
* Search for multiple elements on the page. Refer to the documentation on
|
|
@@ -569,7 +576,7 @@ class IWebDriver {
|
|
|
569
576
|
* @return {!Promise<!Array<!WebElement>>} A promise that will resolve to an
|
|
570
577
|
* array of WebElements.
|
|
571
578
|
*/
|
|
572
|
-
findElements(locator) {} // eslint-disable-line
|
|
579
|
+
findElements(locator) { } // eslint-disable-line
|
|
573
580
|
|
|
574
581
|
/**
|
|
575
582
|
* Takes a screenshot of the current page. The driver makes a best effort to
|
|
@@ -618,7 +625,7 @@ class IWebDriver {
|
|
|
618
625
|
* shrinkToFit: (boolean|undefined)
|
|
619
626
|
* pageRanges: (<Array>|undefined)}} options.
|
|
620
627
|
*/
|
|
621
|
-
printPage(options) {} // eslint-disable-line
|
|
628
|
+
printPage(options) { } // eslint-disable-line
|
|
622
629
|
}
|
|
623
630
|
|
|
624
631
|
/**
|
|
@@ -925,7 +932,7 @@ class WebDriver {
|
|
|
925
932
|
|
|
926
933
|
/** @override */
|
|
927
934
|
sleep(ms) {
|
|
928
|
-
return new Promise((resolve) => setTimeout(
|
|
935
|
+
return new Promise((resolve) => setTimeout(resolve, ms))
|
|
929
936
|
}
|
|
930
937
|
|
|
931
938
|
/** @override */
|
|
@@ -968,16 +975,46 @@ class WebDriver {
|
|
|
968
975
|
/** @override */
|
|
969
976
|
findElement(locator) {
|
|
970
977
|
let id
|
|
971
|
-
|
|
978
|
+
let cmd = null
|
|
979
|
+
|
|
980
|
+
if (locator instanceof RelativeBy) {
|
|
981
|
+
cmd = new command.Command(
|
|
982
|
+
command.Name.FIND_ELEMENTS_RELATIVE
|
|
983
|
+
).setParameter('args', locator.marshall())
|
|
984
|
+
} else {
|
|
985
|
+
locator = by.checkedLocator(locator)
|
|
986
|
+
}
|
|
987
|
+
|
|
972
988
|
if (typeof locator === 'function') {
|
|
973
989
|
id = this.findElementInternal_(locator, this)
|
|
974
|
-
|
|
975
|
-
|
|
990
|
+
return new WebElementPromise(this, id)
|
|
991
|
+
} else if (cmd === null) {
|
|
992
|
+
cmd = new command.Command(command.Name.FIND_ELEMENT)
|
|
976
993
|
.setParameter('using', locator.using)
|
|
977
994
|
.setParameter('value', locator.value)
|
|
978
|
-
id = this.execute(cmd)
|
|
979
995
|
}
|
|
980
|
-
|
|
996
|
+
|
|
997
|
+
id = this.execute(cmd)
|
|
998
|
+
if (locator instanceof RelativeBy) {
|
|
999
|
+
return this.normalize_(id)
|
|
1000
|
+
} else {
|
|
1001
|
+
return new WebElementPromise(this, id)
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
/**
|
|
1006
|
+
* @param {!Function} webElementPromise The webElement in unresolved state
|
|
1007
|
+
* @return {!Promise<!WebElement>} First single WebElement from array of resolved promises
|
|
1008
|
+
*/
|
|
1009
|
+
async normalize_(webElementPromise) {
|
|
1010
|
+
let result = await webElementPromise
|
|
1011
|
+
if (result.length === 0) {
|
|
1012
|
+
throw new NoSuchElementError(
|
|
1013
|
+
'Cannot locate an element with provided parameters'
|
|
1014
|
+
)
|
|
1015
|
+
} else {
|
|
1016
|
+
return result[0]
|
|
1017
|
+
}
|
|
981
1018
|
}
|
|
982
1019
|
|
|
983
1020
|
/**
|
|
@@ -1150,6 +1187,270 @@ class WebDriver {
|
|
|
1150
1187
|
new command.Command(command.Name.PRINT_PAGE).setParameters(resultObj)
|
|
1151
1188
|
)
|
|
1152
1189
|
}
|
|
1190
|
+
|
|
1191
|
+
/**
|
|
1192
|
+
* Creates a new WebSocket connection.
|
|
1193
|
+
* @return {!Promise<resolved>} A new CDP instance.
|
|
1194
|
+
*/
|
|
1195
|
+
async createCDPConnection(target) {
|
|
1196
|
+
const caps = await this.getCapabilities()
|
|
1197
|
+
const seCdp = caps['map_'].get('se:cdp')
|
|
1198
|
+
const vendorInfo =
|
|
1199
|
+
caps['map_'].get(this.VENDOR_COMMAND_PREFIX + ':chromeOptions') ||
|
|
1200
|
+
caps['map_'].get(this.VENDOR_CAPABILITY_PREFIX + ':edgeOptions') ||
|
|
1201
|
+
caps['map_'].get('moz:debuggerAddress') ||
|
|
1202
|
+
new Map()
|
|
1203
|
+
const debuggerUrl = seCdp || vendorInfo['debuggerAddress'] || vendorInfo
|
|
1204
|
+
this._wsUrl = await this.getWsUrl(debuggerUrl, target)
|
|
1205
|
+
|
|
1206
|
+
return new Promise((resolve, reject) => {
|
|
1207
|
+
try {
|
|
1208
|
+
this._wsConnection = new WebSocket(this._wsUrl)
|
|
1209
|
+
} catch (err) {
|
|
1210
|
+
reject(err)
|
|
1211
|
+
return
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
this._wsConnection.on('open', () => {
|
|
1215
|
+
this._cdpConnection = new cdp.CdpConnection(this._wsConnection)
|
|
1216
|
+
resolve(this._cdpConnection)
|
|
1217
|
+
})
|
|
1218
|
+
|
|
1219
|
+
this._wsConnection.on('error', (error) => {
|
|
1220
|
+
reject(error)
|
|
1221
|
+
})
|
|
1222
|
+
})
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
/**
|
|
1226
|
+
* Retrieves 'webSocketDebuggerUrl' by sending a http request using debugger address
|
|
1227
|
+
* @param {string} debuggerAddress
|
|
1228
|
+
* @param {string} target
|
|
1229
|
+
* @return {string} Returns parsed webSocketDebuggerUrl obtained from the http request
|
|
1230
|
+
*/
|
|
1231
|
+
async getWsUrl(debuggerAddress, target) {
|
|
1232
|
+
if (target && cdpTargets.indexOf(target.toLowerCase()) === -1) {
|
|
1233
|
+
throw new error.InvalidArgumentError('invalid target value')
|
|
1234
|
+
}
|
|
1235
|
+
let path
|
|
1236
|
+
if (target === 'page') {
|
|
1237
|
+
path = '/json'
|
|
1238
|
+
} else {
|
|
1239
|
+
path = '/json/version'
|
|
1240
|
+
}
|
|
1241
|
+
let request = new http.Request('GET', path)
|
|
1242
|
+
let client = new http.HttpClient('http://' + debuggerAddress)
|
|
1243
|
+
let response = await client.send(request)
|
|
1244
|
+
let url
|
|
1245
|
+
if (target.toLowerCase() === 'page') {
|
|
1246
|
+
url = JSON.parse(response.body)[0]['webSocketDebuggerUrl']
|
|
1247
|
+
} else {
|
|
1248
|
+
url = JSON.parse(response.body)['webSocketDebuggerUrl']
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
return url
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
/**
|
|
1255
|
+
* Sets a listener for Fetch.authRequired event from CDP
|
|
1256
|
+
* If event is triggered, it enter username and password
|
|
1257
|
+
* and allows the test to move forward
|
|
1258
|
+
* @param {string} username
|
|
1259
|
+
* @param {string} password
|
|
1260
|
+
* @param connection CDP Connection
|
|
1261
|
+
*/
|
|
1262
|
+
async register(username, password, connection) {
|
|
1263
|
+
await connection.execute(
|
|
1264
|
+
'Network.setCacheDisabled',
|
|
1265
|
+
this.getRandomNumber(1, 10),
|
|
1266
|
+
{
|
|
1267
|
+
cacheDisabled: true,
|
|
1268
|
+
},
|
|
1269
|
+
null
|
|
1270
|
+
)
|
|
1271
|
+
|
|
1272
|
+
this._wsConnection.on('message', (message) => {
|
|
1273
|
+
const params = JSON.parse(message)
|
|
1274
|
+
|
|
1275
|
+
if (params.method === 'Fetch.authRequired') {
|
|
1276
|
+
const requestParams = params['params']
|
|
1277
|
+
connection.execute(
|
|
1278
|
+
'Fetch.continueWithAuth',
|
|
1279
|
+
this.getRandomNumber(1, 10),
|
|
1280
|
+
{
|
|
1281
|
+
requestId: requestParams['requestId'],
|
|
1282
|
+
authChallengeResponse: {
|
|
1283
|
+
response: 'ProvideCredentials',
|
|
1284
|
+
username: username,
|
|
1285
|
+
password: password,
|
|
1286
|
+
},
|
|
1287
|
+
}
|
|
1288
|
+
)
|
|
1289
|
+
} else if (params.method === 'Fetch.requestPaused') {
|
|
1290
|
+
const requestPausedParams = params['params']
|
|
1291
|
+
connection.execute(
|
|
1292
|
+
'Fetch.continueRequest',
|
|
1293
|
+
this.getRandomNumber(1, 10),
|
|
1294
|
+
{
|
|
1295
|
+
requestId: requestPausedParams['requestId'],
|
|
1296
|
+
}
|
|
1297
|
+
)
|
|
1298
|
+
}
|
|
1299
|
+
})
|
|
1300
|
+
|
|
1301
|
+
await connection.execute(
|
|
1302
|
+
'Fetch.enable',
|
|
1303
|
+
1,
|
|
1304
|
+
{
|
|
1305
|
+
handleAuthRequests: true,
|
|
1306
|
+
},
|
|
1307
|
+
null
|
|
1308
|
+
)
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
/**
|
|
1312
|
+
*
|
|
1313
|
+
* @param connection
|
|
1314
|
+
* @param callback
|
|
1315
|
+
* @returns {Promise<void>}
|
|
1316
|
+
*/
|
|
1317
|
+
async onLogEvent(connection, callback) {
|
|
1318
|
+
await connection.execute(
|
|
1319
|
+
'Runtime.enable',
|
|
1320
|
+
this.getRandomNumber(1, 10),
|
|
1321
|
+
{},
|
|
1322
|
+
null
|
|
1323
|
+
)
|
|
1324
|
+
|
|
1325
|
+
this._wsConnection.on('message', (message) => {
|
|
1326
|
+
const params = JSON.parse(message)
|
|
1327
|
+
|
|
1328
|
+
if (params.method === 'Runtime.consoleAPICalled') {
|
|
1329
|
+
const consoleEventParams = params['params']
|
|
1330
|
+
let event = {
|
|
1331
|
+
type: consoleEventParams['type'],
|
|
1332
|
+
timestamp: new Date(consoleEventParams['timestamp']),
|
|
1333
|
+
args: consoleEventParams['args'],
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1336
|
+
callback(event)
|
|
1337
|
+
}
|
|
1338
|
+
})
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1341
|
+
/**
|
|
1342
|
+
*
|
|
1343
|
+
* @param connection
|
|
1344
|
+
* @param callback
|
|
1345
|
+
* @returns {Promise<void>}
|
|
1346
|
+
*/
|
|
1347
|
+
async onLogException(connection, callback) {
|
|
1348
|
+
await connection.execute(
|
|
1349
|
+
'Runtime.enable',
|
|
1350
|
+
this.getRandomNumber(1, 10),
|
|
1351
|
+
{},
|
|
1352
|
+
null
|
|
1353
|
+
)
|
|
1354
|
+
|
|
1355
|
+
this._wsConnection.on('message', (message) => {
|
|
1356
|
+
const params = JSON.parse(message)
|
|
1357
|
+
|
|
1358
|
+
if (params.method === 'Runtime.exceptionThrown') {
|
|
1359
|
+
const exceptionEventParams = params['params']
|
|
1360
|
+
let event = {
|
|
1361
|
+
exceptionDetails: exceptionEventParams['exceptionDetails'],
|
|
1362
|
+
timestamp: new Date(exceptionEventParams['timestamp']),
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1365
|
+
callback(event)
|
|
1366
|
+
}
|
|
1367
|
+
})
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1370
|
+
/**
|
|
1371
|
+
* @param connection
|
|
1372
|
+
* @param callback
|
|
1373
|
+
* @returns {Promise<void>}
|
|
1374
|
+
*/
|
|
1375
|
+
async logMutationEvents(connection, callback) {
|
|
1376
|
+
await connection.execute(
|
|
1377
|
+
'Runtime.enable',
|
|
1378
|
+
this.getRandomNumber(1, 10),
|
|
1379
|
+
{},
|
|
1380
|
+
null
|
|
1381
|
+
)
|
|
1382
|
+
await connection.execute(
|
|
1383
|
+
'Page.enable',
|
|
1384
|
+
this.getRandomNumber(1, 10),
|
|
1385
|
+
{},
|
|
1386
|
+
null
|
|
1387
|
+
)
|
|
1388
|
+
|
|
1389
|
+
await connection.execute(
|
|
1390
|
+
'Runtime.addBinding',
|
|
1391
|
+
this.getRandomNumber(1, 10),
|
|
1392
|
+
{
|
|
1393
|
+
name: '__webdriver_attribute',
|
|
1394
|
+
},
|
|
1395
|
+
null
|
|
1396
|
+
)
|
|
1397
|
+
|
|
1398
|
+
let mutationListener = ''
|
|
1399
|
+
try {
|
|
1400
|
+
// Depending on what is running the code it could appear in 2 different places which is why we try
|
|
1401
|
+
// here and then the other location
|
|
1402
|
+
mutationListener = fs
|
|
1403
|
+
.readFileSync(
|
|
1404
|
+
'./javascript/node/selenium-webdriver/lib/atoms/mutation-listener.js',
|
|
1405
|
+
'utf-8'
|
|
1406
|
+
)
|
|
1407
|
+
.toString()
|
|
1408
|
+
} catch {
|
|
1409
|
+
mutationListener = fs
|
|
1410
|
+
.readFileSync(
|
|
1411
|
+
path.resolve(__dirname, './atoms/mutation-listener.js'),
|
|
1412
|
+
'utf-8'
|
|
1413
|
+
)
|
|
1414
|
+
.toString()
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1417
|
+
this.executeScript(mutationListener)
|
|
1418
|
+
|
|
1419
|
+
await connection.execute(
|
|
1420
|
+
'Page.addScriptToEvaluateOnNewDocument',
|
|
1421
|
+
this.getRandomNumber(1, 10),
|
|
1422
|
+
{
|
|
1423
|
+
source: mutationListener,
|
|
1424
|
+
},
|
|
1425
|
+
null
|
|
1426
|
+
)
|
|
1427
|
+
|
|
1428
|
+
this._wsConnection.on('message', async (message) => {
|
|
1429
|
+
const params = JSON.parse(message)
|
|
1430
|
+
if (params.method === 'Runtime.bindingCalled') {
|
|
1431
|
+
let payload = JSON.parse(params['params']['payload'])
|
|
1432
|
+
let elements = await this.findElements({
|
|
1433
|
+
css: '*[data-__webdriver_id=' + payload['target'],
|
|
1434
|
+
})
|
|
1435
|
+
|
|
1436
|
+
if (elements.length === 0) {
|
|
1437
|
+
return
|
|
1438
|
+
}
|
|
1439
|
+
|
|
1440
|
+
let event = {
|
|
1441
|
+
element: elements[0],
|
|
1442
|
+
attribute_name: payload['name'],
|
|
1443
|
+
current_value: payload['value'],
|
|
1444
|
+
old_value: payload['oldValue'],
|
|
1445
|
+
}
|
|
1446
|
+
callback(event)
|
|
1447
|
+
}
|
|
1448
|
+
})
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
getRandomNumber(min, max) {
|
|
1452
|
+
return Math.floor(Math.random() * (max - min + 1) + min)
|
|
1453
|
+
}
|
|
1153
1454
|
}
|
|
1154
1455
|
|
|
1155
1456
|
/**
|
|
@@ -2324,6 +2625,25 @@ class WebElement {
|
|
|
2324
2625
|
return this.execute_(new command.Command(command.Name.GET_ELEMENT_TEXT))
|
|
2325
2626
|
}
|
|
2326
2627
|
|
|
2628
|
+
/**
|
|
2629
|
+
* Get the computed WAI-ARIA role of element.
|
|
2630
|
+
*
|
|
2631
|
+
* @return {!Promise<string>} A promise that will be
|
|
2632
|
+
* resolved with the element's computed role.
|
|
2633
|
+
*/
|
|
2634
|
+
getAriaRole() {
|
|
2635
|
+
return this.execute_(new command.Command(command.Name.GET_COMPUTED_ROLE))
|
|
2636
|
+
}
|
|
2637
|
+
|
|
2638
|
+
/**
|
|
2639
|
+
* Get the computed WAI-ARIA label of element.
|
|
2640
|
+
*
|
|
2641
|
+
* @return {!Promise<string>} A promise that will be
|
|
2642
|
+
* resolved with the element's computed label.
|
|
2643
|
+
*/
|
|
2644
|
+
getAccessibleName() {
|
|
2645
|
+
return this.execute_(new command.Command(command.Name.GET_COMPUTED_LABEL))
|
|
2646
|
+
}
|
|
2327
2647
|
/**
|
|
2328
2648
|
* Returns an object describing an element's location, in pixels relative to
|
|
2329
2649
|
* the document element, and the element's size in pixels.
|
package/net/index.js
CHANGED
|
File without changes
|
package/net/portprober.js
CHANGED
|
@@ -52,21 +52,21 @@ function isFree(port, opt_host) {
|
|
|
52
52
|
|
|
53
53
|
function findFreePort(opt_host) {
|
|
54
54
|
return new Promise((resolve, reject) => {
|
|
55
|
-
const server = net.createServer()
|
|
56
|
-
server.on('listening', function() {
|
|
57
|
-
resolve(server.address().port)
|
|
58
|
-
server.close()
|
|
59
|
-
})
|
|
55
|
+
const server = net.createServer()
|
|
56
|
+
server.on('listening', function () {
|
|
57
|
+
resolve(server.address().port)
|
|
58
|
+
server.close()
|
|
59
|
+
})
|
|
60
60
|
server.on('error', (e) => {
|
|
61
61
|
if (e.code === 'EADDRINUSE' || e.code === 'EACCES') {
|
|
62
62
|
resolve('Unable to find a free port')
|
|
63
63
|
} else {
|
|
64
64
|
reject(e)
|
|
65
65
|
}
|
|
66
|
-
})
|
|
66
|
+
})
|
|
67
67
|
// By providing 0 we let the operative system find an arbitrary port
|
|
68
|
-
server.listen(0, opt_host)
|
|
69
|
-
})
|
|
68
|
+
server.listen(0, opt_host)
|
|
69
|
+
})
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
// PUBLIC API
|
package/opera.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "selenium-webdriver",
|
|
3
|
-
"version": "4.0.0-
|
|
3
|
+
"version": "4.0.0-beta.4",
|
|
4
4
|
"description": "The official WebDriver JavaScript bindings from the Selenium project",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"keywords": [
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"webdriver",
|
|
11
11
|
"webdriverjs"
|
|
12
12
|
],
|
|
13
|
-
"homepage": "https://github.com/SeleniumHQ/selenium",
|
|
13
|
+
"homepage": "https://github.com/SeleniumHQ/selenium/tree/trunk/javascript/node/selenium-webdriver#readme",
|
|
14
14
|
"bugs": {
|
|
15
15
|
"url": "https://github.com/SeleniumHQ/selenium/issues"
|
|
16
16
|
},
|
|
@@ -23,27 +23,27 @@
|
|
|
23
23
|
"node": ">= 10.15.0"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"jszip": "^3.
|
|
27
|
-
"rimraf": "^
|
|
28
|
-
"tmp": "^0.1
|
|
29
|
-
"ws": "
|
|
26
|
+
"jszip": "^3.6.0",
|
|
27
|
+
"rimraf": "^3.0.2",
|
|
28
|
+
"tmp": "^0.2.1",
|
|
29
|
+
"ws": ">=7.4.6"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"eslint": "^7.
|
|
33
|
-
"eslint-config-prettier": "^
|
|
34
|
-
"eslint-plugin-no-only-tests": "^2.
|
|
32
|
+
"eslint": "^7.26.0",
|
|
33
|
+
"eslint-config-prettier": "^8.3.0",
|
|
34
|
+
"eslint-plugin-no-only-tests": "^2.6.0",
|
|
35
35
|
"eslint-plugin-node": "^11.1.0",
|
|
36
|
-
"eslint-plugin-prettier": "^3.
|
|
36
|
+
"eslint-plugin-prettier": "^3.4.0",
|
|
37
37
|
"express": "^4.17.1",
|
|
38
38
|
"jasmine": "^3.6.1",
|
|
39
39
|
"mocha": "^8.1.0",
|
|
40
40
|
"multer": "^1.4.2",
|
|
41
|
-
"prettier": "^2.0
|
|
41
|
+
"prettier": "^2.3.0",
|
|
42
42
|
"serve-index": "^1.9.1",
|
|
43
|
-
"sinon": "^
|
|
43
|
+
"sinon": "^10.0.0"
|
|
44
44
|
},
|
|
45
45
|
"scripts": {
|
|
46
|
-
"lint": "eslint --ignore-pattern node_modules --ignore-pattern generator --ext js \"**/*.js\"",
|
|
46
|
+
"lint": "eslint --ignore-pattern node_modules --ignore-pattern generator --ext js lib/http.js \"**/*.js\"",
|
|
47
47
|
"test": "npm run lint && mocha -t 600000 --recursive test",
|
|
48
48
|
"test-jasmine": "jasmine JASMINE_CONFIG_PATH=jasmine.json"
|
|
49
49
|
},
|
package/proxy.js
CHANGED
|
File without changes
|
package/remote/index.js
CHANGED
|
@@ -210,7 +210,7 @@ class DriverService {
|
|
|
210
210
|
}
|
|
211
211
|
|
|
212
212
|
return resolveCommandLineFlags(this.args_).then((args) => {
|
|
213
|
-
|
|
213
|
+
const command = exec(self.executable_, {
|
|
214
214
|
args: args,
|
|
215
215
|
env: self.env_,
|
|
216
216
|
stdio: self.stdio_,
|
|
@@ -218,8 +218,8 @@ class DriverService {
|
|
|
218
218
|
|
|
219
219
|
resolveCommand(command)
|
|
220
220
|
|
|
221
|
-
|
|
222
|
-
|
|
221
|
+
const earlyTermination = command.result().then(function (result) {
|
|
222
|
+
const error =
|
|
223
223
|
result.code == null
|
|
224
224
|
? Error('Server was killed with ' + result.signal)
|
|
225
225
|
: Error('Server terminated early with status ' + result.code)
|
|
@@ -229,7 +229,7 @@ class DriverService {
|
|
|
229
229
|
throw error
|
|
230
230
|
})
|
|
231
231
|
|
|
232
|
-
|
|
232
|
+
let hostname = self.hostname_
|
|
233
233
|
if (!hostname) {
|
|
234
234
|
hostname =
|
|
235
235
|
(!self.loopbackOnly_ && net.getAddress()) ||
|
|
@@ -338,9 +338,8 @@ DriverService.Builder = class {
|
|
|
338
338
|
* @this {THIS}
|
|
339
339
|
* @template THIS
|
|
340
340
|
*/
|
|
341
|
-
addArguments(
|
|
342
|
-
|
|
343
|
-
this.options_.args = this.options_.args.concat(args)
|
|
341
|
+
addArguments(...arguments_) {
|
|
342
|
+
this.options_.args = this.options_.args.concat(arguments_)
|
|
344
343
|
return this
|
|
345
344
|
}
|
|
346
345
|
|
package/safari.js
CHANGED
|
File without changes
|