selenium-webdriver 4.16.0 → 4.18.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 (65) hide show
  1. package/CHANGES.md +253 -196
  2. package/LICENSE +1 -1
  3. package/NOTICE +1 -1
  4. package/bidi/addInterceptParameters.js +86 -0
  5. package/bidi/browsingContext.js +167 -38
  6. package/bidi/browsingContextInspector.js +13 -40
  7. package/bidi/evaluateResult.js +4 -10
  8. package/bidi/filterBy.js +2 -6
  9. package/bidi/index.js +31 -29
  10. package/bidi/input.js +97 -0
  11. package/bidi/interceptPhase.js +24 -0
  12. package/bidi/logInspector.js +15 -20
  13. package/bidi/network.js +178 -0
  14. package/bidi/networkInspector.js +12 -2
  15. package/bidi/networkTypes.js +22 -49
  16. package/bidi/protocolType.js +4 -9
  17. package/bidi/protocolValue.js +48 -17
  18. package/bidi/realmInfo.js +3 -10
  19. package/bidi/scriptManager.js +60 -48
  20. package/bidi/scriptTypes.js +58 -0
  21. package/bidi/urlPattern.js +58 -0
  22. package/bin/linux/selenium-manager +0 -0
  23. package/bin/macos/selenium-manager +0 -0
  24. package/bin/windows/selenium-manager.exe +0 -0
  25. package/chrome.js +2 -14
  26. package/chromium.js +28 -143
  27. package/common/driverFinder.js +1 -1
  28. package/common/seleniumManager.js +5 -12
  29. package/devtools/CDPConnection.js +1 -3
  30. package/edge.js +1 -3
  31. package/example/chrome_android.js +2 -5
  32. package/example/chrome_mobile_emulation.js +2 -4
  33. package/example/google_search.js +1 -3
  34. package/example/headless.js +4 -10
  35. package/example/logging.js +3 -9
  36. package/firefox.js +37 -111
  37. package/http/index.js +7 -10
  38. package/ie.js +5 -15
  39. package/index.js +10 -32
  40. package/io/exec.js +1 -2
  41. package/io/index.js +3 -3
  42. package/io/zip.js +8 -30
  43. package/lib/atoms/find-elements.js +1 -1
  44. package/lib/atoms/get-attribute.js +6 -100
  45. package/lib/by.js +2 -9
  46. package/lib/capabilities.js +8 -7
  47. package/lib/command.js +4 -0
  48. package/lib/error.js +2 -9
  49. package/lib/http.js +37 -130
  50. package/lib/input.js +22 -34
  51. package/lib/logging.js +3 -11
  52. package/lib/promise.js +2 -7
  53. package/lib/select.js +3 -9
  54. package/lib/until.js +28 -49
  55. package/lib/util.js +1 -4
  56. package/lib/virtual_authenticator.js +4 -22
  57. package/lib/webdriver.js +146 -269
  58. package/lib/webelement.js +1 -5
  59. package/net/index.js +1 -4
  60. package/package.json +2 -1
  61. package/remote/index.js +9 -24
  62. package/remote/util.js +6 -19
  63. package/safari.js +3 -8
  64. package/testing/index.js +6 -11
  65. package/example/firefox_channels.js +0 -84
package/lib/input.js CHANGED
@@ -256,9 +256,7 @@ function checkCodePoint(key) {
256
256
 
257
257
  key = key.normalize()
258
258
  if (Array.from(key).length !== 1) {
259
- throw new InvalidArgumentError(
260
- `key input is not a single code point: ${key}`
261
- )
259
+ throw new InvalidArgumentError(`key input is not a single code point: ${key}`)
262
260
  }
263
261
  return key
264
262
  }
