selenium-webdriver 4.0.0-beta.4 → 4.0.0-rc-1

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 CHANGED
@@ -1,3 +1,22 @@
1
+ ## v4.0.0-rc-1
2
+
3
+ * Deprecates withCapabilities method and removes tests (#9701)
4
+ * expose `withLocator` method at the top level
5
+ * Enables Mobile feature for Firefox (Still need to expand this to chromium based browsers)
6
+
7
+ * Add the ability to do Relative Locators with all By types. Fixes #9559
8
+ * Add default Opera capabilities. Fixes #9654
9
+ * Add support for ChromeDriver `--enable-chrome-logs` (#9575) [Author: Mark Stacey]
10
+
11
+ The `--enable-chrome-logs` ChromeDriver option can now be enabled using
12
+ the Chromium (or Chrome) ServiceBuilder, similarly to the other options
13
+ provided by ChromeDriver.
14
+
15
+ * Add the debuggerAddress option to chromium.js (#9561) [Author: Brandon Walderman]
16
+ * Adds http client options (#9638)[Author: Dharin Shah]
17
+ * Updating edge.js to extend chromium.driver (fixes #9626)
18
+
19
+
1
20
  ## v4.0.0-beta.4
2
21
 
3
22
  * Add windowTypes option support for ChromiumDriver (#7897)
package/README.md CHANGED
@@ -223,7 +223,9 @@ under the License.
223
223
  [edge]: http://go.microsoft.com/fwlink/?LinkId=619687
224
224
  [geckodriver]: https://github.com/mozilla/geckodriver/releases/
225
225
  [reduction]: http://www.webkit.org/quality/reduction.html
226
- [release]: http://selenium-release.storage.googleapis.com/index.html
226
+
227
+ [release]: https://www.selenium.dev/downloads/
228
+
227
229
  [users]: https://groups.google.com/forum/#!forum/selenium-users
228
230
  [safaridriver]: https://developer.apple.com/library/prerelease/content/releasenotes/General/WhatsNewInSafari/Articles/Safari_10_0.html#//apple_ref/doc/uid/TP40014305-CH11-DontLinkElementID_28
229
- [operadriver]: https://github.com/operasoftware/operachromiumdriver/releases
231
+ [operadriver]: https://github.com/operasoftware/operachromiumdriver/releases
package/chrome.js CHANGED
@@ -236,10 +236,9 @@ class Driver extends chromium.Driver {
236
236
  */
237
237
  static createSession(opt_config, opt_serviceExecutor) {
238
238
  let caps = opt_config || new Options()
239
- return /** @type {!Driver} */ (super.createSession(
240
- caps,
241
- opt_serviceExecutor
242
- ))
239
+ return /** @type {!Driver} */ (
240
+ super.createSession(caps, opt_serviceExecutor)
241
+ )
243
242
  }
244
243
  }
245
244
 
package/chromium.js CHANGED
@@ -213,6 +213,14 @@ class ServiceBuilder extends remote.DriverService.Builder {
213
213
  return this.addArguments('--log-path=' + path)
214
214
  }
215
215
 
216
+ /**
217
+ * Enables Chrome logging.
218
+ * @returns {!ServiceBuilder} A self reference.
219
+ */
220
+ enableChromeLogging() {
221
+ return this.addArguments('--enable-chrome-logs');
222
+ }
223
+
216
224
  /**
217
225
  * Enables verbose logging.
218
226
  * @return {!ServiceBuilder} A self reference.
@@ -275,6 +283,19 @@ class Options extends Capabilities {
275
283
  return this
276
284
  }
277
285
 
286
+ /**
287
+ * Sets the address of a Chromium remote debugging server to connect to.
288
+ * Address should be of the form "{hostname|IP address}:port"
289
+ * (e.g. "localhost:9222").
290
+ *
291
+ * @param {string} address The address to connect to.
292
+ * @return {!Options} A self reference.
293
+ */
294
+ debuggerAddress(address) {
295
+ this.options_.debuggerAddress = address;
296
+ return this
297
+ }
298
+
278
299
  /**
279
300
  * Configures the driver to start the browser in headless mode.
280
301
  *
@@ -557,14 +578,13 @@ class Options extends Capabilities {
557
578
  * @return {!Options} A self reference.
558
579
  */
559
580
  windowTypes(...args) {
560
- let windowTypes = (this.options_.windowTypes || []).concat(...args);
581
+ let windowTypes = (this.options_.windowTypes || []).concat(...args)
561
582
  if (windowTypes.length) {
562
- this.options_.windowTypes = windowTypes;
583
+ this.options_.windowTypes = windowTypes
563
584
  }
564
- return this;
585
+ return this
565
586
  }
566
587
 
567
-
568
588
  /**
569
589
  * Converts this instance to its JSON wire protocol representation. Note this
570
590
  * function is an implementation not intended for general use.
@@ -581,7 +601,7 @@ class Options extends Capabilities {
581
601
  return extension.toString('base64')
582
602
  }
583
603
  return io
584
- .read(/** @type {string} */(extension))
604
+ .read(/** @type {string} */ (extension))
585
605
  .then((buffer) => buffer.toString('base64'))
586
606
  })
587
607
  }
@@ -634,7 +654,7 @@ class Driver extends webdriver.WebDriver {
634
654
  * implementation.
635
655
  * @override
636
656
  */
637
- setFileDetector() { }
657
+ setFileDetector() {}
638
658
 
639
659
  /**
640
660
  * Schedules a command to launch Chrome App with given ID.
package/edge.js CHANGED
@@ -80,8 +80,6 @@
80
80
  const { Browser } = require('./lib/capabilities')
81
81
  const io = require('./io')
82
82
  const chromium = require('./chromium')
83
- const http = require('./http')
84
- const webdriver = require('./lib/webdriver')
85
83
 
86
84
  /**
87
85
  * Name of the EdgeDriver executable.
@@ -111,10 +109,10 @@ class ServiceBuilder extends chromium.ServiceBuilder {
111
109
  let exe = opt_exe || locateSynchronously()
112
110
  if (!exe) {
113
111
  throw Error(
114
- `The WebDriver for Edge could not be found on the current PATH. Please download the `+
115
- `latest version of ${EDGEDRIVER_CHROMIUM_EXE} from `+
116
- `https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/ `+
117
- `and ensure it can be found on your PATH.`
112
+ `The WebDriver for Edge could not be found on the current PATH. Please download the ` +
113
+ `latest version of ${EDGEDRIVER_CHROMIUM_EXE} from ` +
114
+ `https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/ ` +
115
+ `and ensure it can be found on your PATH.`
118
116
  )
119
117
  }
120
118
  super(exe)
@@ -143,24 +141,20 @@ class Options extends chromium.Options {
143
141
  /**
144
142
  * Creates a new WebDriver client for Microsoft's Edge.
145
143
  */
146
- class Driver extends webdriver.WebDriver {
144
+ class Driver extends chromium.Driver {
147
145
  /**
148
146
  * Creates a new browser session for Microsoft's Edge browser.
149
147
  *
150
- * @param {(Capabilities|Options)=} options The configuration options.
151
- * @param {remote.DriverService=} opt_service The service to use; will create
148
+ * @param {(Capabilities|Options)=} opt_config The configuration options.
149
+ * @param {remote.DriverService=} opt_serviceExecutor The service to use; will create
152
150
  * a new Legacy or Chromium service based on {@linkplain Options} by default.
153
151
  * @return {!Driver} A new driver instance.
154
152
  */
155
- static createSession(options, opt_service) {
156
- options = options || new Options()
157
- let service = opt_service || getDefaultService()
158
- let client = service.start().then((url) => new http.HttpClient(url))
159
- let executor = new http.Executor(client)
160
-
161
- return /** @type {!Driver} */ (super.createSession(executor, options, () =>
162
- service.kill()
163
- ))
153
+ static createSession(opt_config, opt_serviceExecutor) {
154
+ let caps = opt_config || new Options()
155
+ return /** @type {!Driver} */ (
156
+ super.createSession(caps, opt_serviceExecutor)
157
+ )
164
158
  }
165
159
 
166
160
  /**
@@ -180,7 +174,7 @@ function setDefaultService(service) {
180
174
  if (defaultService && defaultService.isRunning()) {
181
175
  throw Error(
182
176
  'The previously configured EdgeDriver service is still running. ' +
183
- 'You must shut it down before you may adjust its configuration.'
177
+ 'You must shut it down before you may adjust its configuration.'
184
178
  )
185
179
  }
186
180
  defaultService = service
@@ -199,7 +193,6 @@ function getDefaultService() {
199
193
  return defaultService
200
194
  }
201
195
 
202
-
203
196
  /**
204
197
  * _Synchronously_ attempts to locate the chromedriver executable on the current
205
198
  * system.
@@ -213,6 +206,7 @@ function locateSynchronously() {
213
206
  Options.prototype.BROWSER_NAME_VALUE = Browser.EDGE
214
207
  Options.prototype.CAPABILITY_KEY = 'ms:edgeOptions'
215
208
  Driver.prototype.VENDOR_CAPABILITY_PREFIX = 'ms'
209
+ Driver.getDefaultService = getDefaultService
216
210
 
217
211
  // PUBLIC API
218
212
 
package/firefox.js CHANGED
@@ -124,7 +124,6 @@ const io = require('./io')
124
124
  const remote = require('./remote')
125
125
  const webdriver = require('./lib/webdriver')
126
126
  const zip = require('./io/zip')
127
- const cdp = require('./devtools/CDPConnection')
128
127
  const { Browser, Capabilities } = require('./lib/capabilities')
129
128
  const { Zip } = require('./io/zip')
130
129
 
@@ -394,6 +393,24 @@ class Options extends Capabilities {
394
393
  }
395
394
  throw TypeError('binary must be a string path or Channel object')
396
395
  }
396
+
397
+ /**
398
+ * Enables Mobile start up features
399
+ *
400
+ * @param {string} androidPackage The package to use
401
+ * @return {!Options} A self reference
402
+ */
403
+ enableMobile(androidPackage = "org.mozilla.firefox", androidActivity = null, deviceSerial = null) {
404
+ this.firefoxOptions_().androidPackage = androidPackage
405
+
406
+ if (androidActivity) {
407
+ this.firefoxOptions_().androidActivity = androidActivity
408
+ }
409
+ if (deviceSerial) {
410
+ this.firefoxOptions_().deviceSerial = deviceSerial
411
+ }
412
+ return this
413
+ }
397
414
  }
398
415
 
399
416
  /**
package/http/index.js CHANGED
@@ -77,8 +77,9 @@ class HttpClient {
77
77
  * Defaults to `http.globalAgent`.
78
78
  * @param {?string=} opt_proxy The proxy to use for the connection to the
79
79
  * server. Default is to use no proxy.
80
+ * @param {?Object.<string,Object>} client_options
80
81
  */
81
- constructor(serverUrl, opt_agent, opt_proxy) {
82
+ constructor(serverUrl, opt_agent, opt_proxy, client_options = {}) {
82
83
  /** @private {http.Agent} */
83
84
  this.agent_ = opt_agent || null
84
85
 
@@ -88,12 +89,33 @@ class HttpClient {
88
89
  */
89
90
  this.options_ = getRequestOptions(serverUrl)
90
91
 
92
+ /**
93
+ * client options, header overrides
94
+ */
95
+ this.client_options = client_options
96
+
97
+ /**
98
+ * sets keep-alive for the agent
99
+ * see https://stackoverflow.com/a/58332910
100
+ */
101
+ this.keepAlive = this.client_options['keep-alive']
102
+
91
103
  /**
92
104
  * @private {?RequestOptions}
93
105
  */
94
106
  this.proxyOptions_ = opt_proxy ? getRequestOptions(opt_proxy) : null
95
107
  }
96
108
 
109
+ get keepAlive() {
110
+ return this.agent_.keepAlive
111
+ }
112
+
113
+ set keepAlive(value) {
114
+ if (value === 'true' || value === true) {
115
+ this.agent_.keepAlive = true
116
+ }
117
+ }
118
+
97
119
  /** @override */
98
120
  send(httpRequest) {
99
121
  let data
@@ -106,7 +128,7 @@ class HttpClient {
106
128
  })
107
129
  }
108
130
 
109
- headers['User-Agent'] = USER_AGENT
131
+ headers['User-Agent'] = this.client_options['user-agent'] || USER_AGENT
110
132
  headers['Content-Length'] = 0
111
133
  if (httpRequest.method == 'POST' || httpRequest.method == 'PUT') {
112
134
  data = JSON.stringify(httpRequest.data)
@@ -232,7 +254,7 @@ function sendRequest(options, onOk, onError, opt_data, opt_proxy, opt_retries) {
232
254
  hash: location.hash,
233
255
  headers: {
234
256
  Accept: 'application/json; charset=utf-8',
235
- 'User-Agent': USER_AGENT,
257
+ 'User-Agent': options.headers['User-Agent'] || USER_AGENT,
236
258
  },
237
259
  },
238
260
  onOk,
package/ie.js CHANGED
@@ -18,7 +18,7 @@
18
18
  /**
19
19
  * @fileoverview Defines a {@linkplain Driver WebDriver} client for Microsoft's
20
20
  * Internet Explorer. Before using the IEDriver, you must download the latest
21
- * [IEDriverServer](http://selenium-release.storage.googleapis.com/index.html)
21
+ * [IEDriverServer](https://www.selenium.dev/downloads/)
22
22
  * and place it on your
23
23
  * [PATH](http://en.wikipedia.org/wiki/PATH_%28variable%29). You must also apply
24
24
  * the system configuration outlined on the Selenium project
@@ -370,7 +370,7 @@ class Options extends Capabilities {
370
370
  behavior !== SCROLL_BEHAVIOUR.TOP &&
371
371
  behavior !== SCROLL_BEHAVIOUR.BOTTOM
372
372
  ) {
373
- throw new error.InvalidArgumentError(`Element Scroll Behavior out of range.
373
+ throw new error.InvalidArgumentError(`Element Scroll Behavior out of range.
374
374
  It should be either ${SCROLL_BEHAVIOUR.TOP} or ${SCROLL_BEHAVIOUR.BOTTOM}`)
375
375
  }
376
376
  this.options_[Key.ELEMENT_SCROLL_BEHAVIOR] = behavior
@@ -402,9 +402,9 @@ function createServiceFromCapabilities(capabilities) {
402
402
  if (!exe || !fs.existsSync(exe)) {
403
403
  throw Error(
404
404
  `${IEDRIVER_EXE} could not be found on the current PATH. Please ` +
405
- `download the latest version of ${IEDRIVER_EXE} from ` +
406
- 'http://selenium-release.storage.googleapis.com/index.html and ' +
407
- 'ensure it can be found on your system PATH.'
405
+ `download the latest version of ${IEDRIVER_EXE} from ` +
406
+ 'https://www.selenium.dev/downloads/ and ' +
407
+ 'ensure it can be found on your system PATH.'
408
408
  )
409
409
  }
410
410
 
@@ -478,9 +478,9 @@ class Driver extends webdriver.WebDriver {
478
478
  let client = service.start().then((url) => new http.HttpClient(url))
479
479
  let executor = new http.Executor(client)
480
480
 
481
- return /** @type {!Driver} */ (super.createSession(executor, options, () =>
482
- service.kill()
483
- ))
481
+ return /** @type {!Driver} */ (
482
+ super.createSession(executor, options, () => service.kill())
483
+ )
484
484
  }
485
485
 
486
486
  /**
package/index.js CHANGED
@@ -103,7 +103,7 @@ function ensureFileDetectorsAreEnabled(ctor) {
103
103
  */
104
104
  class ThenableWebDriver {
105
105
  /** @param {...?} args */
106
- static createSession(...args) {} // eslint-disable-line
106
+ static createSession(...args) { } // eslint-disable-line
107
107
  }
108
108
 
109
109
  /**
@@ -162,7 +162,7 @@ function createDriver(ctor, ...args) {
162
162
  * option always takes precedence over {@code SELENIUM_SERVER_JAR}.
163
163
  *
164
164
  * - {@code SELENIUM_SERVER_JAR}: defines the path to the
165
- * <a href="http://selenium-release.storage.googleapis.com/index.html">
165
+ * <a href="https://www.selenium.dev/downloads/">
166
166
  * standalone Selenium server</a> jar to use. The server will be started the
167
167
  * first time a WebDriver instance and be killed when the process exits.
168
168
  *
@@ -318,6 +318,8 @@ class Builder {
318
318
  }
319
319
 
320
320
  /**
321
+ * @deprecated Since Selenium 4.0 withCapabilities is deprecated, use set*Options instead where * is the browser(eg setChromeOptions)
322
+ *
321
323
  * Sets the desired capabilities when requesting a new session. This will
322
324
  * overwrite any previously set capabilities.
323
325
  * @param {!(Object|Capabilities)} capabilities The desired capabilities for
@@ -615,7 +617,7 @@ class Builder {
615
617
  if (typeof browser !== 'string') {
616
618
  throw TypeError(
617
619
  `Target browser must be a string, but is <${typeof browser}>;` +
618
- ' did you forget to call forBrowser()?'
620
+ ' did you forget to call forBrowser()?'
619
621
  )
620
622
  }
621
623
 
@@ -736,8 +738,8 @@ class Builder {
736
738
  default:
737
739
  throw new Error(
738
740
  'Do not know how to build driver: ' +
739
- browser +
740
- '; did you forget to call usingServer(url)?'
741
+ browser +
742
+ '; did you forget to call usingServer(url)?'
741
743
  )
742
744
  }
743
745
  }
@@ -793,9 +795,9 @@ function checkOptions(caps, key, optionType, setMethod) {
793
795
  if (val instanceof optionType) {
794
796
  throw new error.InvalidArgumentError(
795
797
  'Options class extends Capabilities and should not be set as key ' +
796
- `"${key}"; set browser-specific options with ` +
797
- `Builder.${setMethod}(). For more information, see the ` +
798
- 'documentation attached to the function that threw this error'
798
+ `"${key}"; set browser-specific options with ` +
799
+ `Builder.${setMethod}(). For more information, see the ` +
800
+ 'documentation attached to the function that threw this error'
799
801
  )
800
802
  }
801
803
  }
@@ -807,6 +809,7 @@ exports.Builder = Builder
807
809
  exports.Button = input.Button
808
810
  exports.By = by.By
809
811
  exports.withTagName = by.withTagName
812
+ exports.withLocator = by.withLocator
810
813
  exports.Capabilities = capabilities.Capabilities
811
814
  exports.Capability = capabilities.Capability
812
815
  exports.Condition = webdriver.Condition
package/io/exec.js CHANGED
@@ -76,7 +76,8 @@ class Result {
76
76
  }
77
77
  }
78
78
 
79
- const COMMAND_RESULT = /** !WeakMap<!Command, !Promise<!Result>> */ new WeakMap()
79
+ const COMMAND_RESULT =
80
+ /** !WeakMap<!Command, !Promise<!Result>> */ new WeakMap()
80
81
  const KILL_HOOK = /** !WeakMap<!Command, function(string)> */ new WeakMap()
81
82
 
82
83
  /**
package/lib/by.js CHANGED
@@ -258,8 +258,36 @@ class By {
258
258
  }
259
259
  }
260
260
 
261
+ /**
262
+ * Start Searching for relative objects using the value returned from
263
+ * `By.tagName()`.
264
+ *
265
+ * Note: this method will likely be removed in the future please use
266
+ * `locateWith`.
267
+ * @param {By} The value returned from calling By.tagName()
268
+ * @returns
269
+ */
261
270
  function withTagName(tagName) {
262
- return new RelativeBy(tagName)
271
+ return new RelativeBy({ 'css selector': tagName })
272
+ }
273
+
274
+ /**
275
+ * Start searching for relative objects using search criteria with By.
276
+ * @param {string} A By map that shows how to find the initial element
277
+ * @returns {RelativeBy}
278
+ */
279
+ function locateWith(by) {
280
+ return new RelativeBy(getLocator(by));
281
+ }
282
+
283
+ function getLocator(locatorOrElement) {
284
+ let toFind
285
+ if (locatorOrElement instanceof By) {
286
+ toFind = locatorOrElement.toObject()
287
+ } else {
288
+ toFind = locatorOrElement
289
+ }
290
+ return toFind
263
291
  }
264
292
 
265
293
  /**
@@ -269,11 +297,11 @@ function withTagName(tagName) {
269
297
  */
270
298
  class RelativeBy {
271
299
  /**
272
- * @param {string} tagName
300
+ * @param {By} findDetails
273
301
  * @param {Array<Object>} filters
274
302
  */
275
- constructor(tagName, filters = null) {
276
- this.root = tagName
303
+ constructor(findDetails, filters = null) {
304
+ this.root = findDetails
277
305
  this.filters = filters || []
278
306
  }
279
307
 
@@ -285,7 +313,7 @@ class RelativeBy {
285
313
  above(locatorOrElement) {
286
314
  this.filters.push({
287
315
  kind: 'above',
288
- args: [this.getLocator(locatorOrElement)],
316
+ args: [getLocator(locatorOrElement)],
289
317
  })
290
318
  return this
291
319
  }
@@ -298,7 +326,7 @@ class RelativeBy {
298
326
  below(locatorOrElement) {
299
327
  this.filters.push({
300
328
  kind: 'below',
301
- args: [this.getLocator(locatorOrElement)],
329
+ args: [getLocator(locatorOrElement)],
302
330
  })
303
331
  return this
304
332
  }
@@ -311,7 +339,7 @@ class RelativeBy {
311
339
  toLeftOf(locatorOrElement) {
312
340
  this.filters.push({
313
341
  kind: 'left',
314
- args: [this.getLocator(locatorOrElement)],
342
+ args: [getLocator(locatorOrElement)],
315
343
  })
316
344
  return this
317
345
  }
@@ -324,7 +352,7 @@ class RelativeBy {
324
352
  toRightOf(locatorOrElement) {
325
353
  this.filters.push({
326
354
  kind: 'right',
327
- args: [this.getLocator(locatorOrElement)],
355
+ args: [getLocator(locatorOrElement)],
328
356
  })
329
357
  return this
330
358
  }
@@ -337,7 +365,7 @@ class RelativeBy {
337
365
  near(locatorOrElement) {
338
366
  this.filters.push({
339
367
  kind: 'near',
340
- args: [this.getLocator(locatorOrElement)],
368
+ args: [getLocator(locatorOrElement)],
341
369
  })
342
370
  return this
343
371
  }
@@ -350,22 +378,12 @@ class RelativeBy {
350
378
  marshall() {
351
379
  return {
352
380
  relative: {
353
- root: { 'css selector': this.root },
381
+ root: this.root,
354
382
  filters: this.filters,
355
383
  },
356
384
  }
357
385
  }
358
386
 
359
- getLocator(locatorOrElement) {
360
- let toFind
361
- if (locatorOrElement instanceof By) {
362
- toFind = locatorOrElement.toObject()
363
- } else {
364
- toFind = locatorOrElement
365
- }
366
- return toFind
367
- }
368
-
369
387
  /** @override */
370
388
  toString() {
371
389
  // The static By.name() overrides this.constructor.name. Shame...
@@ -411,5 +429,6 @@ module.exports = {
411
429
  By: By,
412
430
  RelativeBy: RelativeBy,
413
431
  withTagName: withTagName,
432
+ locateWith: locateWith,
414
433
  checkedLocator: check,
415
434
  }
@@ -263,7 +263,9 @@ class Capabilities {
263
263
  * @return {!Capabilities} A basic set of capabilities for Firefox.
264
264
  */
265
265
  static firefox() {
266
- return new Capabilities().setBrowserName(Browser.FIREFOX).set("moz:debuggerAddress", true)
266
+ return new Capabilities()
267
+ .setBrowserName(Browser.FIREFOX)
268
+ .set('moz:debuggerAddress', true)
267
269
  }
268
270
 
269
271
  /**
@@ -280,6 +282,13 @@ class Capabilities {
280
282
  return new Capabilities().setBrowserName(Browser.SAFARI)
281
283
  }
282
284
 
285
+ /**
286
+ * @return {!Capabilities} A basic set of capabilities for Opera
287
+ */
288
+ static opera() {
289
+ return new Capabilities().setBrowserName(Browser.OPERA)
290
+ }
291
+
283
292
  /**
284
293
  * @return {!Object<string, ?>} The JSON representation of this instance.
285
294
  * Note, the returned object may contain nested promised values.
package/lib/http.js CHANGED
@@ -490,7 +490,8 @@ function buildRequest(customCommands, w3c, command) {
490
490
  }
491
491
  }
492
492
 
493
- const CLIENTS = /** !WeakMap<!Executor, !(Client|IThenable<!Client>)> */ new WeakMap()
493
+ const CLIENTS =
494
+ /** !WeakMap<!Executor, !(Client|IThenable<!Client>)> */ new WeakMap()
494
495
 
495
496
  /**
496
497
  * A command executor that communicates with the server using JSON over HTTP.
package/lib/input.js CHANGED
@@ -20,14 +20,8 @@
20
20
  /**
21
21
  * @fileoverview Defines types related to user input with the WebDriver API.
22
22
  */
23
-
24
- const promise = require('./promise')
25
23
  const { Command, Name } = require('./command')
26
- const {
27
- InvalidArgumentError,
28
- UnknownCommandError,
29
- UnsupportedOperationError,
30
- } = require('./error')
24
+ const { InvalidArgumentError } = require('./error')
31
25
 
32
26
  /**
33
27
  * Enumeration of the buttons used in the advanced interactions API.
@@ -503,7 +497,6 @@ class Actions {
503
497
  * sequence (see class description for details).
504
498
  */
505
499
  constructor(executor, { async = false } = {}) {
506
-
507
500
  /** @private @const */
508
501
  this.executor_ = executor
509
502
 
@@ -882,13 +875,9 @@ class Actions {
882
875
  return Promise.resolve()
883
876
  }
884
877
 
885
- try {
886
- await this.executor_.execute(
887
- new Command(Name.ACTIONS).setParameter('actions', _actions)
888
- )
889
- } catch (ex) {
890
- throw ex
891
- }
878
+ await this.executor_.execute(
879
+ new Command(Name.ACTIONS).setParameter('actions', _actions)
880
+ )
892
881
  }
893
882
  }
894
883
 
package/lib/until.js CHANGED
@@ -137,14 +137,13 @@ exports.alertIsPresent = function alertIsPresent() {
137
137
  * @return {!Condition<boolean>} The new condition.
138
138
  */
139
139
  exports.titleIs = function titleIs(title) {
140
- return new Condition(
141
- 'for title to be ' + JSON.stringify(title),
142
- function (driver) {
143
- return driver.getTitle().then(function (t) {
144
- return t === title
145
- })
146
- }
147
- )
140
+ return new Condition('for title to be ' + JSON.stringify(title), function (
141
+ driver
142
+ ) {
143
+ return driver.getTitle().then(function (t) {
144
+ return t === title
145
+ })
146
+ })
148
147
  }
149
148
 
150
149
  /**
@@ -189,14 +188,13 @@ exports.titleMatches = function titleMatches(regex) {
189
188
  * @return {!Condition<boolean>} The new condition.
190
189
  */
191
190
  exports.urlIs = function urlIs(url) {
192
- return new Condition(
193
- 'for URL to be ' + JSON.stringify(url),
194
- function (driver) {
195
- return driver.getCurrentUrl().then(function (u) {
196
- return u === url
197
- })
198
- }
199
- )
191
+ return new Condition('for URL to be ' + JSON.stringify(url), function (
192
+ driver
193
+ ) {
194
+ return driver.getCurrentUrl().then(function (u) {
195
+ return u === url
196
+ })
197
+ })
200
198
  }
201
199
 
202
200
  /**
package/lib/webdriver.js CHANGED
@@ -258,18 +258,18 @@ class IWebDriver {
258
258
  /**
259
259
  * @return {!command.Executor} The command executor used by this instance.
260
260
  */
261
- getExecutor() {}
261
+ getExecutor() { }
262
262
 
263
263
  /**
264
264
  * @return {!Promise<!Session>} A promise for this client's session.
265
265
  */
266
- getSession() {}
266
+ getSession() { }
267
267
 
268
268
  /**
269
269
  * @return {!Promise<!Capabilities>} A promise that will resolve with
270
270
  * the this instance's capabilities.
271
271
  */
272
- getCapabilities() {}
272
+ getCapabilities() { }
273
273
 
274
274
  /**
275
275
  * Terminates the browser session. After calling quit, this instance will be
@@ -279,7 +279,7 @@ class IWebDriver {
279
279
  * @return {!Promise<void>} A promise that will be resolved when the
280
280
  * command has completed.
281
281
  */
282
- quit() {}
282
+ quit() { }
283
283
 
284
284
  /**
285
285
  * Creates a new action sequence using this driver. The sequence will not be
@@ -458,7 +458,7 @@ class IWebDriver {
458
458
  timeout = undefined, // eslint-disable-line
459
459
  message = undefined, // eslint-disable-line
460
460
  pollTimeout = undefined // eslint-disable-line
461
- ) {}
461
+ ) { }
462
462
 
463
463
  /**
464
464
  * Makes the driver sleep for the given amount of time.
@@ -475,7 +475,7 @@ class IWebDriver {
475
475
  * @return {!Promise<string>} A promise that will be resolved with the current
476
476
  * window handle.
477
477
  */
478
- getWindowHandle() {}
478
+ getWindowHandle() { }
479
479
 
480
480
  /**
481
481
  * Retrieves a list of all available window handles.
@@ -483,7 +483,7 @@ class IWebDriver {
483
483
  * @return {!Promise<!Array<string>>} A promise that will be resolved with an
484
484
  * array of window handles.
485
485
  */
486
- getAllWindowHandles() {}
486
+ getAllWindowHandles() { }
487
487
 
488
488
  /**
489
489
  * Retrieves the current page's source. The returned source is a representation
@@ -493,7 +493,7 @@ class IWebDriver {
493
493
  * @return {!Promise<string>} A promise that will be resolved with the current
494
494
  * page source.
495
495
  */
496
- getPageSource() {}
496
+ getPageSource() { }
497
497
 
498
498
  /**
499
499
  * Closes the current window.
@@ -501,7 +501,7 @@ class IWebDriver {
501
501
  * @return {!Promise<void>} A promise that will be resolved when this command
502
502
  * has completed.
503
503
  */
504
- close() {}
504
+ close() { }
505
505
 
506
506
  /**
507
507
  * Navigates to the given URL.
@@ -518,7 +518,7 @@ class IWebDriver {
518
518
  * @return {!Promise<string>} A promise that will be resolved with the
519
519
  * current URL.
520
520
  */
521
- getCurrentUrl() {}
521
+ getCurrentUrl() { }
522
522
 
523
523
  /**
524
524
  * Retrieves the current page title.
@@ -526,7 +526,7 @@ class IWebDriver {
526
526
  * @return {!Promise<string>} A promise that will be resolved with the current
527
527
  * page's title.
528
528
  */
529
- getTitle() {}
529
+ getTitle() { }
530
530
 
531
531
  /**
532
532
  * Locates an element on the page. If the element cannot be found, a
@@ -590,23 +590,23 @@ class IWebDriver {
590
590
  * @return {!Promise<string>} A promise that will be resolved to the
591
591
  * screenshot as a base-64 encoded PNG.
592
592
  */
593
- takeScreenshot() {}
593
+ takeScreenshot() { }
594
594
 
595
595
  /**
596
596
  * @return {!Options} The options interface for this instance.
597
597
  */
598
- manage() {}
598
+ manage() { }
599
599
 
600
600
  /**
601
601
  * @return {!Navigation} The navigation interface for this instance.
602
602
  */
603
- navigate() {}
603
+ navigate() { }
604
604
 
605
605
  /**
606
606
  * @return {!TargetLocator} The target locator interface for this
607
607
  * instance.
608
608
  */
609
- switchTo() {}
609
+ switchTo() { }
610
610
 
611
611
  /**
612
612
  *
@@ -665,7 +665,7 @@ class WebDriver {
665
665
  // If session is a rejected promise, add a no-op rejection handler.
666
666
  // This effectively hides setup errors until users attempt to interact
667
667
  // with the session.
668
- this.session_.catch(function () {})
668
+ this.session_.catch(function () { })
669
669
 
670
670
  /** @private {!command.Executor} */
671
671
  this.executor_ = executor
@@ -761,12 +761,12 @@ class WebDriver {
761
761
  this.session_ = Promise.reject(
762
762
  new error.NoSuchSessionError(
763
763
  'This driver instance does not have a valid session ID ' +
764
- '(did you call WebDriver.quit()?) and may no longer be used.'
764
+ '(did you call WebDriver.quit()?) and may no longer be used.'
765
765
  )
766
766
  )
767
767
 
768
768
  // Only want the session rejection to bubble if accessed.
769
- this.session_.catch(function () {})
769
+ this.session_.catch(function () { })
770
770
 
771
771
  if (this.onQuit_) {
772
772
  return this.onQuit_.call(void 0)
@@ -827,18 +827,15 @@ class WebDriver {
827
827
  let timeoutMessage = resolveWaitMessage(message)
828
828
  reject(
829
829
  new error.TimeoutError(
830
- `${timeoutMessage}Timed out waiting for promise to resolve after ${
831
- Date.now() - start
830
+ `${timeoutMessage}Timed out waiting for promise to resolve after ${Date.now() - start
832
831
  }ms`
833
832
  )
834
833
  )
835
834
  } catch (ex) {
836
835
  reject(
837
836
  new error.TimeoutError(
838
- `${
839
- ex.message
840
- }\nTimed out waiting for promise to resolve after ${
841
- Date.now() - start
837
+ `${ex.message
838
+ }\nTimed out waiting for promise to resolve after ${Date.now() - start
842
839
  }ms`
843
840
  )
844
841
  )
@@ -868,7 +865,7 @@ class WebDriver {
868
865
  if (typeof fn !== 'function') {
869
866
  throw TypeError(
870
867
  'Wait condition must be a promise-like object, function, or a ' +
871
- 'Condition object'
868
+ 'Condition object'
872
869
  )
873
870
  }
874
871
 
@@ -920,7 +917,7 @@ class WebDriver {
920
917
  if (!(value instanceof WebElement)) {
921
918
  throw TypeError(
922
919
  'WebElementCondition did not resolve to a WebElement: ' +
923
- Object.prototype.toString.call(value)
920
+ Object.prototype.toString.call(value)
924
921
  )
925
922
  }
926
923
  return value
@@ -1732,7 +1729,7 @@ class Options {
1732
1729
  } else if (typeof value !== 'undefined') {
1733
1730
  throw TypeError(
1734
1731
  'invalid timeouts configuration:' +
1735
- ` expected "${key}" to be a number, got ${typeof value}`
1732
+ ` expected "${key}" to be a number, got ${typeof value}`
1736
1733
  )
1737
1734
  }
1738
1735
  }
@@ -1793,7 +1790,7 @@ function legacyTimeout(driver, type, ms) {
1793
1790
  *
1794
1791
  * @record
1795
1792
  */
1796
- Options.Cookie = function () {}
1793
+ Options.Cookie = function () { }
1797
1794
 
1798
1795
  /**
1799
1796
  * The name of the cookie.
@@ -2498,18 +2495,18 @@ class WebElement {
2498
2495
  */
2499
2496
  async sendKeys(...args) {
2500
2497
  let keys = []
2501
- ;(await Promise.all(args)).forEach((key) => {
2502
- let type = typeof key
2503
- if (type === 'number') {
2504
- key = String(key)
2505
- } else if (type !== 'string') {
2506
- throw TypeError('each key must be a number of string; got ' + type)
2507
- }
2498
+ ; (await Promise.all(args)).forEach((key) => {
2499
+ let type = typeof key
2500
+ if (type === 'number') {
2501
+ key = String(key)
2502
+ } else if (type !== 'string') {
2503
+ throw TypeError('each key must be a number of string; got ' + type)
2504
+ }
2508
2505
 
2509
- // The W3C protocol requires keys to be specified as an array where
2510
- // each element is a single key.
2511
- keys.push(...key.split(''))
2512
- })
2506
+ // The W3C protocol requires keys to be specified as an array where
2507
+ // each element is a single key.
2508
+ keys.push(...key.split(''))
2509
+ })
2513
2510
 
2514
2511
  if (!this.driver_.fileDetector_) {
2515
2512
  return this.execute_(
@@ -2728,18 +2725,12 @@ class WebElement {
2728
2725
  * Take a screenshot of the visible region encompassed by this element's
2729
2726
  * bounding rectangle.
2730
2727
  *
2731
- * @param {boolean=} scroll Optional argument that indicates whether the
2732
- * element should be scrolled into view before taking a screenshot.
2733
- * Defaults to false.
2734
2728
  * @return {!Promise<string>} A promise that will be
2735
2729
  * resolved to the screenshot as a base-64 encoded PNG.
2736
2730
  */
2737
- takeScreenshot(scroll = false) {
2731
+ takeScreenshot() {
2738
2732
  return this.execute_(
2739
- new command.Command(command.Name.TAKE_ELEMENT_SCREENSHOT).setParameter(
2740
- 'scroll',
2741
- scroll
2742
- )
2733
+ new command.Command(command.Name.TAKE_ELEMENT_SCREENSHOT)
2743
2734
  )
2744
2735
  }
2745
2736
  }
package/opera.js CHANGED
@@ -383,9 +383,9 @@ class Driver extends webdriver.WebDriver {
383
383
  caps = options.toCapabilities(caps)
384
384
  }
385
385
 
386
- return /** @type {!Driver} */ (super.createSession(executor, caps, () =>
387
- service.kill()
388
- ))
386
+ return /** @type {!Driver} */ (
387
+ super.createSession(executor, caps, () => service.kill())
388
+ )
389
389
  }
390
390
 
391
391
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "selenium-webdriver",
3
- "version": "4.0.0-beta.4",
3
+ "version": "4.0.0-rc-1",
4
4
  "description": "The official WebDriver JavaScript bindings from the Selenium project",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
@@ -35,7 +35,7 @@
35
35
  "eslint-plugin-node": "^11.1.0",
36
36
  "eslint-plugin-prettier": "^3.4.0",
37
37
  "express": "^4.17.1",
38
- "jasmine": "^3.6.1",
38
+ "jasmine": "^3.8.0",
39
39
  "mocha": "^8.1.0",
40
40
  "multer": "^1.4.2",
41
41
  "prettier": "^2.3.0",
package/remote/index.js CHANGED
@@ -448,7 +448,7 @@ DriverService.Builder = class {
448
448
 
449
449
  /**
450
450
  * Manages the life and death of the
451
- * <a href="http://selenium-release.storage.googleapis.com/index.html">
451
+ * <a href="https://www.selenium.dev/downloads/">
452
452
  * standalone Selenium server</a>.
453
453
  */
454
454
  class SeleniumServer extends DriverService {
@@ -562,7 +562,7 @@ SeleniumServer.Options = class {
562
562
  /**
563
563
  * A {@link webdriver.FileDetector} that may be used when running
564
564
  * against a remote
565
- * [Selenium server](http://selenium-release.storage.googleapis.com/index.html).
565
+ * [Selenium server](https://www.selenium.dev/downloads/).
566
566
  *
567
567
  * When a file path on the local machine running this script is entered with
568
568
  * {@link webdriver.WebElement#sendKeys WebElement#sendKeys}, this file detector
package/safari.js CHANGED
@@ -154,9 +154,9 @@ class Driver extends webdriver.WebDriver {
154
154
  service.start().then((url) => new http.HttpClient(url))
155
155
  )
156
156
 
157
- return /** @type {!Driver} */ (super.createSession(executor, caps, () =>
158
- service.kill()
159
- ))
157
+ return /** @type {!Driver} */ (
158
+ super.createSession(executor, caps, () => service.kill())
159
+ )
160
160
  }
161
161
  }
162
162
 
package/testing/index.js CHANGED
@@ -47,7 +47,7 @@ const { Builder } = require('../index')
47
47
  * Describes a browser targeted by a {@linkplain suite test suite}.
48
48
  * @record
49
49
  */
50
- function TargetBrowser() { }
50
+ function TargetBrowser() {}
51
51
 
52
52
  /**
53
53
  * The {@linkplain Browser name} of the targeted browser.
@@ -210,7 +210,7 @@ function init(force = false) {
210
210
  if (seleniumJar && seleniumUrl) {
211
211
  throw Error(
212
212
  'Ambiguous test configuration: both SELENIUM_REMOTE_URL' +
213
- ' && SELENIUM_SERVER_JAR environment variables are set'
213
+ ' && SELENIUM_SERVER_JAR environment variables are set'
214
214
  )
215
215
  }
216
216
 
@@ -218,8 +218,8 @@ function init(force = false) {
218
218
  if ((seleniumJar || seleniumUrl) && envBrowsers.length === 0) {
219
219
  throw Error(
220
220
  'Ambiguous test configuration: when either the SELENIUM_REMOTE_URL or' +
221
- ' SELENIUM_SERVER_JAR environment variable is set, the' +
222
- ' SELENIUM_BROWSER variable must also be set.'
221
+ ' SELENIUM_SERVER_JAR environment variable is set, the' +
222
+ ' SELENIUM_BROWSER variable must also be set.'
223
223
  )
224
224
  }
225
225
 
@@ -236,7 +236,8 @@ function init(force = false) {
236
236
  }
237
237
 
238
238
  const TARGET_MAP = /** !WeakMap<!Environment, !TargetBrowser> */ new WeakMap()
239
- const URL_MAP = /** !WeakMap<!Environment, ?(string|remote.SeleniumServer)> */ new WeakMap()
239
+ const URL_MAP =
240
+ /** !WeakMap<!Environment, ?(string|remote.SeleniumServer)> */ new WeakMap()
240
241
 
241
242
  /**
242
243
  * Defines the environment a {@linkplain suite test suite} is running against.
@@ -249,9 +250,9 @@ class Environment {
249
250
  * Selenium server to test against.
250
251
  */
251
252
  constructor(browser, url = undefined) {
252
- browser = /** @type {!TargetBrowser} */ (Object.seal(
253
- Object.assign({}, browser)
254
- ))
253
+ browser = /** @type {!TargetBrowser} */ (
254
+ Object.seal(Object.assign({}, browser))
255
+ )
255
256
 
256
257
  TARGET_MAP.set(this, browser)
257
258
  URL_MAP.set(this, url || null)
@@ -288,7 +289,6 @@ class Environment {
288
289
 
289
290
  const realBuild = builder.build
290
291
  builder.build = function () {
291
-
292
292
  builder.forBrowser(browser.name, browser.version, browser.platform)
293
293
 
294
294
  if (browser.capabilities) {
@@ -311,7 +311,7 @@ class Environment {
311
311
  * Configuration options for a {@linkplain ./index.suite test suite}.
312
312
  * @record
313
313
  */
314
- function SuiteOptions() { }
314
+ function SuiteOptions() {}
315
315
 
316
316
  /**
317
317
  * The browsers to run the test suite against.
@@ -486,8 +486,8 @@ function getTestHook(name) {
486
486
  if (type !== 'function') {
487
487
  throw TypeError(
488
488
  `Expected global.${name} to be a function, but is ${type}.` +
489
- ' This can happen if you try using this module when running with' +
490
- ' node directly instead of using jasmine or mocha'
489
+ ' This can happen if you try using this module when running with' +
490
+ ' node directly instead of using jasmine or mocha'
491
491
  )
492
492
  }
493
493
  return fn