selenium-webdriver 4.9.2 → 4.11.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 +48 -0
- package/bidi/browsingContext.js +50 -4
- package/bidi/browsingContextInspector.js +1 -1
- package/bidi/logInspector.js +14 -11
- package/bidi/networkInspector.js +88 -0
- package/bidi/networkTypes.js +483 -0
- package/bidi/protocolValue.js +1 -1
- package/bidi/scriptManager.js +40 -6
- 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 +5 -25
- package/chromium.js +16 -5
- package/common/driverFinder.js +8 -23
- package/common/seleniumManager.js +50 -28
- package/edge.js +17 -25
- package/firefox.js +22 -27
- package/ie.js +4 -17
- package/index.js +2 -0
- package/io/exec.js +2 -2
- package/lib/atoms/find-elements.js +3 -4
- package/lib/by.js +1 -1
- package/lib/webdriver.js +2 -2
- package/package.json +5 -5
- package/remote/util.js +1 -3
- package/safari.js +6 -31
- package/testing/index.js +8 -7
package/common/driverFinder.js
CHANGED
|
@@ -22,38 +22,23 @@
|
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
const { driverLocation } = require('./seleniumManager')
|
|
25
|
-
const fs = require('fs')
|
|
26
25
|
|
|
27
26
|
/**
|
|
28
27
|
* Determines the path of the correct Selenium Manager binary
|
|
29
|
-
* @returns {string}
|
|
28
|
+
* @returns {{browserPath: string, driverPath: string}} path of the driver
|
|
29
|
+
* and browser location
|
|
30
30
|
*/
|
|
31
|
-
function getPath(
|
|
31
|
+
function getPath(capabilities) {
|
|
32
32
|
try {
|
|
33
|
-
return
|
|
33
|
+
return driverLocation(capabilities)
|
|
34
34
|
} catch (e) {
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
throw Error(
|
|
36
|
+
`Unable to obtain browser driver.
|
|
37
37
|
For more information on how to install drivers see
|
|
38
|
-
https://www.selenium.dev/documentation/webdriver/
|
|
39
|
-
|
|
38
|
+
https://www.selenium.dev/documentation/webdriver/troubleshooting/errors/driver_location/. ${e}`
|
|
39
|
+
)
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
/**
|
|
44
|
-
* _Synchronously_ attempts to locate the driver executable on the current
|
|
45
|
-
* system.
|
|
46
|
-
*
|
|
47
|
-
* @param {!string} driverPath
|
|
48
|
-
*
|
|
49
|
-
* @return {?string} the located executable, or `null`.
|
|
50
|
-
*/
|
|
51
|
-
function pathExists(driverPath) {
|
|
52
|
-
if (!driverPath || !fs.existsSync(driverPath)) {
|
|
53
|
-
return null
|
|
54
|
-
}
|
|
55
|
-
return driverPath
|
|
56
|
-
}
|
|
57
|
-
|
|
58
43
|
// PUBLIC API
|
|
59
44
|
module.exports = { getPath }
|
|
@@ -26,11 +26,7 @@ const path = require('path')
|
|
|
26
26
|
const fs = require('fs')
|
|
27
27
|
const spawnSync = require('child_process').spawnSync
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
* currently supported browsers for selenium-manager
|
|
31
|
-
* @type {string[]}
|
|
32
|
-
*/
|
|
33
|
-
const Browser = ['chrome', 'firefox', 'edge', 'MicrosoftEdge', 'iexplorer']
|
|
29
|
+
let debugMessagePrinted = false;
|
|
34
30
|
|
|
35
31
|
/**
|
|
36
32
|
* Determines the path of the correct Selenium Manager binary
|
|
@@ -47,12 +43,7 @@ function getBinary() {
|
|
|
47
43
|
const file =
|
|
48
44
|
directory === 'windows' ? 'selenium-manager.exe' : 'selenium-manager'
|
|
49
45
|
|
|
50
|
-
let seleniumManagerBasePath
|
|
51
|
-
if (process.env.SELENIUM_MANAGER_BASE_PATH) {
|
|
52
|
-
seleniumManagerBasePath = process.env.SELENIUM_MANAGER_BASE_PATH
|
|
53
|
-
} else {
|
|
54
|
-
seleniumManagerBasePath = path.join(__dirname, '..', '/bin')
|
|
55
|
-
}
|
|
46
|
+
let seleniumManagerBasePath = path.join(__dirname, '..', '/bin')
|
|
56
47
|
|
|
57
48
|
const filePath = path.join(seleniumManagerBasePath, directory, file)
|
|
58
49
|
|
|
@@ -60,32 +51,50 @@ function getBinary() {
|
|
|
60
51
|
throw new Error(`Unable to obtain Selenium Manager`)
|
|
61
52
|
}
|
|
62
53
|
|
|
54
|
+
if (!debugMessagePrinted) {
|
|
55
|
+
console.debug(`Selenium Manager binary found at ${filePath}`)
|
|
56
|
+
debugMessagePrinted = true; // Set the flag to true after printing the debug message
|
|
57
|
+
}
|
|
58
|
+
|
|
63
59
|
return filePath
|
|
64
60
|
}
|
|
65
61
|
|
|
66
62
|
/**
|
|
67
63
|
* Determines the path of the correct driver
|
|
68
64
|
* @param {Capabilities} options browser options to fetch the driver
|
|
69
|
-
* @returns {string} path of the driver
|
|
65
|
+
* @returns {{browserPath: string, driverPath: string}} path of the driver and
|
|
66
|
+
* browser location
|
|
70
67
|
*/
|
|
71
68
|
|
|
72
69
|
function driverLocation(options) {
|
|
73
|
-
if (!Browser.includes(options.getBrowserName().toLocaleString())) {
|
|
74
|
-
throw new Error(
|
|
75
|
-
`Unable to locate driver associated with browser name: ${options.getBrowserName()}`
|
|
76
|
-
)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
70
|
let args = ['--browser', options.getBrowserName(), '--output', 'json']
|
|
80
71
|
|
|
81
|
-
if (options.getBrowserVersion() && options.getBrowserVersion() !==
|
|
82
|
-
args.push(
|
|
72
|
+
if (options.getBrowserVersion() && options.getBrowserVersion() !== '') {
|
|
73
|
+
args.push('--browser-version', options.getBrowserVersion())
|
|
83
74
|
}
|
|
84
75
|
|
|
85
|
-
const vendorOptions =
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
76
|
+
const vendorOptions =
|
|
77
|
+
options.get('goog:chromeOptions') ||
|
|
78
|
+
options.get('ms:edgeOptions') ||
|
|
79
|
+
options.get('moz:firefoxOptions')
|
|
80
|
+
if (vendorOptions && vendorOptions.binary && vendorOptions.binary !== '') {
|
|
81
|
+
args.push('--browser-path', '"' + vendorOptions.binary + '"')
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const proxyOptions = options.getProxy();
|
|
85
|
+
|
|
86
|
+
// Check if proxyOptions exists and has properties
|
|
87
|
+
if (proxyOptions && Object.keys(proxyOptions).length > 0) {
|
|
88
|
+
const httpProxy = proxyOptions['httpProxy'];
|
|
89
|
+
const sslProxy = proxyOptions['sslProxy'];
|
|
90
|
+
|
|
91
|
+
if (httpProxy !== undefined) {
|
|
92
|
+
args.push('--proxy', httpProxy);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
else if (sslProxy !== undefined) {
|
|
96
|
+
args.push('--proxy', sslProxy);
|
|
97
|
+
}
|
|
89
98
|
}
|
|
90
99
|
|
|
91
100
|
const smBinary = getBinary()
|
|
@@ -99,27 +108,40 @@ function driverLocation(options) {
|
|
|
99
108
|
if (spawnResult.stdout.toString()) {
|
|
100
109
|
try {
|
|
101
110
|
output = JSON.parse(spawnResult.stdout.toString())
|
|
111
|
+
logOutput(output)
|
|
102
112
|
errorMessage = output.result.message
|
|
103
113
|
} catch (e) {
|
|
104
114
|
errorMessage = e.toString()
|
|
105
115
|
}
|
|
106
116
|
}
|
|
107
|
-
throw new Error(
|
|
117
|
+
throw new Error(
|
|
118
|
+
`Error executing command for ${smBinary} with ${args}: ${errorMessage}`
|
|
119
|
+
)
|
|
108
120
|
}
|
|
109
121
|
try {
|
|
110
122
|
output = JSON.parse(spawnResult.stdout.toString())
|
|
111
123
|
} catch (e) {
|
|
112
|
-
throw new Error(
|
|
124
|
+
throw new Error(
|
|
125
|
+
`Error executing command for ${smBinary} with ${args}: ${e.toString()}`
|
|
126
|
+
)
|
|
113
127
|
}
|
|
114
128
|
|
|
129
|
+
logOutput(output)
|
|
130
|
+
return {
|
|
131
|
+
driverPath: output.result.driver_path,
|
|
132
|
+
browserPath: output.result.browser_path,
|
|
133
|
+
}
|
|
134
|
+
}
|
|
115
135
|
|
|
136
|
+
function logOutput (output) {
|
|
116
137
|
for (const key in output.logs) {
|
|
117
138
|
if (output.logs[key].level === 'WARN') {
|
|
118
139
|
console.warn(`${output.logs[key].message}`)
|
|
119
140
|
}
|
|
141
|
+
if (['DEBUG', 'INFO'].includes(output.logs[key].level)) {
|
|
142
|
+
console.debug(`${output.logs[key].message}`)
|
|
143
|
+
}
|
|
120
144
|
}
|
|
121
|
-
|
|
122
|
-
return output.result.message
|
|
123
145
|
}
|
|
124
146
|
|
|
125
147
|
// PUBLIC API
|
package/edge.js
CHANGED
|
@@ -78,16 +78,8 @@
|
|
|
78
78
|
'use strict'
|
|
79
79
|
|
|
80
80
|
const { Browser } = require('./lib/capabilities')
|
|
81
|
-
const io = require('./io')
|
|
82
81
|
const chromium = require('./chromium')
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Name of the EdgeDriver executable.
|
|
86
|
-
* @type {string}
|
|
87
|
-
* @const
|
|
88
|
-
*/
|
|
89
|
-
const EDGEDRIVER_CHROMIUM_EXE =
|
|
90
|
-
process.platform === 'win32' ? 'msedgedriver.exe' : 'msedgedriver'
|
|
82
|
+
const EDGE_CAPABILITY_KEY = 'ms:edgeOptions'
|
|
91
83
|
|
|
92
84
|
/** @type {remote.DriverService} */
|
|
93
85
|
|
|
@@ -105,8 +97,7 @@ class ServiceBuilder extends chromium.ServiceBuilder {
|
|
|
105
97
|
* cannot be found on the PATH.
|
|
106
98
|
*/
|
|
107
99
|
constructor(opt_exe) {
|
|
108
|
-
|
|
109
|
-
super(exe)
|
|
100
|
+
super(opt_exe)
|
|
110
101
|
this.setLoopback(true)
|
|
111
102
|
}
|
|
112
103
|
}
|
|
@@ -127,6 +118,19 @@ class Options extends chromium.Options {
|
|
|
127
118
|
setEdgeChromiumBinaryPath(path) {
|
|
128
119
|
return this.setBinaryPath(path)
|
|
129
120
|
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Changes the browser name to 'webview2' to enable
|
|
124
|
+
* <a href="https://learn.microsoft.com/en-us/microsoft-edge/webview2/how-to/webdriver">
|
|
125
|
+
* test automation of WebView2 apps with Microsoft Edge WebDriver
|
|
126
|
+
* </a>
|
|
127
|
+
*
|
|
128
|
+
* @param {boolean} enable flag to enable or disable the 'webview2' usage
|
|
129
|
+
*/
|
|
130
|
+
useWebView(enable) {
|
|
131
|
+
const browserName = enable ? 'webview2' : Browser.EDGE
|
|
132
|
+
return this.setBrowserName(browserName)
|
|
133
|
+
}
|
|
130
134
|
}
|
|
131
135
|
|
|
132
136
|
/**
|
|
@@ -144,7 +148,7 @@ class Driver extends chromium.Driver {
|
|
|
144
148
|
static createSession(opt_config, opt_serviceExecutor) {
|
|
145
149
|
let caps = opt_config || new Options()
|
|
146
150
|
return /** @type {!Driver} */ (
|
|
147
|
-
super.createSession(caps, opt_serviceExecutor)
|
|
151
|
+
super.createSession(caps, opt_serviceExecutor, 'ms', EDGE_CAPABILITY_KEY)
|
|
148
152
|
)
|
|
149
153
|
}
|
|
150
154
|
|
|
@@ -164,19 +168,8 @@ class Driver extends chromium.Driver {
|
|
|
164
168
|
setFileDetector() {}
|
|
165
169
|
}
|
|
166
170
|
|
|
167
|
-
/**
|
|
168
|
-
* _Synchronously_ attempts to locate the chromedriver executable on the current
|
|
169
|
-
* system.
|
|
170
|
-
*
|
|
171
|
-
* @return {?string} the located executable, or `null`.
|
|
172
|
-
*/
|
|
173
|
-
function locateSynchronously() {
|
|
174
|
-
return io.findInPath(EDGEDRIVER_CHROMIUM_EXE, true)
|
|
175
|
-
}
|
|
176
|
-
|
|
177
171
|
Options.prototype.BROWSER_NAME_VALUE = Browser.EDGE
|
|
178
|
-
Options.prototype.CAPABILITY_KEY =
|
|
179
|
-
Driver.prototype.VENDOR_CAPABILITY_PREFIX = 'ms'
|
|
172
|
+
Options.prototype.CAPABILITY_KEY = EDGE_CAPABILITY_KEY
|
|
180
173
|
|
|
181
174
|
// PUBLIC API
|
|
182
175
|
|
|
@@ -184,5 +177,4 @@ module.exports = {
|
|
|
184
177
|
Driver,
|
|
185
178
|
Options,
|
|
186
179
|
ServiceBuilder,
|
|
187
|
-
locateSynchronously,
|
|
188
180
|
}
|
package/firefox.js
CHANGED
|
@@ -128,6 +128,7 @@ const zip = require('./io/zip')
|
|
|
128
128
|
const { Browser, Capabilities } = require('./lib/capabilities')
|
|
129
129
|
const { Zip } = require('./io/zip')
|
|
130
130
|
const { getPath } = require('./common/driverFinder')
|
|
131
|
+
const FIREFOX_CAPABILITY_KEY = 'moz:firefoxOptions'
|
|
131
132
|
|
|
132
133
|
/**
|
|
133
134
|
* Thrown when there an add-on is malformed.
|
|
@@ -263,10 +264,10 @@ class Options extends Capabilities {
|
|
|
263
264
|
* @private
|
|
264
265
|
*/
|
|
265
266
|
firefoxOptions_() {
|
|
266
|
-
let options = this.get(
|
|
267
|
+
let options = this.get(FIREFOX_CAPABILITY_KEY)
|
|
267
268
|
if (!options) {
|
|
268
269
|
options = {}
|
|
269
|
-
this.set(
|
|
270
|
+
this.set(FIREFOX_CAPABILITY_KEY, options)
|
|
270
271
|
}
|
|
271
272
|
return options
|
|
272
273
|
}
|
|
@@ -453,27 +454,6 @@ const Context = {
|
|
|
453
454
|
CHROME: 'chrome',
|
|
454
455
|
}
|
|
455
456
|
|
|
456
|
-
const GECKO_DRIVER_EXE =
|
|
457
|
-
process.platform === 'win32' ? 'geckodriver.exe' : 'geckodriver'
|
|
458
|
-
|
|
459
|
-
/**
|
|
460
|
-
* _Synchronously_ attempts to locate the geckodriver executable on the current
|
|
461
|
-
* system.
|
|
462
|
-
*
|
|
463
|
-
* @return {?string} the located executable, or `null`.
|
|
464
|
-
*/
|
|
465
|
-
function locateSynchronously() {
|
|
466
|
-
return io.findInPath(GECKO_DRIVER_EXE, true)
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
/**
|
|
470
|
-
* @return {string} .
|
|
471
|
-
* @throws {Error}
|
|
472
|
-
*/
|
|
473
|
-
function findGeckoDriver() {
|
|
474
|
-
return locateSynchronously()
|
|
475
|
-
}
|
|
476
|
-
|
|
477
457
|
/**
|
|
478
458
|
* @param {string} file Path to the file to find, relative to the program files
|
|
479
459
|
* root.
|
|
@@ -555,7 +535,7 @@ class ServiceBuilder extends remote.DriverService.Builder {
|
|
|
555
535
|
* the builder will attempt to locate the geckodriver on the system PATH.
|
|
556
536
|
*/
|
|
557
537
|
constructor(opt_exe) {
|
|
558
|
-
super(opt_exe
|
|
538
|
+
super(opt_exe)
|
|
559
539
|
this.setLoopback(true) // Required.
|
|
560
540
|
}
|
|
561
541
|
|
|
@@ -601,6 +581,8 @@ class Driver extends webdriver.WebDriver {
|
|
|
601
581
|
let caps =
|
|
602
582
|
opt_config instanceof Capabilities ? opt_config : new Options(opt_config)
|
|
603
583
|
|
|
584
|
+
let firefoxBrowserPath = null
|
|
585
|
+
|
|
604
586
|
let executor
|
|
605
587
|
let onQuit
|
|
606
588
|
|
|
@@ -609,19 +591,33 @@ class Driver extends webdriver.WebDriver {
|
|
|
609
591
|
configureExecutor(executor)
|
|
610
592
|
} else if (opt_executor instanceof remote.DriverService) {
|
|
611
593
|
if (!opt_executor.getExecutable()) {
|
|
612
|
-
|
|
594
|
+
const {driverPath, browserPath} = getPath(caps)
|
|
595
|
+
opt_executor.setExecutable(driverPath)
|
|
596
|
+
firefoxBrowserPath = browserPath
|
|
613
597
|
}
|
|
614
598
|
executor = createExecutor(opt_executor.start())
|
|
615
599
|
onQuit = () => opt_executor.kill()
|
|
616
600
|
} else {
|
|
617
601
|
let service = new ServiceBuilder().build()
|
|
618
602
|
if (!service.getExecutable()) {
|
|
619
|
-
|
|
603
|
+
const {driverPath, browserPath} = getPath(caps)
|
|
604
|
+
service.setExecutable(driverPath)
|
|
605
|
+
firefoxBrowserPath = browserPath
|
|
620
606
|
}
|
|
621
607
|
executor = createExecutor(service.start())
|
|
622
608
|
onQuit = () => service.kill()
|
|
623
609
|
}
|
|
624
610
|
|
|
611
|
+
if (firefoxBrowserPath) {
|
|
612
|
+
const vendorOptions = caps.get(FIREFOX_CAPABILITY_KEY)
|
|
613
|
+
if (vendorOptions) {
|
|
614
|
+
vendorOptions['binary'] = firefoxBrowserPath
|
|
615
|
+
caps.set(FIREFOX_CAPABILITY_KEY, vendorOptions)
|
|
616
|
+
} else {
|
|
617
|
+
caps.set(FIREFOX_CAPABILITY_KEY, {binary: firefoxBrowserPath})
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
|
|
625
621
|
return /** @type {!Driver} */ (super.createSession(executor, caps, onQuit))
|
|
626
622
|
}
|
|
627
623
|
|
|
@@ -832,5 +828,4 @@ module.exports = {
|
|
|
832
828
|
Driver,
|
|
833
829
|
Options,
|
|
834
830
|
ServiceBuilder,
|
|
835
|
-
locateSynchronously,
|
|
836
831
|
}
|
package/ie.js
CHANGED
|
@@ -27,9 +27,7 @@
|
|
|
27
27
|
|
|
28
28
|
'use strict'
|
|
29
29
|
|
|
30
|
-
const fs = require('fs')
|
|
31
30
|
const http = require('./http')
|
|
32
|
-
const io = require('./io')
|
|
33
31
|
const portprober = require('./net/portprober')
|
|
34
32
|
const remote = require('./remote')
|
|
35
33
|
const webdriver = require('./lib/webdriver')
|
|
@@ -37,7 +35,6 @@ const { Browser, Capabilities } = require('./lib/capabilities')
|
|
|
37
35
|
const error = require('./lib/error')
|
|
38
36
|
const { getPath } = require('./common/driverFinder')
|
|
39
37
|
|
|
40
|
-
const IEDRIVER_EXE = 'IEDriverServer.exe'
|
|
41
38
|
const OPTIONS_CAPABILITY_KEY = 'se:ieOptions'
|
|
42
39
|
const SCROLL_BEHAVIOUR = {
|
|
43
40
|
BOTTOM: 1,
|
|
@@ -83,6 +80,7 @@ const Key = {
|
|
|
83
80
|
FILE_UPLOAD_DIALOG_TIMEOUT: 'ie.fileUploadDialogTimeout',
|
|
84
81
|
ATTACH_TO_EDGE_CHROMIUM: 'ie.edgechromium',
|
|
85
82
|
EDGE_EXECUTABLE_PATH: 'ie.edgepath',
|
|
83
|
+
IGNORE_PROCESS_MATCH: 'ie.ignoreprocessmatch',
|
|
86
84
|
}
|
|
87
85
|
|
|
88
86
|
/**
|
|
@@ -379,16 +377,6 @@ class Options extends Capabilities {
|
|
|
379
377
|
}
|
|
380
378
|
}
|
|
381
379
|
|
|
382
|
-
/**
|
|
383
|
-
* _Synchronously_ attempts to locate the IE driver executable on the current
|
|
384
|
-
* system.
|
|
385
|
-
*
|
|
386
|
-
* @return {?string} the located executable, or `null`.
|
|
387
|
-
*/
|
|
388
|
-
function locateSynchronously() {
|
|
389
|
-
return process.platform === 'win32' ? io.findInPath(IEDRIVER_EXE, true) : null
|
|
390
|
-
}
|
|
391
|
-
|
|
392
380
|
function createServiceFromCapabilities(capabilities) {
|
|
393
381
|
if (process.platform !== 'win32') {
|
|
394
382
|
throw Error(
|
|
@@ -399,7 +387,7 @@ function createServiceFromCapabilities(capabilities) {
|
|
|
399
387
|
)
|
|
400
388
|
}
|
|
401
389
|
|
|
402
|
-
let exe =
|
|
390
|
+
let exe = null // Let Selenium Manager find it
|
|
403
391
|
var args = []
|
|
404
392
|
if (capabilities.has(Key.HOST)) {
|
|
405
393
|
args.push('--host=' + capabilities.get(Key.HOST))
|
|
@@ -439,7 +427,7 @@ class ServiceBuilder extends remote.DriverService.Builder {
|
|
|
439
427
|
* the builder will attempt to locate the IEDriverServer on the system PATH.
|
|
440
428
|
*/
|
|
441
429
|
constructor(opt_exe) {
|
|
442
|
-
super(opt_exe
|
|
430
|
+
super(opt_exe)
|
|
443
431
|
this.setLoopback(true) // Required.
|
|
444
432
|
}
|
|
445
433
|
}
|
|
@@ -467,7 +455,7 @@ class Driver extends webdriver.WebDriver {
|
|
|
467
455
|
service = createServiceFromCapabilities(options)
|
|
468
456
|
}
|
|
469
457
|
if (!service.getExecutable()) {
|
|
470
|
-
service.setExecutable(getPath(
|
|
458
|
+
service.setExecutable(getPath(options).driverPath)
|
|
471
459
|
}
|
|
472
460
|
|
|
473
461
|
let client = service.start().then((url) => new http.HttpClient(url))
|
|
@@ -495,4 +483,3 @@ exports.ServiceBuilder = ServiceBuilder
|
|
|
495
483
|
exports.Key = Key
|
|
496
484
|
exports.VENDOR_COMMAND_PREFIX = OPTIONS_CAPABILITY_KEY
|
|
497
485
|
exports.Behavior = SCROLL_BEHAVIOUR
|
|
498
|
-
exports.locateSynchronously = locateSynchronously
|
package/index.js
CHANGED
|
@@ -43,6 +43,7 @@ const LogInspector = require('./bidi/logInspector')
|
|
|
43
43
|
const BrowsingContext = require('./bidi/browsingContext')
|
|
44
44
|
const BrowsingConextInspector = require('./bidi/browsingContextInspector')
|
|
45
45
|
const ScriptManager = require('./bidi/scriptManager')
|
|
46
|
+
const NetworkInspector = require('./bidi/networkInspector')
|
|
46
47
|
|
|
47
48
|
const Browser = capabilities.Browser
|
|
48
49
|
const Capabilities = capabilities.Capabilities
|
|
@@ -803,3 +804,4 @@ exports.LogInspector = LogInspector
|
|
|
803
804
|
exports.BrowsingContext = BrowsingContext
|
|
804
805
|
exports.BrowsingConextInspector = BrowsingConextInspector
|
|
805
806
|
exports.ScriptManager = ScriptManager
|
|
807
|
+
exports.NetworkInspector = NetworkInspector
|
package/io/exec.js
CHANGED
|
@@ -114,10 +114,9 @@ function nd(a,b,c,d){a=a.nodeValue.replace(/[\u200b\u200e\u200f]/g,"");a=a.repla
|
|
|
114
114
|
function pd(a,b,c,d,e){if(3==a.nodeType&&c)nd(a,b,d,e);else if(S(a))if(S(a,"CONTENT")||S(a,"SLOT")){for(var f=a;f.parentNode;)f=f.parentNode;f instanceof ShadowRoot?(a=S(a,"CONTENT")?a.getDistributedNodes():a.assignedNodes(),l(a,function(g){pd(g,b,c,d,e)})):jd(a,b)}else if(S(a,"SHADOW")){for(f=a;f.parentNode;)f=f.parentNode;if(f instanceof ShadowRoot&&(a=f))for(a=a.olderShadowRoot;a;)l(a.childNodes,function(g){pd(g,b,c,d,e)}),a=a.olderShadowRoot}else jd(a,b)}
|
|
115
115
|
function jd(a,b){a.shadowRoot&&l(a.shadowRoot.childNodes,function(c){pd(c,b,!0,null,null)});ld(a,b,function(c,d,e,f,g){var h=null;1==c.nodeType?h=c:3==c.nodeType&&(h=c);null!=h&&(null!=h.assignedSlot||h.getDestinationInsertionPoints&&0<h.getDestinationInsertionPoints().length)||pd(c,d,e,f,g)})};var qd={C:function(a,b){return!(!a.querySelectorAll||!a.querySelector)&&!/^\d.*/.test(b)},o:function(a,b){var c=eb(b),d="string"===typeof a?c.a.getElementById(a):a;return d?Uc(d,"id")==a&&b!=d&&hb(b,d)?d:ua(mb(c,"*"),function(e){return Uc(e,"id")==a&&b!=e&&hb(b,e)}):null},j:function(a,b){if(!a)return[];if(qd.C(b,a))try{return b.querySelectorAll("#"+qd.T(a))}catch(c){return[]}b=mb(eb(b),"*",null,b);return pa(b,function(c){return Uc(c,"id")==a})},T:function(a){return a.replace(/([\s'"\\#.:;,!?+<>=~*^$|%&@`{}\-\/\[\]\(\)])/g,
|
|
116
116
|
"\\$1")}};var Y={},rd={};Y.N=function(a,b,c){try{var d=Nc.j("a",b)}catch(e){d=mb(eb(b),"A",null,b)}return ua(d,function(e){e=id(e);e=e.replace(/^[\s]+|[\s]+$/g,"");return c&&-1!=e.indexOf(a)||e==a})};Y.K=function(a,b,c){try{var d=Nc.j("a",b)}catch(e){d=mb(eb(b),"A",null,b)}return pa(d,function(e){e=id(e);e=e.replace(/^[\s]+|[\s]+$/g,"");return c&&-1!=e.indexOf(a)||e==a})};Y.o=function(a,b){return Y.N(a,b,!1)};Y.j=function(a,b){return Y.K(a,b,!1)};rd.o=function(a,b){return Y.N(a,b,!0)};
|
|
117
|
-
rd.j=function(a,b){return Y.K(a,b,!0)};var Z={F:function(a,b){return function(c){var d=Z.u(a);d=W(d);c=W(c);return b.call(null,d,c)}},R:function(a){return Z.F(a,function(b,c){return c.b+c.height<b.b})},S:function(a){return Z.F(a,function(b,c){return b.b+b.height<c.b})},V:function(a){return Z.F(a,function(b,c){return c.a+c.width<b.a})},aa:function(a){return Z.F(a,function(b,c){return b.a+b.width<c.a})},W:function(a,b){var c;b?c=b:"number"==typeof a.distance&&(c=a.distance);c||(c=
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
Z.U=function(a,b){var c=[];l(a,function(e){e&&ta(b,function(f){var g=f.kind,h=Z.P[g];if(!h)throw new P(61,"Cannot find filter suitable for "+g);return h.apply(null,f.args)(e)},null)&&c.push(e)},null);a=b[b.length-1];var d=Z.O[a?a.kind:"unknown"];return d?(a=d.apply(null,a.args))?Z.ba(a,c):c:c};
|
|
117
|
+
rd.j=function(a,b){return Y.K(a,b,!0)};var Z={F:function(a,b){return function(c){var d=Z.u(a);d=W(d);c=W(c);return b.call(null,d,c)}},R:function(a){return Z.F(a,function(b,c){return c.b+c.height<b.b})},S:function(a){return Z.F(a,function(b,c){return b.b+b.height<c.b})},V:function(a){return Z.F(a,function(b,c){return c.a+c.width<b.a})},aa:function(a){return Z.F(a,function(b,c){return b.a+b.width<c.a})},W:function(a,b){var c;b?c=b:"number"==typeof a.distance&&(c=a.distance);c||(c=50);return function(d){var e=Z.u(a);if(e===d)return!1;e=W(e);
|
|
118
|
+
d=W(d);e=new U(e.a-c,e.b-c,e.width+2*c,e.height+2*c);return e.a<=d.a+d.width&&d.a<=e.a+e.width&&e.b<=d.b+d.height&&d.b<=e.b+e.height}},u:function(a){if(ha(a)&&1==a.nodeType)return a;if(ea(a))return Z.u(a.call(null));if(ha(a)){var b;a:{if(b=sd(a)){var c=td[b];if(c&&ea(c.o)){b=c.o(a[b],Bc.document);break a}}throw new P(61,"Unsupported locator strategy: "+b);}if(!b)throw new P(7,"No element has been found by "+JSON.stringify(a));return b}throw new P(61,"Selector is of wrong type: "+JSON.stringify(a));
|
|
119
|
+
}};Z.P={left:Z.V,right:Z.aa,above:Z.R,below:Z.S,near:Z.W};Z.O={left:Z.u,right:Z.u,above:Z.u,below:Z.u,near:Z.u};Z.U=function(a,b){var c=[];l(a,function(e){e&&ta(b,function(f){var g=f.kind,h=Z.P[g];if(!h)throw new P(61,"Cannot find filter suitable for "+g);return h.apply(null,f.args)(e)},null)&&c.push(e)},null);a=b[b.length-1];var d=Z.O[a?a.kind:"unknown"];return d?(a=d.apply(null,a.args))?Z.ba(a,c):c:c};
|
|
121
120
|
Z.ba=function(a,b){function c(f){f=W(f);return Math.sqrt(Math.pow(d-(f.a+Math.max(1,f.width)/2),2)+Math.pow(e-(f.b+Math.max(1,f.height)/2),2))}a=W(a);var d=a.a+Math.max(1,a.width)/2,e=a.b+Math.max(1,a.height)/2;xa(b,function(f,g){return c(f)-c(g)});return b};Z.o=function(a,b){a=Z.j(a,b);return 0==a.length?null:a[0]};
|
|
122
121
|
Z.j=function(a,b){if(!a.hasOwnProperty("root")||!a.hasOwnProperty("filters"))throw new P(61,"Locator not suitable for relative locators: "+JSON.stringify(a));var c=a.filters,d=da(c);if("array"!=d&&("object"!=d||"number"!=typeof c.length))throw new P(61,"Targets should be an array: "+JSON.stringify(a));var e;S(a.root)?e=[a.root]:e=ud(a.root,b);return 0==e.length?[]:Z.U(e,a.filters)};var vd={o:function(a,b){if(""===a)throw new P(32,'Unable to locate an element with the tagName ""');return b.getElementsByTagName(a)[0]||null},j:function(a,b){if(""===a)throw new P(32,'Unable to locate an element with the tagName ""');return b.getElementsByTagName(a)}};var td={className:Dc,"class name":Dc,css:Nc,"css selector":Nc,relative:Z,id:qd,linkText:Y,"link text":Y,name:{o:function(a,b){b=mb(eb(b),"*",null,b);return ua(b,function(c){return Uc(c,"name")==a})},j:function(a,b){b=mb(eb(b),"*",null,b);return pa(b,function(c){return Uc(c,"name")==a})}},partialLinkText:rd,"partial link text":rd,tagName:vd,"tag name":vd,xpath:T};function sd(a){for(var b in a)if(a.hasOwnProperty(b))return b;return null}
|
|
123
122
|
function ud(a,b){var c=sd(a);if(c){var d=td[c];if(d&&ea(d.j))return d.j(a[c],b||Bc.document)}throw new P(61,"Unsupported locator strategy: "+c);};ca("_",ud);; return this._.apply(null,arguments);}).apply({navigator:typeof window!='undefined'?window.navigator:null,document:typeof window!='undefined'?window.document:null}, arguments);};
|
package/lib/by.js
CHANGED
|
@@ -396,7 +396,7 @@ class RelativeBy {
|
|
|
396
396
|
* strategy.
|
|
397
397
|
*/
|
|
398
398
|
function check(locator) {
|
|
399
|
-
if (locator instanceof By || typeof locator === 'function') {
|
|
399
|
+
if (locator instanceof By || locator instanceof RelativeBy || typeof locator === 'function') {
|
|
400
400
|
return locator
|
|
401
401
|
}
|
|
402
402
|
|
package/lib/webdriver.js
CHANGED
|
@@ -1238,8 +1238,8 @@ class WebDriver {
|
|
|
1238
1238
|
} else {
|
|
1239
1239
|
const seCdp = caps['map_'].get('se:cdp')
|
|
1240
1240
|
const vendorInfo =
|
|
1241
|
-
caps['map_'].get(
|
|
1242
|
-
caps['map_'].get(
|
|
1241
|
+
caps['map_'].get('goog:chromeOptions') ||
|
|
1242
|
+
caps['map_'].get('ms:edgeOptions') ||
|
|
1243
1243
|
caps['map_'].get('moz:debuggerAddress') ||
|
|
1244
1244
|
new Map()
|
|
1245
1245
|
debuggerUrl = seCdp || vendorInfo['debuggerAddress'] || vendorInfo
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "selenium-webdriver",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.11.0",
|
|
4
4
|
"description": "The official WebDriver JavaScript bindings from the Selenium project",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"keywords": [
|
|
@@ -28,17 +28,17 @@
|
|
|
28
28
|
"ws": ">=8.13.0"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"eslint": "^8.
|
|
31
|
+
"eslint": "^8.44.0",
|
|
32
32
|
"eslint-config-prettier": "^8.8.0",
|
|
33
33
|
"eslint-plugin-no-only-tests": "^3.1.0",
|
|
34
34
|
"eslint-plugin-node": "^11.1.0",
|
|
35
|
-
"eslint-plugin-prettier": "^
|
|
35
|
+
"eslint-plugin-prettier": "^5.0.0",
|
|
36
36
|
"express": "^4.18.2",
|
|
37
37
|
"mocha": "^10.2.0",
|
|
38
38
|
"multer": "^1.4.5-lts.1",
|
|
39
|
-
"prettier": "^
|
|
39
|
+
"prettier": "^3.0.0",
|
|
40
40
|
"serve-index": "^1.9.1",
|
|
41
|
-
"sinon": "^15.0
|
|
41
|
+
"sinon": "^15.2.0"
|
|
42
42
|
},
|
|
43
43
|
"scripts": {
|
|
44
44
|
"lint": "eslint --ignore-pattern node_modules --ignore-pattern generator --ext js lib/http.js \"**/*.js\"",
|
package/remote/util.js
CHANGED
|
@@ -37,9 +37,7 @@ function getJavaPath() {
|
|
|
37
37
|
function isSelenium3x(seleniumStandalonePath) {
|
|
38
38
|
const javaPath = getJavaPath()
|
|
39
39
|
|
|
40
|
-
const execRes = cp.
|
|
41
|
-
`${javaPath} -jar ${seleniumStandalonePath} --version`
|
|
42
|
-
)
|
|
40
|
+
const execRes = cp.execFileSync(javaPath, ['-jar', seleniumStandalonePath, '--version'])
|
|
43
41
|
|
|
44
42
|
return execRes.toString().trim().startsWith('Selenium server version: 3')
|
|
45
43
|
}
|
package/safari.js
CHANGED
|
@@ -22,37 +22,10 @@
|
|
|
22
22
|
'use strict'
|
|
23
23
|
|
|
24
24
|
const http = require('./http')
|
|
25
|
-
const io = require('./io')
|
|
26
25
|
const remote = require('./remote')
|
|
27
26
|
const webdriver = require('./lib/webdriver')
|
|
28
27
|
const { Browser, Capabilities } = require('./lib/capabilities')
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* _Synchronously_ attempts to locate the IE driver executable on the current
|
|
32
|
-
* system.
|
|
33
|
-
*
|
|
34
|
-
* @return {?string} the located executable, or `null`.
|
|
35
|
-
*/
|
|
36
|
-
function locateSynchronously() {
|
|
37
|
-
return process.platform === 'darwin'
|
|
38
|
-
? io.findInPath('safaridriver', true)
|
|
39
|
-
: null
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* @return {string} .
|
|
44
|
-
* @throws {Error}
|
|
45
|
-
*/
|
|
46
|
-
function findSafariDriver() {
|
|
47
|
-
let exe = locateSynchronously()
|
|
48
|
-
if (!exe) {
|
|
49
|
-
throw Error(
|
|
50
|
-
`The safaridriver executable could not be found on the current PATH.
|
|
51
|
-
Please ensure you are using Safari 10.0 or above.`
|
|
52
|
-
)
|
|
53
|
-
}
|
|
54
|
-
return exe
|
|
55
|
-
}
|
|
28
|
+
const { getPath } = require('./common/driverFinder')
|
|
56
29
|
|
|
57
30
|
/**
|
|
58
31
|
* Creates {@link selenium-webdriver/remote.DriverService} instances that manage
|
|
@@ -66,12 +39,12 @@ class ServiceBuilder extends remote.DriverService.Builder {
|
|
|
66
39
|
* the builder will attempt to locate the safaridriver on the system PATH.
|
|
67
40
|
*/
|
|
68
41
|
constructor(opt_exe) {
|
|
69
|
-
super(opt_exe
|
|
42
|
+
super(opt_exe)
|
|
70
43
|
this.setLoopback(true) // Required.
|
|
71
44
|
}
|
|
72
45
|
}
|
|
73
46
|
|
|
74
|
-
const OPTIONS_CAPABILITY_KEY = 'safari
|
|
47
|
+
const OPTIONS_CAPABILITY_KEY = 'safari:options'
|
|
75
48
|
const TECHNOLOGY_PREVIEW_OPTIONS_KEY = 'technologyPreview'
|
|
76
49
|
|
|
77
50
|
/**
|
|
@@ -150,6 +123,9 @@ class Driver extends webdriver.WebDriver {
|
|
|
150
123
|
}
|
|
151
124
|
|
|
152
125
|
let service = new ServiceBuilder(exe).build()
|
|
126
|
+
if (!service.getExecutable()) {
|
|
127
|
+
service.setExecutable(getPath(caps).driverPath)
|
|
128
|
+
}
|
|
153
129
|
let executor = new http.Executor(
|
|
154
130
|
service.start().then((url) => new http.HttpClient(url))
|
|
155
131
|
)
|
|
@@ -165,4 +141,3 @@ class Driver extends webdriver.WebDriver {
|
|
|
165
141
|
exports.Driver = Driver
|
|
166
142
|
exports.Options = Options
|
|
167
143
|
exports.ServiceBuilder = ServiceBuilder
|
|
168
|
-
exports.locateSynchronously = locateSynchronously
|
package/testing/index.js
CHANGED
|
@@ -41,6 +41,7 @@ const remote = require('../remote')
|
|
|
41
41
|
const safari = require('../safari')
|
|
42
42
|
const { Browser } = require('../lib/capabilities')
|
|
43
43
|
const { Builder } = require('../index')
|
|
44
|
+
const { getPath } = require('../common/driverFinder')
|
|
44
45
|
|
|
45
46
|
/**
|
|
46
47
|
* Describes a browser targeted by a {@linkplain suite test suite}.
|
|
@@ -117,19 +118,19 @@ function getAvailableBrowsers() {
|
|
|
117
118
|
info(`Searching for WebDriver executables installed on the current system...`)
|
|
118
119
|
|
|
119
120
|
let targets = [
|
|
120
|
-
[chrome.
|
|
121
|
-
[edge.
|
|
122
|
-
[firefox.
|
|
123
|
-
[ie.
|
|
124
|
-
[safari.
|
|
121
|
+
[getPath(chrome.Options).driverPath, Browser.CHROME],
|
|
122
|
+
[getPath(edge.Options).driverPath, Browser.EDGE],
|
|
123
|
+
[getPath(firefox.Options).driverPath, Browser.FIREFOX],
|
|
124
|
+
[getPath(ie.Options).driverPath, Browser.INTERNET_EXPLORER],
|
|
125
|
+
[getPath(safari.Options).driverPath, Browser.SAFARI],
|
|
125
126
|
]
|
|
126
127
|
|
|
127
128
|
let availableBrowsers = []
|
|
128
129
|
for (let pair of targets) {
|
|
129
|
-
const
|
|
130
|
+
const driverPath = pair[0]
|
|
130
131
|
const name = pair[1]
|
|
131
132
|
const capabilities = pair[2]
|
|
132
|
-
if (
|
|
133
|
+
if (driverPath.length > 0) {
|
|
133
134
|
info(`... located ${name}`)
|
|
134
135
|
availableBrowsers.push({ name, capabilities })
|
|
135
136
|
}
|