@@ -333,10 +331,7 @@ class Pointer extends Device {
333
331
 
334
332
  /** @override */
335
333
  toJSON() {
336
- return Object.assign(
337
- { parameters: { pointerType: this.pointerType_ } },
338
- super.toJSON()
339
- )
334
+ return Object.assign({ parameters: { pointerType: this.pointerType_ } }, super.toJSON())
340
335
  }
341
336
 
342
337
  /**
@@ -371,7 +366,7 @@ class Pointer extends Device {
371
366
  tiltY = 0,
372
367
  twist = 0,
373
368
  altitudeAngle = 0,
374
- azimuthAngle = 0
369
+ azimuthAngle = 0,
375
370
  ) {
376
371
  return {
377
372
  type: Action.Type.POINTER_DOWN,
@@ -814,10 +809,7 @@ class Actions {
814
809
  for (const key of keys) {
815
810
  if (typeof key === 'string') {
816
811
  for (const symbol of key) {
817
- actions.push(
818
- this.keyboard_.keyDown(symbol),
819
- this.keyboard_.keyUp(symbol)
820
- )
812
+ actions.push(this.keyboard_.keyDown(symbol), this.keyboard_.keyUp(symbol))
821
813
  }
822
814
  } else {
823
815
  actions.push(this.keyboard_.keyDown(key), this.keyboard_.keyUp(key))
@@ -857,10 +849,7 @@ class Actions {
857
849
  * @returns {!Actions} An action to scroll with this device.
858
850
  */
859
851
  scroll(x, y, targetDeltaX, targetDeltaY, origin, duration) {
860
- return this.insert(
861
- this.wheel_,
862
- this.wheel_.scroll(x, y, targetDeltaX, targetDeltaY, origin, duration)
863
- )
852
+ return this.insert(this.wheel_, this.wheel_.scroll(x, y, targetDeltaX, targetDeltaY, origin, duration))
864
853
  }
865
854
 
866
855
  /**
@@ -885,10 +874,7 @@ class Actions {
885
874
  * @return {!Actions} a self reference.
886
875
  */
887
876
  move({ x = 0, y = 0, duration = 100, origin = Origin.VIEWPORT } = {}) {
888
- return this.insert(
889
- this.mouse_,
890
- this.mouse_.move({ x, y, duration, origin })
891
- )
877
+ return this.insert(this.mouse_, this.mouse_.move({ x, y, duration, origin }))
892
878
  }
893
879
 
894
880
  /**
@@ -953,13 +939,8 @@ class Actions {
953
939
  dragAndDrop(from, to) {
954
940
  // Do not require up top to avoid a cycle that breaks static analysis.
955
941
  const { WebElement } = require('./webdriver')
956
- if (
957
- !(to instanceof WebElement) &&
958
- (!to || typeof to.x !== 'number' || typeof to.y !== 'number')
959
- ) {
960
- throw new InvalidArgumentError(
961
- 'Invalid drag target; must specify a WebElement or {x, y} offset'
962
- )
942
+ if (!(to instanceof WebElement) && (!to || typeof to.x !== 'number' || typeof to.y !== 'number')) {
943
+ throw new InvalidArgumentError('Invalid drag target; must specify a WebElement or {x, y} offset')
963
944
  }
964
945
 
965
946
  this.move({ origin: from }).press()
@@ -1003,9 +984,19 @@ class Actions {
1003
984
  return Promise.resolve()
1004
985
  }
1005
986
 
1006
- await this.executor_.execute(
1007
- new Command(Name.ACTIONS).setParameter('actions', _actions)
1008
- )
987
+ await this.executor_.execute(new Command(Name.ACTIONS).setParameter('actions', _actions))
988
+ }
989
+
990
+ getSequences() {
991
+ const _actions = []
992
+ this.sequences_.forEach((actions, device) => {
993
+ if (!isIdle(actions)) {
994
+ actions = actions.concat()
995
+ _actions.push(Object.assign({ actions }, device.toJSON()))
996
+ }
997
+ })
998
+
999
+ return _actions
1009
1000
  }
1010
1001
  }
1011
1002
 
@@ -1014,10 +1005,7 @@ class Actions {
1014
1005
  * @return {boolean}
1015
1006
  */
1016
1007
  function isIdle(actions) {
1017
- return (
1018
- actions.length === 0 ||
1019
- actions.every((a) => a.type === Action.Type.PAUSE && !a.duration)
1020
- )
1008
+ return actions.length === 0 || actions.every((a) => a.type === Action.Type.PAUSE && !a.duration)
1021
1009
  }
1022
1010
 
1023
1011
  /**
package/lib/logging.js CHANGED
@@ -220,8 +220,7 @@ class Entry {
220
220
  constructor(level, message, opt_timestamp, opt_type) {
221
221
  this.level = level instanceof Level ? level : getLevel(level)
222
222
  this.message = message
223
- this.timestamp =
224
- typeof opt_timestamp === 'number' ? opt_timestamp : Date.now()
223
+ this.timestamp = typeof opt_timestamp === 'number' ? opt_timestamp : Date.now()
225
224
  this.type = opt_type || ''
226
225
  }
227
226
 
@@ -311,10 +310,7 @@ class Logger {
311
310
  * by this instance.
312
311
  */
313
312
  isLoggable(level) {
314
- return (
315
- level.value !== Level.OFF.value &&
316
- level.value >= this.getEffectiveLevel().value
317
- )
313
+ return level.value !== Level.OFF.value && level.value >= this.getEffectiveLevel().value
318
314
  }
319
315
 
320
316
  /**
@@ -358,11 +354,7 @@ class Logger {
358
354
  if (!this.isLoggable(level)) {
359
355
  return
360
356
  }
361
- let message =
362
- '[' +
363
- this.name_ +
364
- '] ' +
365
- (typeof loggable === 'function' ? loggable() : loggable)
357
+ let message = '[' + this.name_ + '] ' + (typeof loggable === 'function' ? loggable() : loggable)
366
358
  let entry = new Entry(level, message, Date.now())
367
359
  for (let logger = this; logger; logger = logger.parent_) {
368
360
  if (logger.handlers_) {
package/lib/promise.js CHANGED
@@ -173,9 +173,7 @@ async function filter(array, fn, self = undefined) {
173
173
  const values = []
174
174
 
175
175
  for (const [index, item] of arr.entries()) {
176
- const isConditionTrue = await Promise.resolve(
177
- fn.call(self, item, index, arr)
178
- )
176
+ const isConditionTrue = await Promise.resolve(fn.call(self, item, index, arr))
179
177
  if (isConditionTrue) {
180
178
  values.push(item)
181
179
  }
@@ -247,10 +245,7 @@ async function fullyResolveKeys(obj) {
247
245
 
248
246
  const forEachKey = isArray ? forEachElement : forEachProperty
249
247
  await forEachKey(obj, async function (partialValue, key) {
250
- if (
251
- !Array.isArray(partialValue) &&
252
- (!partialValue || typeof partialValue !== 'object')
253
- ) {
248
+ if (!Array.isArray(partialValue) && (!partialValue || typeof partialValue !== 'object')) {
254
249
  return
255
250
  }
256
251
  obj[key] = await fullyResolved(partialValue)
package/lib/select.js CHANGED
@@ -184,9 +184,7 @@ class Select {
184
184
 
185
185
  if (options.length - 1 < index) {
186
186
  throw new Error(
187
- `Option with index "${index}" not found. Select element only contains ${
188
- options.length - 1
189
- } option elements`
187
+ `Option with index "${index}" not found. Select element only contains ${options.length - 1} option elements`,
190
188
  )
191
189
  }
192
190
 
@@ -408,9 +406,7 @@ class Select {
408
406
 
409
407
  if (options.length - 1 < index) {
410
408
  throw new Error(
411
- `Option with index "${index}" not found. Select element only contains ${
412
- options.length - 1
413
- } option elements`
409
+ `Option with index "${index}" not found. Select element only contains ${options.length - 1} option elements`,
414
410
  )
415
411
  }
416
412
 
@@ -454,9 +450,7 @@ class Select {
454
450
  async setSelected(option) {
455
451
  if (!(await option.isSelected())) {
456
452
  if (!(await option.isEnabled())) {
457
- throw new error.UnsupportedOperationError(
458
- `You may not select a disabled option`
459
- )
453
+ throw new error.UnsupportedOperationError(`You may not select a disabled option`)
460
454
  }
461
455
  await option.click()
462
456
  }
package/lib/until.js CHANGED
@@ -96,7 +96,7 @@ function ableToSwitchToFrame(frame) {
96
96
  if (!(e instanceof error.NoSuchFrameError)) {
97
97
  throw e
98
98
  }
99
- }
99
+ },
100
100
  )
101
101
  }
102
102
  }
@@ -119,8 +119,7 @@ function alertIsPresent() {
119
119
  // XXX: Workaround for GeckoDriver error `TypeError: can't convert null
120
120
  // to object`. For more details, see
121
121
  // https://github.com/SeleniumHQ/selenium/pull/2137
122
- (e instanceof error.WebDriverError &&
123
- e.message === `can't convert null to object`)
122
+ (e instanceof error.WebDriverError && e.message === `can't convert null to object`)
124
123
  )
125
124
  ) {
126
125
  throw e
@@ -137,9 +136,7 @@ function alertIsPresent() {
137
136
  * @return {!Condition<boolean>} The new condition.
138
137
  */
139
138
  function titleIs(title) {
140
- return new Condition('for title to be ' + JSON.stringify(title), function (
141
- driver
142
- ) {
139
+ return new Condition('for title to be ' + JSON.stringify(title), function (driver) {
143
140
  return driver.getTitle().then(function (t) {
144
141
  return t === title
145
142
  })
@@ -155,14 +152,11 @@ function titleIs(title) {
155
152
  * @return {!Condition<boolean>} The new condition.
156
153
  */
157
154
  function titleContains(substr) {
158
- return new Condition(
159
- 'for title to contain ' + JSON.stringify(substr),
160
- function (driver) {
161
- return driver.getTitle().then(function (title) {
162
- return title.indexOf(substr) !== -1
163
- })
164
- }
165
- )
155
+ return new Condition('for title to contain ' + JSON.stringify(substr), function (driver) {
156
+ return driver.getTitle().then(function (title) {
157
+ return title.indexOf(substr) !== -1
158
+ })
159
+ })
166
160
  }
167
161
 
168
162
  /**
@@ -188,9 +182,7 @@ function titleMatches(regex) {
188
182
  * @return {!Condition<boolean>} The new condition.
189
183
  */
190
184
  function urlIs(url) {
191
- return new Condition('for URL to be ' + JSON.stringify(url), function (
192
- driver
193
- ) {
185
+ return new Condition('for URL to be ' + JSON.stringify(url), function (driver) {
194
186
  return driver.getCurrentUrl().then(function (u) {
195
187
  return u === url
196
188
  })
@@ -206,14 +198,11 @@ function urlIs(url) {
206
198
  * @return {!Condition<boolean>} The new condition.
207
199
  */
208
200
  function urlContains(substrUrl) {
209
- return new Condition(
210
- 'for URL to contain ' + JSON.stringify(substrUrl),
211
- function (driver) {
212
- return driver.getCurrentUrl().then(function (url) {
213
- return url && url.includes(substrUrl)
214
- })
215
- }
216
- )
201
+ return new Condition('for URL to contain ' + JSON.stringify(substrUrl), function (driver) {
202
+ return driver.getCurrentUrl().then(function (url) {
203
+ return url && url.includes(substrUrl)
204
+ })
205
+ })
217
206
  }
218
207
 
219
208
  /**
@@ -240,16 +229,12 @@ function urlMatches(regex) {
240
229
  */
241
230
  function elementLocated(locator) {
242
231
  locator = by.checkedLocator(locator)
243
- let locatorStr =
244
- typeof locator === 'function' ? 'by function()' : locator + ''
245
- return new WebElementCondition(
246
- 'for element to be located ' + locatorStr,
247
- function (driver) {
248
- return driver.findElements(locator).then(function (elements) {
249
- return elements[0]
250
- })
251
- }
252
- )
232
+ let locatorStr = typeof locator === 'function' ? 'by function()' : locator + ''
233
+ return new WebElementCondition('for element to be located ' + locatorStr, function (driver) {
234
+ return driver.findElements(locator).then(function (elements) {
235
+ return elements[0]
236
+ })
237
+ })
253
238
  }
254
239
 
255
240
  /**
@@ -262,16 +247,12 @@ function elementLocated(locator) {
262
247
  */
263
248
  function elementsLocated(locator) {
264
249
  locator = by.checkedLocator(locator)
265
- let locatorStr =
266
- typeof locator === 'function' ? 'by function()' : locator + ''
267
- return new Condition(
268
- 'for at least one element to be located ' + locatorStr,
269
- function (driver) {
270
- return driver.findElements(locator).then(function (elements) {
271
- return elements.length > 0 ? elements : null
272
- })
273
- }
274
- )
250
+ let locatorStr = typeof locator === 'function' ? 'by function()' : locator + ''
251
+ return new Condition('for at least one element to be located ' + locatorStr, function (driver) {
252
+ return driver.findElements(locator).then(function (elements) {
253
+ return elements.length > 0 ? elements : null
254
+ })
255
+ })
275
256
  }
276
257
 
277
258
  /**
@@ -293,7 +274,7 @@ function stalenessOf(element) {
293
274
  return true
294
275
  }
295
276
  throw e
296
- }
277
+ },
297
278
  )
298
279
  })
299
280
  }
@@ -404,9 +385,7 @@ function elementTextIs(element, text) {
404
385
  */
405
386
  function elementTextContains(element, substr) {
406
387
  return new WebElementCondition('until element text contains', function () {
407
- return element
408
- .getText()
409
- .then((t) => (t.indexOf(substr) != -1 ? element : null))
388
+ return element.getText().then((t) => (t.indexOf(substr) != -1 ? element : null))
410
389
  })
411
390
  }
412
391
 
package/lib/util.js CHANGED
@@ -37,10 +37,7 @@ function isPromise(value) {
37
37
  try {
38
38
  // Use array notation so the Closure compiler does not obfuscate away our
39
39
  // contract.
40
- return (
41
- (typeof value === 'object' || typeof value === 'function') &&
42
- typeof value['then'] === 'function'
43
- )
40
+ return (typeof value === 'object' || typeof value === 'function') && typeof value['then'] === 'function'
44
41
  } catch (ex) {
45
42
  return false
46
43
  }
@@ -119,14 +119,7 @@ class VirtualAuthenticatorOptions {
119
119
  * @see https://w3c.github.io/webauthn/#credential-parameters
120
120
  */
121
121
  class Credential {
122
- constructor(
123
- credentialId,
124
- isResidentCredential,
125
- rpId,
126
- userHandle,
127
- privateKey,
128
- signCount
129
- ) {
122
+ constructor(credentialId, isResidentCredential, rpId, userHandle, privateKey, signCount) {
130
123
  this._id = credentialId
131
124
  this._isResidentCredential = isResidentCredential
132
125
  this._rpId = rpId
@@ -207,9 +200,7 @@ class Credential {
207
200
  }
208
201
 
209
202
  if (this.userHandle() != null) {
210
- credentialData['userHandle'] = Buffer.from(this._userHandle).toString(
211
- 'base64url'
212
- )
203
+ credentialData['userHandle'] = Buffer.from(this._userHandle).toString('base64url')
213
204
  }
214
205
 
215
206
  return credentialData
@@ -222,9 +213,7 @@ class Credential {
222
213
  let id = new Uint8Array(Buffer.from(data['credentialId'], 'base64url'))
223
214
  let isResidentCredential = data['isResidentCredential']
224
215
  let rpId = data['rpId']
225
- let privateKey = Buffer.from(data['privateKey'], 'base64url').toString(
226
- 'binary'
227
- )
216
+ let privateKey = Buffer.from(data['privateKey'], 'base64url').toString('binary')
228
217
  let signCount = data['signCount']
229
218
  let userHandle
230
219
 
@@ -233,14 +222,7 @@ class Credential {
233
222
  } else {
234
223
  userHandle = null
235
224
  }
236
- return new Credential(
237
- id,
238
- isResidentCredential,
239
- rpId,
240
- userHandle,
241
- privateKey,
242
- signCount
243
- )
225
+ return new Credential(id, isResidentCredential, rpId, userHandle, privateKey, signCount)
244
226
  }
245
227
  }
246
228