selenium-webdriver 4.0.0 → 4.1.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 CHANGED
@@ -1,3 +1,20 @@
1
+ ## v4.1.0
2
+
3
+ * add support for handling Shadow DOM elements
4
+ * Capture browser console logs when using BiDi onLogEvent api
5
+ * add CDP support for v96 and remove v93
6
+ * remove useless package, change io public api import to more common approach (#10037)
7
+ * Fix flaky CDP dom mutation (#10029)
8
+ * Fix edge test failures (#10012)
9
+ * code cleanup second iteration (#9979)
10
+ * Ensure correct serialization of extensions in chromium.Options (#6676)
11
+ * Remove explicit id passing for CDP commands
12
+ * Attach to page target while creating a CDP connection (#10005)
13
+ * Add support for form submit in W3C mode (fixes #9916) (#9936)
14
+ * Fixes relative locator 'locateWith' export
15
+ * update doc string for CDP Commands (#9929)
16
+
17
+
1
18
  ## v4.0.0
2
19
 
3
20
  * Fixes cdp for Chrome and Firefox (#9909)
@@ -516,7 +533,7 @@ This release requires [geckodriver 0.15.0](https://github.com/mozilla/geckodrive
516
533
  DriverService instances that run in a child-process. The
517
534
  `chrome.ServiceBuilder`, `edge.ServiceBuilder`, and `opera.ServiceBuilder`
518
535
  classes now all extend this base class with browser-specific options.
519
- * For each of the ServiceBuilder clases, renamed `usingPort` and
536
+ * For each of the ServiceBuilder classes, renamed `usingPort` and
520
537
  `withEnvironment` to `setPort` and `setEnvironment`, respectively.
521
538
  * Renamed `chrome.ServiceBuilder#setUrlBasePath` to `#setPath`
522
539
  * Changed the signature of the `firefox.Driver` from `(config, flow, executor)`
package/chrome.js CHANGED
@@ -236,9 +236,10 @@ 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} */ (
240
- super.createSession(caps, opt_serviceExecutor)
241
- )
239
+ return /** @type {!Driver} */ (super.createSession(
240
+ caps,
241
+ opt_serviceExecutor
242
+ ))
242
243
  }
243
244
  }
244
245
 
package/chromium.js CHANGED
@@ -358,8 +358,11 @@ class Options extends Capabilities {
358
358
  * @return {!Options} A self reference.
359
359
  */
360
360
  addExtensions(...args) {
361
- let current = this.options_.extensions || []
362
- this.options_.extensions = current.concat(...args)
361
+ let extensions = this.options_.extensions || new Extensions()
362
+ extensions.add(...args)
363
+ if (extensions.length) {
364
+ this.options_.extensions = extensions
365
+ }
363
366
  return this
364
367
  }
365
368
 
@@ -584,28 +587,47 @@ class Options extends Capabilities {
584
587
  }
585
588
  return this
586
589
  }
590
+ }
591
+
592
+ /**
593
+ * A list of extensions to install when launching the browser.
594
+ */
595
+ class Extensions {
596
+ constructor() {
597
+ this.extensions = []
598
+ }
599
+
600
+ /**
601
+ * @return {number} The length of the extensions list.
602
+ */
603
+ get length() {
604
+ return this.extensions.length
605
+ }
587
606
 
588
607
  /**
589
- * Converts this instance to its JSON wire protocol representation. Note this
590
- * function is an implementation not intended for general use.
608
+ * Add additional extensions to install when launching the browser. Each
609
+ * extension should be specified as the path to the packed CRX file, or a
610
+ * Buffer for an extension.
591
611
  *
592
- * @return {!Object} The JSON wire protocol representation of this instance.
593
- * @suppress {checkTypes} Suppress [] access on a struct.
612
+ * @param {...(string|!Buffer|!Array<(string|!Buffer)>)} args The
613
+ * extensions to add.
614
+ */
615
+ add(...args) {
616
+ this.extensions = this.extensions.concat(...args)
617
+ }
618
+
619
+ /**
620
+ * @return {!Object} A serialized representation of this Extensions object.
594
621
  */
595
622
  [Symbols.serialize]() {
596
- if (this.options_.extensions && this.options_.extensions.length) {
597
- this.options_.extensions = this.options_.extensions.map(function (
598
- extension
599
- ) {
600
- if (Buffer.isBuffer(extension)) {
601
- return extension.toString('base64')
602
- }
603
- return io
604
- .read(/** @type {string} */ (extension))
605
- .then((buffer) => buffer.toString('base64'))
606
- })
607
- }
608
- return super[Symbols.serialize]()
623
+ return this.extensions.map(function (extension) {
624
+ if (Buffer.isBuffer(extension)) {
625
+ return extension.toString('base64')
626
+ }
627
+ return io
628
+ .read(/** @type {string} */ (extension))
629
+ .then((buffer) => buffer.toString('base64'))
630
+ })
609
631
  }
610
632
  }
611
633
 
@@ -725,11 +747,11 @@ class Driver extends webdriver.WebDriver {
725
747
  }
726
748
 
727
749
  /**
728
- * ends an arbitrary devtools command to the browser and get the result.
750
+ * Sends an arbitrary devtools command to the browser and get the result.
729
751
  *
730
752
  * @param {string} cmd The name of the command to send.
731
753
  * @param {Object=} params The command parameters.
732
- * @return {!Promise<void>} A promise that will be resolved when the command
754
+ * @return {!Promise<string>} A promise that will be resolved when the command
733
755
  * has finished.
734
756
  * @see <https://chromedevtools.github.io/devtools-protocol/>
735
757
  */
@@ -18,16 +18,21 @@
18
18
  class CDPConnection {
19
19
  constructor(wsConnection) {
20
20
  this._wsConnection = wsConnection
21
+ this.cmd_id = 0
22
+ this.targetID = null;
23
+ this.sessionId = null
21
24
  }
22
25
 
23
- execute(method, id, params, callback) {
24
- const message = {
26
+ execute(method, params, callback) {
27
+ let message = {
25
28
  method,
26
- id: id,
29
+ id: this.cmd_id++,
30
+ }
31
+ if (this.sessionId) {
32
+ message['sessionId'] = this.sessionId
27
33
  }
28
34
 
29
35
  const mergedMessage = Object.assign({ params: params }, message)
30
-
31
36
  this._wsConnection.send(JSON.stringify(mergedMessage), callback)
32
37
  }
33
38
  }
@@ -16,74 +16,73 @@
16
16
  // under the License.
17
17
 
18
18
  class HttpResponse {
19
- /**
20
- * Creates a HTTP Response that will be used to
21
- * mock out network interceptions.
22
- * @param {*} urlToIntercept
23
- */
24
- constructor(urlToIntercept = "") {
25
- this.returnBody = ""
26
- this.returnHeaders = []
27
- this.returnMethod = "GET"
28
- this.returnStatus = 200
29
- this.urlToIntercept = urlToIntercept
30
- }
19
+ /**
20
+ * Creates a HTTP Response that will be used to
21
+ * mock out network interceptions.
22
+ * @param {*} urlToIntercept
23
+ */
24
+ constructor(urlToIntercept = '') {
25
+ this.returnBody = ''
26
+ this.returnHeaders = []
27
+ this.returnMethod = 'GET'
28
+ this.returnStatus = 200
29
+ this.urlToIntercept = urlToIntercept
30
+ }
31
31
 
32
- /**
33
- * Add headers that will be returned when we intercept
34
- * a HTTP Request
35
- * @param {*} header
36
- * @param {*} value
37
- */
38
- addHeaders(header, value) {
39
- this.returnHeaders.push({ name: header, value: value })
40
- }
32
+ /**
33
+ * Add headers that will be returned when we intercept
34
+ * a HTTP Request
35
+ * @param {*} header
36
+ * @param {*} value
37
+ */
38
+ addHeaders(header, value) {
39
+ this.returnHeaders.push({ name: header, value: value })
40
+ }
41
41
 
42
- get headers() {
43
- return this.returnHeaders
44
- }
42
+ get headers() {
43
+ return this.returnHeaders
44
+ }
45
45
 
46
- /**
47
- * Set the STATUS value of the returned HTTP Request
48
- * @param {*} value
49
- */
50
- set status(value) {
51
- // Add in check that his should be a number
52
- this.returnStatus = value
53
- }
46
+ /**
47
+ * Set the STATUS value of the returned HTTP Request
48
+ * @param {*} value
49
+ */
50
+ set status(value) {
51
+ // Add in check that his should be a number
52
+ this.returnStatus = value
53
+ }
54
54
 
55
- get status() {
56
- return this.returnStatus
57
- }
55
+ get status() {
56
+ return this.returnStatus
57
+ }
58
58
 
59
- /**
60
- * Sets the value of the body of the HTTP Request that
61
- * will be returned.
62
- * @param {*} value
63
- */
64
- set body(value) {
65
- this.returnBody = value
66
- }
59
+ /**
60
+ * Sets the value of the body of the HTTP Request that
61
+ * will be returned.
62
+ * @param {*} value
63
+ */
64
+ set body(value) {
65
+ this.returnBody = value
66
+ }
67
67
 
68
- get body() {
69
- let buff = Buffer.from(this.returnBody, "utf-8")
70
- return buff.toString("base64")
71
- }
68
+ get body() {
69
+ let buff = Buffer.from(this.returnBody, 'utf-8')
70
+ return buff.toString('base64')
71
+ }
72
72
 
73
- /**
74
- * Sets the method of the HTTP Request
75
- * @param {*} value the method of the request.
76
- */
77
- set method(value) {
78
- this.returnMethod = value
79
- }
80
-
81
- /**
82
- * Returns the Method to be used in the intercept
83
- */
84
- get method() {
85
- return this.returnMethod
86
- }
73
+ /**
74
+ * Sets the method of the HTTP Request
75
+ * @param {*} value the method of the request.
76
+ */
77
+ set method(value) {
78
+ this.returnMethod = value
79
+ }
87
80
 
81
+ /**
82
+ * Returns the Method to be used in the intercept
83
+ */
84
+ get method() {
85
+ return this.returnMethod
86
+ }
88
87
  }
89
88
  exports.HttpResponse = HttpResponse
package/http/index.js CHANGED
@@ -37,7 +37,7 @@ const httpLib = require('../lib/http')
37
37
  * path: (?string|undefined),
38
38
  * pathname: (?string|undefined)}}
39
39
  */
40
- var RequestOptions // eslint-disable-line
40
+ let RequestOptions // eslint-disable-line
41
41
 
42
42
  /**
43
43
  * @param {string} aUrl The request URL to parse.
@@ -100,9 +100,7 @@ class HttpClient {
100
100
  */
101
101
  this.keepAlive = this.client_options['keep-alive']
102
102
 
103
- /**
104
- * @private {?RequestOptions}
105
- */
103
+ /** @private {?RequestOptions} */
106
104
  this.proxyOptions_ = opt_proxy ? getRequestOptions(opt_proxy) : null
107
105
  }
108
106
 
@@ -219,9 +217,10 @@ function sendRequest(options, onOk, onError, opt_data, opt_proxy, opt_retries) {
219
217
  let requestFn = options.protocol === 'https:' ? https.request : http.request
220
218
  var request = requestFn(options, function onResponse(response) {
221
219
  if (response.statusCode == 302 || response.statusCode == 303) {
220
+ let location
222
221
  try {
223
222
  // eslint-disable-next-line node/no-deprecated-api
224
- var location = url.parse(response.headers['location'])
223
+ location = url.parse(response.headers['location'])
225
224
  } catch (ex) {
226
225
  onError(
227
226
  Error(
@@ -240,7 +239,7 @@ function sendRequest(options, onOk, onError, opt_data, opt_proxy, opt_retries) {
240
239
  location.auth = options.auth
241
240
  }
242
241
 
243
- request.abort()
242
+ request.destroy()
244
243
  sendRequest(
245
244
  {
246
245
  method: 'GET',
@@ -265,10 +264,10 @@ function sendRequest(options, onOk, onError, opt_data, opt_proxy, opt_retries) {
265
264
  return
266
265
  }
267
266
 
268
- var body = []
267
+ const body = []
269
268
  response.on('data', body.push.bind(body))
270
269
  response.on('end', function () {
271
- var resp = new httpLib.Response(
270
+ const resp = new httpLib.Response(
272
271
  /** @type {number} */ (response.statusCode),
273
272
  /** @type {!Object<string>} */ (response.headers),
274
273
  Buffer.concat(body).toString('utf8').replace(/\0/g, '')
@@ -288,7 +287,7 @@ function sendRequest(options, onOk, onError, opt_data, opt_proxy, opt_retries) {
288
287
  sendRequest(options, onOk, onError, opt_data, opt_proxy, opt_retries)
289
288
  }, 15)
290
289
  } else {
291
- var message = e.message
290
+ let message = e.message
292
291
  if (e.code) {
293
292
  message = e.code + ' ' + message
294
293
  }
@@ -339,8 +338,8 @@ function isRetryableNetworkError(err) {
339
338
 
340
339
  // PUBLIC API
341
340
 
342
- exports.Agent = http.Agent
343
- exports.Executor = httpLib.Executor
344
- exports.HttpClient = HttpClient
345
- exports.Request = httpLib.Request
346
- exports.Response = httpLib.Response
341
+ module.exports.Agent = http.Agent
342
+ module.exports.Executor = httpLib.Executor
343
+ module.exports.HttpClient = HttpClient
344
+ module.exports.Request = httpLib.Request
345
+ module.exports.Response = httpLib.Response
package/http/util.js CHANGED
@@ -21,12 +21,12 @@
21
21
 
22
22
  'use strict'
23
23
 
24
- const Executor = require('./index').Executor,
25
- HttpClient = require('./index').HttpClient,
26
- HttpRequest = require('./index').Request,
27
- Command = require('../lib/command').Command,
28
- CommandName = require('../lib/command').Name,
29
- error = require('../lib/error')
24
+ const Executor = require('./index').Executor
25
+ const HttpClient = require('./index').HttpClient
26
+ const HttpRequest = require('./index').Request
27
+ const Command = require('../lib/command').Command
28
+ const CommandName = require('../lib/command').Name
29
+ const error = require('../lib/error')
30
30
 
31
31
  /**
32
32
  * Queries a WebDriver server for its current status.
@@ -43,18 +43,6 @@ function getStatus(url) {
43
43
 
44
44
  class CancellationError {}
45
45
 
46
- // PUBLIC API
47
-
48
- /**
49
- * Queries a WebDriver server for its current status.
50
- * @param {string} url Base URL of the server to query.
51
- * @return {!Promise<!Object>} A promise that resolves with
52
- * a hash of the server status.
53
- */
54
- exports.getStatus = getStatus
55
-
56
- exports.CancellationError = CancellationError
57
-
58
46
  /**
59
47
  * Waits for a WebDriver server to be healthy and accepting requests.
60
48
  * @param {string} url Base URL of the server to query.
@@ -65,7 +53,7 @@ exports.CancellationError = CancellationError
65
53
  * @return {!Promise} A promise that will resolve when the server is ready, or
66
54
  * if the wait is cancelled.
67
55
  */
68
- exports.waitForServer = function (url, timeout, opt_cancelToken) {
56
+ function waitForServer(url, timeout, opt_cancelToken) {
69
57
  return new Promise((onResolve, onReject) => {
70
58
  let start = Date.now()
71
59
 
@@ -120,7 +108,7 @@ exports.waitForServer = function (url, timeout, opt_cancelToken) {
120
108
  * @return {!Promise} A promise that will resolve when a 2xx is received from
121
109
  * the given URL, or if the wait is cancelled.
122
110
  */
123
- exports.waitForUrl = function (url, timeout, opt_cancelToken) {
111
+ function waitForUrl(url, timeout, opt_cancelToken) {
124
112
  return new Promise((onResolve, onReject) => {
125
113
  let client = new HttpClient(url)
126
114
  let request = new HttpRequest('GET', '')
@@ -170,3 +158,9 @@ exports.waitForUrl = function (url, timeout, opt_cancelToken) {
170
158
  }
171
159
  })
172
160
  }
161
+
162
+ // PUBLIC API
163
+ module.exports.getStatus = getStatus
164
+ module.exports.CancellationError = CancellationError
165
+ module.exports.waitForServer = waitForServer
166
+ module.exports.waitForUrl = waitForUrl
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
  /**
@@ -339,10 +339,10 @@ class Builder {
339
339
  getCapabilities() {
340
340
  return this.capabilities_
341
341
  }
342
-
342
+
343
343
  /**
344
- * Sets the desired capability when requesting a new session.
345
- * If there is already a capability named key, its value will be overwritten with value.
344
+ * Sets the desired capability when requesting a new session.
345
+ * If there is already a capability named key, its value will be overwritten with value.
346
346
  * This is a convenience wrapper around builder.getCapabilities().set(key, value) to support Builder method chaining.
347
347
  * @param {string} key The capability key.
348
348
  * @param {*} value The capability value.
@@ -630,7 +630,7 @@ class Builder {
630
630
  if (typeof browser !== 'string') {
631
631
  throw TypeError(
632
632
  `Target browser must be a string, but is <${typeof browser}>;` +
633
- ' did you forget to call forBrowser()?'
633
+ ' did you forget to call forBrowser()?'
634
634
  )
635
635
  }
636
636
 
@@ -751,8 +751,8 @@ class Builder {
751
751
  default:
752
752
  throw new Error(
753
753
  'Do not know how to build driver: ' +
754
- browser +
755
- '; did you forget to call usingServer(url)?'
754
+ browser +
755
+ '; did you forget to call usingServer(url)?'
756
756
  )
757
757
  }
758
758
  }
@@ -808,9 +808,9 @@ function checkOptions(caps, key, optionType, setMethod) {
808
808
  if (val instanceof optionType) {
809
809
  throw new error.InvalidArgumentError(
810
810
  'Options class extends Capabilities and should not be set as key ' +
811
- `"${key}"; set browser-specific options with ` +
812
- `Builder.${setMethod}(). For more information, see the ` +
813
- 'documentation attached to the function that threw this error'
811
+ `"${key}"; set browser-specific options with ` +
812
+ `Builder.${setMethod}(). For more information, see the ` +
813
+ 'documentation attached to the function that threw this error'
814
814
  )
815
815
  }
816
816
  }
@@ -822,7 +822,7 @@ exports.Builder = Builder
822
822
  exports.Button = input.Button
823
823
  exports.By = by.By
824
824
  exports.withTagName = by.withTagName
825
- exports.withLocator = by.withLocator
825
+ exports.locateWith = by.locateWith
826
826
  exports.Capabilities = capabilities.Capabilities
827
827
  exports.Capability = capabilities.Capability
828
828
  exports.Condition = webdriver.Condition
package/io/exec.js CHANGED
@@ -76,8 +76,7 @@ class Result {
76
76
  }
77
77
  }
78
78
 
79
- const COMMAND_RESULT =
80
- /** !WeakMap<!Command, !Promise<!Result>> */ new WeakMap()
79
+ const COMMAND_RESULT = /** !WeakMap<!Command, !Promise<!Result>> */ new WeakMap()
81
80
  const KILL_HOOK = /** !WeakMap<!Command, function(string)> */ new WeakMap()
82
81
 
83
82
  /**