selenium-webdriver 4.18.1 → 4.20.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.
Files changed (68) hide show
  1. package/CHANGES.md +946 -743
  2. package/README.md +71 -72
  3. package/bidi/addInterceptParameters.js +65 -45
  4. package/bidi/argumentValue.js +1 -0
  5. package/bidi/browser.js +94 -0
  6. package/bidi/browsingContext.js +214 -32
  7. package/bidi/browsingContextInspector.js +51 -0
  8. package/bidi/browsingContextTypes.js +31 -0
  9. package/bidi/captureScreenshotParameters.js +96 -0
  10. package/bidi/clipRectangle.js +127 -0
  11. package/bidi/continueRequestParameters.js +122 -0
  12. package/bidi/continueResponseParameters.js +129 -0
  13. package/bidi/cookieFilter.js +139 -0
  14. package/bidi/createContextParameters.js +73 -0
  15. package/bidi/evaluateResult.js +17 -0
  16. package/bidi/index.js +25 -26
  17. package/bidi/input.js +47 -3
  18. package/bidi/interceptPhase.js +5 -1
  19. package/bidi/logEntries.js +66 -0
  20. package/bidi/network.js +176 -23
  21. package/bidi/networkTypes.js +394 -17
  22. package/bidi/partialCookie.js +115 -0
  23. package/bidi/partitionDescriptor.js +102 -0
  24. package/bidi/partitionKey.js +53 -0
  25. package/bidi/protocolType.js +20 -0
  26. package/bidi/protocolValue.js +140 -9
  27. package/bidi/provideResponseParameters.js +123 -0
  28. package/bidi/realmInfo.js +27 -0
  29. package/bidi/resultOwnership.js +4 -0
  30. package/bidi/scriptManager.js +131 -5
  31. package/bidi/scriptTypes.js +36 -0
  32. package/bidi/storage.js +201 -0
  33. package/bidi/urlPattern.js +36 -3
  34. package/bin/linux/selenium-manager +0 -0
  35. package/bin/macos/selenium-manager +0 -0
  36. package/bin/windows/selenium-manager.exe +0 -0
  37. package/chromium.js +13 -9
  38. package/common/driverFinder.js +36 -4
  39. package/common/seleniumManager.js +7 -39
  40. package/devtools/CDPConnection.js +1 -0
  41. package/devtools/networkinterceptor.js +1 -0
  42. package/eslint.config.js +107 -0
  43. package/firefox.js +20 -6
  44. package/http/index.js +6 -6
  45. package/http/util.js +1 -0
  46. package/ie.js +8 -4
  47. package/index.js +11 -0
  48. package/io/exec.js +1 -1
  49. package/io/index.js +3 -2
  50. package/io/zip.js +1 -1
  51. package/lib/atoms/find-elements.js +26 -26
  52. package/lib/atoms/is-displayed.js +24 -97
  53. package/lib/capabilities.js +5 -5
  54. package/lib/http.js +8 -4
  55. package/lib/input.js +0 -1
  56. package/lib/pinnedScript.js +1 -1
  57. package/lib/select.js +8 -8
  58. package/lib/until.js +3 -3
  59. package/lib/util.js +1 -0
  60. package/lib/virtual_authenticator.js +8 -8
  61. package/lib/webdriver.js +8 -3
  62. package/net/index.js +1 -1
  63. package/net/portprober.js +1 -1
  64. package/package.json +21 -13
  65. package/remote/index.js +1 -1
  66. package/remote/util.js +2 -2
  67. package/safari.js +3 -3
  68. package/testing/index.js +17 -8
