selenium-webdriver 4.10.0 → 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.
@@ -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
@@ -55,26 +51,22 @@ function getBinary() {
55
51
  throw new Error(`Unable to obtain Selenium Manager`)
56
52
  }
57
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
+
58
59
  return filePath
59
60
  }
60
61
 
61
62
  /**
62
63
  * Determines the path of the correct driver
63
64
  * @param {Capabilities} options browser options to fetch the driver
64
- * @returns {string} path of the driver location
65
+ * @returns {{browserPath: string, driverPath: string}} path of the driver and
66
+ * browser location
65
67
  */
66
68
 
67
69
  function driverLocation(options) {
68
- if (!Browser.includes(options.getBrowserName().toLocaleString())) {
69
- throw new Error(
70
- `Unable to locate driver associated with browser name: ${options.getBrowserName()}`
71
- )
72
- }
73
-
74
- console.debug(
75
- 'Applicable driver not found; attempting to install with Selenium Manager (Beta)'
76
- )
77
-
78
70
  let args = ['--browser', options.getBrowserName(), '--output', 'json']
79
71
 
80
72
  if (options.getBrowserVersion() && options.getBrowserVersion() !== '') {
@@ -116,6 +108,7 @@ function driverLocation(options) {
116
108
  if (spawnResult.stdout.toString()) {
117
109
  try {
118
110
  output = JSON.parse(spawnResult.stdout.toString())
111
+ logOutput(output)
119
112
  errorMessage = output.result.message
120
113
  } catch (e) {
121
114
  errorMessage = e.toString()
@@ -133,13 +126,22 @@ function driverLocation(options) {
133
126
  )
134
127
  }
135
128
 
129
+ logOutput(output)
130
+ return {
131
+ driverPath: output.result.driver_path,
132
+ browserPath: output.result.browser_path,
133
+ }
134
+ }
135
+
136
+ function logOutput (output) {
136
137
  for (const key in output.logs) {
137
138
  if (output.logs[key].level === 'WARN') {
138
139
  console.warn(`${output.logs[key].message}`)
139
140
  }
141
+ if (['DEBUG', 'INFO'].includes(output.logs[key].level)) {
142
+ console.debug(`${output.logs[key].message}`)
143
+ }
140
144
  }
141
-
142
- return output.result.message
143
145
  }
144
146
 
145
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
- let exe = opt_exe || locateSynchronously()
109
- super(exe)
100
+ super(opt_exe)
110
101
  this.setLoopback(true)
111
102
  }
112
103
  }
@@ -157,7 +148,7 @@ class Driver extends chromium.Driver {
157
148
  static createSession(opt_config, opt_serviceExecutor) {
158
149
  let caps = opt_config || new Options()
159
150
  return /** @type {!Driver} */ (
160
- super.createSession(caps, opt_serviceExecutor)
151
+ super.createSession(caps, opt_serviceExecutor, 'ms', EDGE_CAPABILITY_KEY)
161
152
  )
162
153
  }
163
154
 
@@ -177,19 +168,8 @@ class Driver extends chromium.Driver {
177
168
  setFileDetector() {}
178
169
  }
179
170
 
180
- /**
181
- * _Synchronously_ attempts to locate the chromedriver executable on the current
182
- * system.
183
- *
184
- * @return {?string} the located executable, or `null`.
185
- */
186
- function locateSynchronously() {
187
- return io.findInPath(EDGEDRIVER_CHROMIUM_EXE, true)
188
- }
189
-
190
171
  Options.prototype.BROWSER_NAME_VALUE = Browser.EDGE
191
- Options.prototype.CAPABILITY_KEY = 'ms:edgeOptions'
192
- Driver.prototype.VENDOR_CAPABILITY_PREFIX = 'ms'
172
+ Options.prototype.CAPABILITY_KEY = EDGE_CAPABILITY_KEY
193
173
 
194
174
  // PUBLIC API
195
175
 
@@ -197,5 +177,4 @@ module.exports = {
197
177
  Driver,
198
178
  Options,
199
179
  ServiceBuilder,
200
- locateSynchronously,
201
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('moz:firefoxOptions')
267
+ let options = this.get(FIREFOX_CAPABILITY_KEY)
267
268
  if (!options) {
268
269
  options = {}
269
- this.set('moz:firefoxOptions', options)
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 || findGeckoDriver())
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
- opt_executor.setExecutable(getPath(opt_executor, opt_config))
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
- service.setExecutable(getPath(service, opt_config))
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 = locateSynchronously()
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 || IEDRIVER_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(service, options))
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/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(this.VENDOR_COMMAND_PREFIX + ':chromeOptions') ||
1242
- caps['map_'].get(this.VENDOR_CAPABILITY_PREFIX + ':edgeOptions') ||
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.10.0",
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.41.0",
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": "^4.2.1",
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": "^2.8.8",
39
+ "prettier": "^3.0.0",
40
40
  "serve-index": "^1.9.1",
41
- "sinon": "^15.1.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.execSync(
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 || findSafariDriver())
42
+ super(opt_exe)
70
43
  this.setLoopback(true) // Required.
71
44
  }
72
45
  }
73
46
 
74
- const OPTIONS_CAPABILITY_KEY = 'safari.options'
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.locateSynchronously, Browser.CHROME],
121
- [edge.locateSynchronously, Browser.EDGE],
122
- [firefox.locateSynchronously, Browser.FIREFOX],
123
- [ie.locateSynchronously, Browser.INTERNET_EXPLORER],
124
- [safari.locateSynchronously, Browser.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 fn = pair[0]
130
+ const driverPath = pair[0]
130
131
  const name = pair[1]
131
132
  const capabilities = pair[2]
132
- if (fn()) {
133
+ if (driverPath.length > 0) {
133
134
  info(`... located ${name}`)
134
135
  availableBrowsers.push({ name, capabilities })
135
136
  }