@@ -0,0 +1,123 @@
1
+ // Licensed to the Software Freedom Conservancy (SFC) under one
2
+ // or more contributor license agreements. See the NOTICE file
3
+ // distributed with this work for additional information
4
+ // regarding copyright ownership. The SFC licenses this file
5
+ // to you under the Apache License, Version 2.0 (the
6
+ // "License"); you may not use this file except in compliance
7
+ // with the License. You may obtain a copy of the License at
8
+ //
9
+ // http://www.apache.org/licenses/LICENSE-2.0
10
+ //
11
+ // Unless required by applicable law or agreed to in writing,
12
+ // software distributed under the License is distributed on an
13
+ // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ // KIND, either express or implied. See the License for the
15
+ // specific language governing permissions and limitations
16
+ // under the License.
17
+
18
+ const { BytesValue, Header } = require('./networkTypes')
19
+
20
+ /**
21
+ * Represents parameters for providingResponse command.
22
+ * Described in https://w3c.github.io/webdriver-bidi/#command-network-provideResponse.
23
+ * @class
24
+ */
25
+ class ProvideResponseParameters {
26
+ #map = new Map()
27
+
28
+ constructor(request) {
29
+ this.#map.set('request', request)
30
+ }
31
+
32
+ /**
33
+ * Sets the body value for the response parameters.
34
+ *
35
+ * @param {BytesValue} value - The value to set as the body. Must be an instance of BytesValue.
36
+ * @returns {ProvideResponseParameters} - Returns the ProvideResponseParameters object for chaining.
37
+ * @throws {Error} - Throws an error if the value is not an instance of BytesValue.
38
+ */
39
+ body(value) {
40
+ if (!(value instanceof BytesValue)) {
41
+ throw new Error(`Value must be an instance of BytesValue. Received: ${typeof value} with value: ${value}`)
42
+ }
43
+ this.#map.set('body', Object.fromEntries(value.asMap()))
44
+ return this
45
+ }
46
+
47
+ /**
48
+ * Sets the cookie headers for the response.
49
+ *
50
+ * @param {Header[]} cookieHeaders - An array of cookie headers.
51
+ * @returns {ProvideResponseParameters} - Returns the ProvideResponseParameters object for chaining.
52
+ * @throws {Error} - Throws an error if a cookie header is not an instance of Header.
53
+ */
54
+ cookies(cookieHeaders) {
55
+ const cookies = []
56
+ cookieHeaders.forEach((header) => {
57
+ if (!(header instanceof Header)) {
58
+ throw new Error(`CookieHeader must be an instance of Header. Received:'${header}'`)
59
+ }
60
+ cookies.push(Object.fromEntries(header.asMap()))
61
+ })
62
+
63
+ this.#map.set('cookies', cookies)
64
+ return this
65
+ }
66
+
67
+ /**
68
+ * Sets the headers for the response.
69
+ *
70
+ * @param {Header[]} headers - The headers to be set.
71
+ * @returns {ProvideResponseParameters} - Returns the ProvideResponseParameters object for chaining.
72
+ * @throws {Error} - If the provided header is not an instance of Header.
73
+ */
74
+ headers(headers) {
75
+ const headerList = []
76
+ headers.forEach((header) => {
77
+ if (!(header instanceof Header)) {
78
+ throw new Error(`Header must be an instance of Header. Received:'${header}'`)
79
+ }
80
+ headerList.push(Object.fromEntries(header.asMap()))
81
+ })
82
+
83
+ this.#map.set('headers', headerList)
84
+ return this
85
+ }
86
+
87
+ /**
88
+ * Sets the reason phrase for the response.
89
+ *
90
+ * @param {string} reasonPhrase - The reason phrase to set.
91
+ * @returns {ProvideResponseParameters} - Returns the ProvideResponseParameters object for chaining.
92
+ * @throws {Error} - If the reason phrase is not a string.
93
+ */
94
+ reasonPhrase(reasonPhrase) {
95
+ if (typeof reasonPhrase !== 'string') {
96
+ throw new Error(`Reason phrase must be a string. Received: '${reasonPhrase})'`)
97
+ }
98
+ this.#map.set('reasonPhrase', reasonPhrase)
99
+ return this
100
+ }
101
+
102
+ /**
103
+ * Sets the status code for the response.
104
+ *
105
+ * @param {number} statusCode - The status code to set.
106
+ * @returns {ProvideResponseParameters} - Returns the ProvideResponseParameters object for chaining.
107
+ * @throws {Error} - If the status code is not an integer.
108
+ */
109
+ statusCode(statusCode) {
110
+ if (!Number.isInteger(statusCode)) {
111
+ throw new Error(`Status must be an integer. Received:'${statusCode}'`)
112
+ }
113
+
114
+ this.#map.set('statusCode', statusCode)
115
+ return this
116
+ }
117
+
118
+ asMap() {
119
+ return this.#map
120
+ }
121
+ }
122
+
123
+ module.exports = { ProvideResponseParameters }
package/bidi/realmInfo.js CHANGED
@@ -15,6 +15,11 @@
15
15
  // specific language governing permissions and limitations
16
16
  // under the License.
17
17
 
18
+ /**
19
+ * Represents the types of realms.
20
+ * Described in https://w3c.github.io/webdriver-bidi/#type-script-RealmType.
21
+ * @enum
22
+ */
18
23
  const RealmType = {
19
24
  AUDIO_WORKLET: 'audio-worklet',
20
25
  DEDICATED_WORKER: 'dedicated-worker',
@@ -34,7 +39,17 @@ const RealmType = {
34
39
  },
35
40
  }
36
41
 
42
+ /**
43
+ * Represents information about a realm.
44
+ * Described in https://w3c.github.io/webdriver-bidi/#type-script-RealmInfo.
45
+ */
37
46
  class RealmInfo {
47
+ /**
48
+ * Constructs a new RealmInfo object.
49
+ * @param {string} realmId - The ID of the realm.
50
+ * @param {string} origin - The origin of the realm.
51
+ * @param {string} realmType - The type of the realm.
52
+ */
38
53
  constructor(realmId, origin, realmType) {
39
54
  this.realmId = realmId
40
55
  this.origin = origin
@@ -77,7 +92,19 @@ class RealmInfo {
77
92
  }
78
93
  }
79
94
 
95
+ /**
96
+ * Represents information about a window realm.
97
+ * @extends RealmInfo
98
+ */
80
99
  class WindowRealmInfo extends RealmInfo {
100
+ /**
101
+ * Constructs a new instance of the WindowRealmInfo class.
102
+ * @param {string} realmId - The ID of the realm.
103
+ * @param {string} origin - The origin of the realm.
104
+ * @param {string} realmType - The type of the realm.
105
+ * @param {string} browsingContext - The browsing context of the realm.
106
+ * @param {string|null} sandbox - The sandbox of the realm (optional).
107
+ */
81
108
  constructor(realmId, origin, realmType, browsingContext, sandbox = null) {
82
109
  super(realmId, origin, realmType)
83
110
  this.browsingContext = browsingContext
@@ -15,6 +15,10 @@
15
15
  // specific language governing permissions and limitations
16
16
  // under the License.
17
17
 
18
+ /**
19
+ * Enum representing the ownership types.
20
+ * @enum {string}
21
+ */
18
22
  const ResultOwnership = {
19
23
  ROOT: 'root',
20
24
  NONE: 'none',
@@ -27,20 +27,32 @@ const { RemoteValue } = require('./protocolValue')
27
27
  const { Source } = require('./scriptTypes')
28
28
  const { WebDriverError } = require('../lib/error')
29
29
 
30
+ /**
31
+ * Represents class to run events and commands of Script module.
32
+ * Described in https://w3c.github.io/webdriver-bidi/#module-script.
33
+ * @class
34
+ */
30
35
  class ScriptManager {
31
36
  constructor(driver) {
32
37
  this._driver = driver
33
38
  }
34
39
 
35
- async init(browsingContextId) {
40
+ async init(browsingContextIds) {
36
41
  if (!(await this._driver.getCapabilities()).get('webSocketUrl')) {
37
42
  throw Error('WebDriver instance must support BiDi protocol')
38
43
  }
39
44
 
40
45
  this.bidi = await this._driver.getBidi()
41
- this._browsingContextId = browsingContextId
46
+ this._browsingContextIds = browsingContextIds
42
47
  }
43
48
 
49
+ /**
50
+ * Disowns the handles in the specified realm.
51
+ *
52
+ * @param {string} realmId - The ID of the realm.
53
+ * @param {string[]} handles - The handles to disown to allow garbage collection.
54
+ * @returns {Promise<void>} - A promise that resolves when the command is sent.
55
+ */
44
56
  async disownRealmScript(realmId, handles) {
45
57
  const params = {
46
58
  method: 'script.disown',
@@ -55,6 +67,13 @@ class ScriptManager {
55
67
  await this.bidi.send(params)
56
68
  }
57
69
 
70
+ /**
71
+ * Disowns the handles in the specified browsing context.
72
+ * @param {string} browsingContextId - The ID of the browsing context.
73
+ * @param {string[]} handles - The handles to disown to allow garbage collection.
74
+ * @param {String|null} [sandbox=null] - The sandbox name.
75
+ * @returns {Promise<void>} - A promise that resolves when the command is sent.
76
+ */
58
77
  async disownBrowsingContextScript(browsingContextId, handles, sandbox = null) {
59
78
  const params = {
60
79
  method: 'script.disown',
@@ -73,6 +92,17 @@ class ScriptManager {
73
92
  await this.bidi.send(params)
74
93
  }
75
94
 
95
+ /**
96
+ * Calls a function in the specified realm.
97
+ *
98
+ * @param {string} realmId - The ID of the realm.
99
+ * @param {string} functionDeclaration - The function to call.
100
+ * @param {boolean} awaitPromise - Whether to await the promise returned by the function.
101
+ * @param {LocalValue[]} [argumentValueList|null] - The list of argument values to pass to the function.
102
+ * @param {Object} [thisParameter|null] - The value of 'this' parameter for the function.
103
+ * @param {ResultOwnership} [resultOwnership|null] - The ownership of the result.
104
+ * @returns {Promise<EvaluateResultSuccess|EvaluateResultException>} - A promise that resolves to the evaluation result or exception.
105
+ */
76
106
  async callFunctionInRealm(
77
107
  realmId,
78
108
  functionDeclaration,
@@ -101,6 +131,17 @@ class ScriptManager {
101
131
  return this.createEvaluateResult(response)
102
132
  }
103
133
 
134
+ /**
135
+ * Calls a function in the specified browsing context.
136
+ *
137
+ * @param {string} realmId - The ID of the browsing context.
138
+ * @param {string} functionDeclaration - The function to call.
139
+ * @param {boolean} awaitPromise - Whether to await the promise returned by the function.
140
+ * @param {LocalValue[]} [argumentValueList|null] - The list of argument values to pass to the function.
141
+ * @param {Object} [thisParameter|null] - The value of 'this' parameter for the function.
142
+ * @param {ResultOwnership} [resultOwnership|null] - The ownership of the result.
143
+ * @returns {Promise<EvaluateResultSuccess|EvaluateResultException>} - A promise that resolves to the evaluation result or exception.
144
+ */
104
145
  async callFunctionInBrowsingContext(
105
146
  browsingContextId,
106
147
  functionDeclaration,
@@ -129,6 +170,15 @@ class ScriptManager {
129
170
  return this.createEvaluateResult(response)
130
171
  }
131
172
 
173
+ /**
174
+ * Evaluates a function in the specified realm.
175
+ *
176
+ * @param {string} realmId - The ID of the realm.
177
+ * @param {string} expression - The expression to function to evaluate.
178
+ * @param {boolean} awaitPromise - Whether to await the promise.
179
+ * @param {ResultOwnership|null} resultOwnership - The ownership of the result.
180
+ * @returns {Promise<EvaluateResultSuccess|EvaluateResultException>} - A promise that resolves to the evaluation result or exception.
181
+ */
132
182
  async evaluateFunctionInRealm(realmId, expression, awaitPromise, resultOwnership = null) {
133
183
  const params = this.getEvaluateParams('realm', realmId, null, expression, awaitPromise, resultOwnership)
134
184
 
@@ -141,6 +191,15 @@ class ScriptManager {
141
191
  return this.createEvaluateResult(response)
142
192
  }
143
193
 
194
+ /**
195
+ * Evaluates a function in the browsing context.
196
+ *
197
+ * @param {string} realmId - The ID of the browsing context.
198
+ * @param {string} expression - The expression to function to evaluate.
199
+ * @param {boolean} awaitPromise - Whether to await the promise.
200
+ * @param {ResultOwnership|null} resultOwnership - The ownership of the result.
201
+ * @returns {Promise<EvaluateResultSuccess|EvaluateResultException>} - A promise that resolves to the evaluation result or exception.
202
+ */
144
203
  async evaluateFunctionInBrowsingContext(
145
204
  browsingContextId,
146
205
  expression,
@@ -166,11 +225,30 @@ class ScriptManager {
166
225
  return this.createEvaluateResult(response)
167
226
  }
168
227
 
228
+ /**
229
+ * Adds a preload script.
230
+ *
231
+ * @param {string} functionDeclaration - The declaration of the function to be added as a preload script.
232
+ * @param {LocalValue[]} [argumentValueList=[]] - The list of argument values to be passed to the preload script function.
233
+ * @param {string} [sandbox|null] - The sandbox object to be used for the preload script.
234
+ * @returns {Promise<number>} - A promise that resolves to the added preload script ID.
235
+ */
169
236
  async addPreloadScript(functionDeclaration, argumentValueList = [], sandbox = null) {
170
237
  const params = {
171
238
  functionDeclaration: functionDeclaration,
172
239
  arguments: argumentValueList,
173
- sandbox: sandbox,
240
+ }
241
+
242
+ if (sandbox !== null) {
243
+ params.sandbox = sandbox
244
+ }
245
+
246
+ if (Array.isArray(this._browsingContextIds) && this._browsingContextIds.length > 0) {
247
+ params.contexts = this._browsingContextIds
248
+ }
249
+
250
+ if (typeof this._browsingContextIds === 'string') {
251
+ params.contexts = new Array(this._browsingContextIds)
174
252
  }
175
253
 
176
254
  const command = {
@@ -182,6 +260,13 @@ class ScriptManager {
182
260
  return response.result.script
183
261
  }
184
262
 
263
+ /**
264
+ * Removes a preload script.
265
+ *
266
+ * @param {string} script - The ID for the script to be removed.
267
+ * @returns {Promise<any>} - A promise that resolves with the result of the removal.
268
+ * @throws {WebDriverError} - If an error occurs during the removal process.
269
+ */
185
270
  async removePreloadScript(script) {
186
271
  const params = { script: script }
187
272
  const command = {
@@ -282,6 +367,10 @@ class ScriptManager {
282
367
  return realmsList
283
368
  }
284
369
 
370
+ /**
371
+ * Retrieves all realms.
372
+ * @returns {Promise<RealmInfo[]>} - A promise that resolves to an array of RealmInfo objects.
373
+ */
285
374
  async getAllRealms() {
286
375
  const command = {
287
376
  method: 'script.getRealms',
@@ -291,6 +380,12 @@ class ScriptManager {
291
380
  return this.realmInfoMapper(response.result.realms)
292
381
  }
293
382
 
383
+ /**
384
+ * Retrieves the realms by type.
385
+ *
386
+ * @param {Type} type - The type of realms to retrieve.
387
+ * @returns {Promise<RealmInfo[]>} - A promise that resolves to an array of RealmInfo objects.
388
+ */
294
389
  async getRealmsByType(type) {
295
390
  const command = {
296
391
  method: 'script.getRealms',
@@ -300,6 +395,12 @@ class ScriptManager {
300
395
  return this.realmInfoMapper(response.result.realms)
301
396
  }
302
397
 
398
+ /**
399
+ * Retrieves the realms in the specified browsing context.
400
+ *
401
+ * @param {string} browsingContext - The browsing context ID.
402
+ * @returns {Promise<RealmInfo[]>} - A promise that resolves to an array of RealmInfo objects.
403
+ */
303
404
  async getRealmsInBrowsingContext(browsingContext) {
304
405
  const command = {
305
406
  method: 'script.getRealms',
@@ -309,6 +410,13 @@ class ScriptManager {
309
410
  return this.realmInfoMapper(response.result.realms)
310
411
  }
311
412
 
413
+ /**
414
+ * Retrieves the realms in a browsing context based on the specified type.
415
+ *
416
+ * @param {string} browsingContext - The browsing context ID.
417
+ * @param {string} type - The type of realms to retrieve.
418
+ * @returns {Promise<RealmInfo[]>} - A promise that resolves to an array of RealmInfo objects.
419
+ */
312
420
  async getRealmsInBrowsingContextByType(browsingContext, type) {
313
421
  const command = {
314
422
  method: 'script.getRealms',
@@ -318,21 +426,39 @@ class ScriptManager {
318
426
  return this.realmInfoMapper(response.result.realms)
319
427
  }
320
428
 
429
+ /**
430
+ * Subscribes to the 'script.message' event and handles the callback function when a message is received.
431
+ *
432
+ * @param {Function} callback - The callback function to be executed when a message is received.
433
+ * @returns {Promise<void>} - A promise that resolves when the subscription is successful.
434
+ */
321
435
  async onMessage(callback) {
322
436
  await this.subscribeAndHandleEvent('script.message', callback)
323
437
  }
324
438
 
439
+ /**
440
+ * Subscribes to the 'script.realmCreated' event and handles it with the provided callback.
441
+ *
442
+ * @param {Function} callback - The callback function to handle the 'script.realmCreated' event.
443
+ * @returns {Promise<void>} - A promise that resolves when the subscription is successful.
444
+ */
325
445
  async onRealmCreated(callback) {
326
446
  await this.subscribeAndHandleEvent('script.realmCreated', callback)
327
447
  }
328
448
 
449
+ /**
450
+ * Subscribes to the 'script.realmDestroyed' event and handles it with the provided callback function.
451
+ *
452
+ * @param {Function} callback - The callback function to be executed when the 'script.realmDestroyed' event occurs.
453
+ * @returns {Promise<void>} - A promise that resolves when the subscription is successful.
454
+ */
329
455
  async onRealmDestroyed(callback) {
330
456
  await this.subscribeAndHandleEvent('script.realmDestroyed', callback)
331
457
  }
332
458
 
333
459
  async subscribeAndHandleEvent(eventType, callback) {
334
- if (this._browsingContextIds != null) {
335
- await this.bidi.subscribe(eventType, this._browsingContextIds)
460
+ if (this.browsingContextIds != null) {
461
+ await this.bidi.subscribe(eventType, this.browsingContextIds)
336
462
  } else {
337
463
  await this.bidi.subscribe(eventType)
338
464
  }
@@ -15,26 +15,54 @@
15
15
  // specific language governing permissions and limitations
16
16
  // under the License.
17
17
 
18
+ /**
19
+ * Represents a message received through a channel.
20
+ * Described in https://w3c.github.io/webdriver-bidi/#event-script-message.
21
+ * @class
22
+ */
18
23
  class Message {
24
+ /**
25
+ * Creates a new Message instance.
26
+ * @param {string} channel - The channel through which the message is received.
27
+ * @param {RemoteValue} data - The data contained in the message.
28
+ * @param {Source} source - The source of the message.
29
+ */
19
30
  constructor(channel, data, source) {
20
31
  this._channel = channel
21
32
  this._data = data
22
33
  this._source = source
23
34
  }
24
35
 
36
+ /**
37
+ * Gets the channel through which the message is received.
38
+ * @returns {string} The channel.
39
+ */
25
40
  get channel() {
26
41
  return this._channel
27
42
  }
28
43
 
44
+ /**
45
+ * Gets the data contained in the message.
46
+ * @returns {RemoteValue} The data.
47
+ */
29
48
  get data() {
30
49
  return this._data
31
50
  }
32
51
 
52
+ /**
53
+ * Gets the source of the message.
54
+ * @returns {Source} The source.
55
+ */
33
56
  get source() {
34
57
  return this._source
35
58
  }
36
59
  }
37
60
 
61
+ /**
62
+ * Represents a source object.
63
+ * Described in https://w3c.github.io/webdriver-bidi/#type-script-Source.
64
+ * @class
65
+ */
38
66
  class Source {
39
67
  constructor(source) {
40
68
  this._browsingContextId = null
@@ -46,10 +74,18 @@ class Source {
46
74
  }
47
75
  }
48
76
 
77
+ /**
78
+ * Get the browsing context ID.
79
+ * @returns {string|null} The browsing context ID.
80
+ */
49
81
  get browsingContextId() {
50
82
  return this._browsingContextId
51
83
  }
52
84
 
85
+ /**
86
+ * Get the realm ID.
87
+ * @returns {string} The realm ID.
88
+ */
53
89
  get realmId() {
54
90
  return this._realmId
55
91
  }