selenium-webdriver 4.10.0 → 4.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,483 @@
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 { NavigationInfo } = require('./browsingContextTypes')
19
+
20
+ class Header {
21
+ constructor(name, value, binaryValue) {
22
+ this._name = name
23
+ this._value = value
24
+ this._binaryValue = binaryValue
25
+ }
26
+
27
+ get name() {
28
+ return this._name
29
+ }
30
+
31
+ get value() {
32
+ return this._value
33
+ }
34
+
35
+ get binaryValue() {
36
+ return this._binaryValue
37
+ }
38
+ }
39
+
40
+ class Cookie {
41
+ constructor(
42
+ name,
43
+ value,
44
+ binaryValue,
45
+ domain,
46
+ path,
47
+ expires,
48
+ size,
49
+ httpOnly,
50
+ secure,
51
+ sameSite
52
+ ) {
53
+ this._name = name
54
+ this._value = value
55
+ this._binaryValue = binaryValue
56
+ this._domain = domain
57
+ this._path = path
58
+ this._expires = expires
59
+ this._size = size
60
+ this._httpOnly = httpOnly
61
+ this._secure = secure
62
+ this._sameSite = sameSite
63
+ }
64
+
65
+ get name() {
66
+ return this._name
67
+ }
68
+
69
+ get value() {
70
+ return this._value
71
+ }
72
+
73
+ get binaryValue() {
74
+ return this._binaryValue
75
+ }
76
+
77
+ get domain() {
78
+ return this._domain
79
+ }
80
+
81
+ get path() {
82
+ return this._path
83
+ }
84
+
85
+ get expires() {
86
+ return this._expires
87
+ }
88
+
89
+ get size() {
90
+ return this._size
91
+ }
92
+
93
+ get httpOnly() {
94
+ return this._httpOnly
95
+ }
96
+
97
+ get secure() {
98
+ return this._secure
99
+ }
100
+
101
+ get sameSite() {
102
+ return this._sameSite
103
+ }
104
+ }
105
+
106
+ // No tests written for FetchTimingInfo. Must be updated after browsers implment it and corresponding WPT test are written.
107
+ class FetchTimingInfo {
108
+ constructor(
109
+ originTime,
110
+ requestTime,
111
+ redirectStart,
112
+ redirectEnd,
113
+ fetchStart,
114
+ dnsStart,
115
+ dnsEnd,
116
+ connectStart,
117
+ connectEnd,
118
+ tlsStart,
119
+ requestStart,
120
+ responseStart,
121
+ responseEnd
122
+ ) {
123
+ this._originTime = originTime
124
+ this._requestTime = requestTime
125
+ this._redirectStart = redirectStart
126
+ this._redirectEnd = redirectEnd
127
+ this._fetchStart = fetchStart
128
+ this._dnsStart = dnsStart
129
+ this._dnsEnd = dnsEnd
130
+ this._connectStart = connectStart
131
+ this._connectEnd = connectEnd
132
+ this._tlsStart = tlsStart
133
+ this._requestStart = requestStart
134
+ this._responseStart = responseStart
135
+ this._responseEnd = responseEnd
136
+ }
137
+
138
+ get originTime() {
139
+ return this._originTime
140
+ }
141
+
142
+ get requestTime() {
143
+ return this._requestTime
144
+ }
145
+
146
+ get redirectStart() {
147
+ return this._redirectStart
148
+ }
149
+
150
+ get redirectEnd() {
151
+ return this._redirectEnd
152
+ }
153
+
154
+ get fetchStart() {
155
+ return this._fetchStart
156
+ }
157
+
158
+ get dnsStart() {
159
+ return this._dnsStart
160
+ }
161
+
162
+ get dnsEnd() {
163
+ return this._dnsEnd
164
+ }
165
+
166
+ get connectStart() {
167
+ return this._connectStart
168
+ }
169
+
170
+ get connectEnd() {
171
+ return this._connectEnd
172
+ }
173
+
174
+ get tlsStart() {
175
+ return this._tlsStart
176
+ }
177
+
178
+ get requestStart() {
179
+ return this._requestStart
180
+ }
181
+
182
+ get responseStart() {
183
+ return this._responseStart
184
+ }
185
+
186
+ get responseEnd() {
187
+ return this._responseEnd
188
+ }
189
+ }
190
+
191
+ class RequestData {
192
+ constructor(
193
+ request,
194
+ url,
195
+ method,
196
+ headers,
197
+ cookies,
198
+ headersSize,
199
+ bodySize,
200
+ timings
201
+ ) {
202
+ this._request = request
203
+ this._url = url
204
+ this._method = method
205
+ this._headers = []
206
+ headers.forEach((header) => {
207
+ let name = header.name
208
+ let value = 'value' in header ? header.value : null
209
+ let binaryValue = 'binaryValue' in header ? header.binaryValue : null
210
+
211
+ this._headers.push(new Header(name, value, binaryValue))
212
+ })
213
+
214
+ this._cookies = []
215
+ cookies.forEach((cookie) => {
216
+ let name = cookie.name
217
+ let domain = cookie.domain
218
+ let path = cookie.path
219
+ let size = cookie.size
220
+ let httpOnly = cookie.httpOnly
221
+ let secure = cookie.secure
222
+ let sameSite = cookie.sameSite
223
+ let value = 'value' in cookie ? cookie.value : null
224
+ let binaryValue = 'binaryValue' in cookie ? cookie.binaryValue : null
225
+ let expires = 'expires' in cookie ? cookie.expires : null
226
+
227
+ this._cookies.push(
228
+ new Cookie(
229
+ name,
230
+ value,
231
+ binaryValue,
232
+ domain,
233
+ path,
234
+ expires,
235
+ size,
236
+ httpOnly,
237
+ secure,
238
+ sameSite
239
+ )
240
+ )
241
+ })
242
+ this._headersSize = headersSize
243
+ this._bodySize = bodySize
244
+ this._timings = new FetchTimingInfo(
245
+ timings.originTime,
246
+ timings.requestTime,
247
+ timings.redirectStart,
248
+ timings.redirectEnd,
249
+ timings.fetchStart,
250
+ timings.dnsStart,
251
+ timings.dnsEnd,
252
+ timings.connectStart,
253
+ timings.connectEnd,
254
+ timings.tlsStart,
255
+ timings.requestStart,
256
+ timings.responseStart,
257
+ timings.responseEnd
258
+ )
259
+ }
260
+
261
+ get request() {
262
+ return this._request
263
+ }
264
+
265
+ get url() {
266
+ return this._url
267
+ }
268
+
269
+ get method() {
270
+ return this._method
271
+ }
272
+
273
+ get headers() {
274
+ return this._headers
275
+ }
276
+
277
+ get cookies() {
278
+ return this._cookies
279
+ }
280
+
281
+ get headersSize() {
282
+ return this._headersSize
283
+ }
284
+
285
+ get bodySize() {
286
+ return this._bodySize
287
+ }
288
+
289
+ get timings() {
290
+ return this._timings
291
+ }
292
+ }
293
+
294
+ class BaseParameters {
295
+ constructor(id, navigation, redirectCount, request, timestamp) {
296
+ this._id = id
297
+ this._navigation =
298
+ navigation != null
299
+ ? new NavigationInfo(
300
+ navigation.context,
301
+ navigation.navigation,
302
+ navigation.timestamp,
303
+ navigation.url
304
+ )
305
+ : null
306
+ this._redirectCount = redirectCount
307
+ this._request = new RequestData(
308
+ request.request,
309
+ request.url,
310
+ request.method,
311
+ request.headers,
312
+ request.cookies,
313
+ request.headersSize,
314
+ request.bodySize,
315
+ request.timings
316
+ )
317
+ this._timestamp = timestamp
318
+ }
319
+
320
+ get id() {
321
+ return this._id
322
+ }
323
+
324
+ get navigation() {
325
+ return this._navigation
326
+ }
327
+
328
+ get redirectCount() {
329
+ return this._redirectCount
330
+ }
331
+
332
+ get request() {
333
+ return this._request
334
+ }
335
+
336
+ get timestamp() {
337
+ return this._timestamp
338
+ }
339
+ }
340
+
341
+ class Initiator {
342
+ constructor(type, columnNumber, lineNumber, stackTrace, request) {
343
+ this._type = type
344
+ this._columnNumber = columnNumber
345
+ this._lineNumber = lineNumber
346
+ this._stackTrace = stackTrace
347
+ this._request = request
348
+ }
349
+
350
+ get type() {
351
+ return this._type
352
+ }
353
+
354
+ get columnNumber() {
355
+ return this._columnNumber
356
+ }
357
+
358
+ get lineNumber() {
359
+ return this._lineNumber
360
+ }
361
+
362
+ get stackTrace() {
363
+ return this._stackTrace
364
+ }
365
+
366
+ get request() {
367
+ return this._request
368
+ }
369
+ }
370
+
371
+ class BeforeRequestSent extends BaseParameters {
372
+ constructor(id, navigation, redirectCount, request, timestamp, initiator) {
373
+ super(id, navigation, redirectCount, request, timestamp)
374
+ this._initiator = new Initiator(
375
+ initiator.type,
376
+ initiator.columnNumber,
377
+ initiator.lineNumber,
378
+ initiator.stackTrace,
379
+ initiator.request
380
+ )
381
+ }
382
+
383
+ get initiator() {
384
+ return this._initiator
385
+ }
386
+ }
387
+
388
+ class ResponseData {
389
+ constructor(
390
+ url,
391
+ protocol,
392
+ status,
393
+ statusText,
394
+ fromCache,
395
+ headers,
396
+ mimeType,
397
+ bytesReceived,
398
+ headersSize,
399
+ bodySize,
400
+ content
401
+ ) {
402
+ this._url = url
403
+ this._protocol = protocol
404
+ this._status = status
405
+ this._statusText = statusText
406
+ this._fromCache = fromCache
407
+ this._headers = headers
408
+ this._mimeType = mimeType
409
+ this._bytesReceived = bytesReceived
410
+ this._headersSize = headersSize
411
+ this._bodySize = bodySize
412
+ this._content = content
413
+ }
414
+
415
+ get url() {
416
+ return this._url
417
+ }
418
+
419
+ get protocol() {
420
+ return this._protocol
421
+ }
422
+
423
+ get status() {
424
+ return this._status
425
+ }
426
+
427
+ get statusText() {
428
+ return this._statusText
429
+ }
430
+
431
+ get fromCache() {
432
+ return this._fromCache
433
+ }
434
+
435
+ get headers() {
436
+ return this._headers
437
+ }
438
+
439
+ get mimeType() {
440
+ return this._mimeType
441
+ }
442
+
443
+ get bytesReceived() {
444
+ return this._bytesReceived
445
+ }
446
+
447
+ get headerSize() {
448
+ return this._headersSize
449
+ }
450
+
451
+ get bodySize() {
452
+ return this._bodySize
453
+ }
454
+
455
+ get content() {
456
+ return this._content
457
+ }
458
+ }
459
+
460
+ class ResponseStarted extends BaseParameters {
461
+ constructor(id, navigation, redirectCount, request, timestamp, response) {
462
+ super(id, navigation, redirectCount, request, timestamp)
463
+ this._response = new ResponseData(
464
+ response.url,
465
+ response.protocol,
466
+ response.status,
467
+ response.statusText,
468
+ response.fromCache,
469
+ response.headers,
470
+ response.mimeType,
471
+ response.bytesReceived,
472
+ response.headerSize,
473
+ response.bodySize,
474
+ response.content
475
+ )
476
+ }
477
+
478
+ get response() {
479
+ return this._response
480
+ }
481
+ }
482
+
483
+ module.exports = { BeforeRequestSent, ResponseStarted }
@@ -123,7 +123,7 @@ class RemoteValue {
123
123
  this.sharedId = null
124
124
 
125
125
  if ('type' in remoteValue) {
126
- var typeString = remoteValue['type']
126
+ const typeString = remoteValue['type']
127
127
  if (PrimitiveType.findByName(typeString) != null) {
128
128
  this.type = PrimitiveType.findByName(typeString)
129
129
  } else if (NonPrimitiveType.findByName(typeString) != null) {
@@ -182,7 +182,7 @@ class ScriptManager {
182
182
 
183
183
  async addPreloadScript(
184
184
  functionDeclaration,
185
- argumentValueList = null,
185
+ argumentValueList = [],
186
186
  sandbox = null
187
187
  ) {
188
188
  const params = {
@@ -285,18 +285,18 @@ class ScriptManager {
285
285
  }
286
286
 
287
287
  createEvaluateResult(response) {
288
- var type = response.result.type
289
- var realmId = response.result.realm
290
- var evaluateResult
288
+ const type = response.result.type
289
+ const realmId = response.result.realm
290
+ let evaluateResult
291
291
 
292
292
  if (type === EvaluateResultType.SUCCESS) {
293
- var result = response.result.result
293
+ const result = response.result.result
294
294
  evaluateResult = new EvaluateResultSuccess(
295
295
  realmId,
296
296
  new RemoteValue(result)
297
297
  )
298
298
  } else {
299
- var exceptionDetails = response.result.exceptionDetails
299
+ const exceptionDetails = response.result.exceptionDetails
300
300
  evaluateResult = new EvaluateResultException(
301
301
  realmId,
302
302
  new ExceptionDetails(exceptionDetails)
@@ -306,7 +306,7 @@ class ScriptManager {
306
306
  }
307
307
 
308
308
  realmInfoMapper(realms) {
309
- var realmsList = []
309
+ const realmsList = []
310
310
  realms.forEach((realm) => {
311
311
  realmsList.push(RealmInfo.fromJson(realm))
312
312
  })
Binary file
Binary file
Binary file
package/chrome.js CHANGED
@@ -130,14 +130,7 @@
130
130
  const io = require('./io')
131
131
  const { Browser } = require('./lib/capabilities')
132
132
  const chromium = require('./chromium')
133
-
134
- /**
135
- * Name of the ChromeDriver executable.
136
- * @type {string}
137
- * @const
138
- */
139
- const CHROMEDRIVER_EXE =
140
- process.platform === 'win32' ? 'chromedriver.exe' : 'chromedriver'
133
+ const CHROME_CAPABILITY_KEY = 'goog:chromeOptions'
141
134
 
142
135
  /** @type {remote.DriverService} */
143
136
 
@@ -156,8 +149,7 @@ class ServiceBuilder extends chromium.ServiceBuilder {
156
149
  * cannot be found on the PATH.
157
150
  */
158
151
  constructor(opt_exe) {
159
- let exe = opt_exe || locateSynchronously()
160
- super(exe)
152
+ super(opt_exe)
161
153
  }
162
154
  }
163
155
 
@@ -229,7 +221,7 @@ class Driver extends chromium.Driver {
229
221
  static createSession(opt_config, opt_serviceExecutor) {
230
222
  let caps = opt_config || new Options()
231
223
  return /** @type {!Driver} */ (
232
- super.createSession(caps, opt_serviceExecutor)
224
+ super.createSession(caps, opt_serviceExecutor, 'goog', CHROME_CAPABILITY_KEY)
233
225
  )
234
226
  }
235
227
 
@@ -242,24 +234,12 @@ class Driver extends chromium.Driver {
242
234
  }
243
235
  }
244
236
 
245
- /**
246
- * _Synchronously_ attempts to locate the chromedriver executable on the current
247
- * system.
248
- *
249
- * @return {?string} the located executable, or `null`.
250
- */
251
- function locateSynchronously() {
252
- return io.findInPath(CHROMEDRIVER_EXE, true)
253
- }
254
-
255
- Options.prototype.CAPABILITY_KEY = 'goog:chromeOptions'
237
+ Options.prototype.CAPABILITY_KEY = CHROME_CAPABILITY_KEY
256
238
  Options.prototype.BROWSER_NAME_VALUE = Browser.CHROME
257
- Driver.prototype.VENDOR_COMMAND_PREFIX = 'goog'
258
239
 
259
240
  // PUBLIC API
260
241
  module.exports = {
261
- Driver: Driver,
242
+ Driver,
262
243
  Options,
263
244
  ServiceBuilder,
264
- locateSynchronously,
265
245
  }
package/chromium.js CHANGED
@@ -669,27 +669,38 @@ class Driver extends webdriver.WebDriver {
669
669
  /**
670
670
  * Creates a new session with the WebDriver server.
671
671
  *
672
- * @param {(Capabilities|Options)=} opt_config The configuration options.
672
+ * @param {(Capabilities|Options)=} caps The configuration options.
673
673
  * @param {(remote.DriverService|http.Executor)=} opt_serviceExecutor Either
674
674
  * a DriverService to use for the remote end, or a preconfigured executor
675
675
  * for an externally managed endpoint. If neither is provided, the
676
676
  * {@linkplain ##getDefaultService default service} will be used by
677
677
  * default.
678
+ * @param vendorPrefix Either 'goog' or 'ms'
679
+ * @param vendorCapabilityKey Either 'goog:chromeOptions' or 'ms:edgeOptions'
678
680
  * @return {!Driver} A new driver instance.
679
681
  */
680
- static createSession(caps, opt_serviceExecutor) {
682
+ static createSession(caps, opt_serviceExecutor,
683
+ vendorPrefix = '', vendorCapabilityKey = '') {
681
684
  let executor
682
685
  let onQuit
683
686
  if (opt_serviceExecutor instanceof http.Executor) {
684
687
  executor = opt_serviceExecutor
685
- configureExecutor(executor, this.VENDOR_COMMAND_PREFIX)
688
+ configureExecutor(executor, vendorPrefix)
686
689
  } else {
687
690
  let service = opt_serviceExecutor || this.getDefaultService()
688
691
  if (!service.getExecutable()) {
689
- service.setExecutable(getPath(service, caps))
692
+ const {driverPath, browserPath} = getPath(caps)
693
+ service.setExecutable(driverPath)
694
+ const vendorOptions = caps.get(vendorCapabilityKey)
695
+ if (vendorOptions) {
696
+ vendorOptions['binary'] = browserPath
697
+ caps.set(vendorCapabilityKey, vendorOptions)
698
+ } else {
699
+ caps.set(vendorCapabilityKey, {binary: browserPath})
700
+ }
690
701
  }
691
702
  onQuit = () => service.kill()
692
- executor = createExecutor(service.start(), this.VENDOR_COMMAND_PREFIX)
703
+ executor = createExecutor(service.start(), vendorPrefix)
693
704
  }
694
705
 
695
706
  // W3C spec requires noProxy value to be an array of strings, but Chromium
@@ -22,38 +22,23 @@
22
22
  */
23
23
 
24
24
  const { driverLocation } = require('./seleniumManager')
25
- const fs = require('fs')
26
25
 
27
26
  /**
28
27
  * Determines the path of the correct Selenium Manager binary
29
- * @returns {string}
28
+ * @returns {{browserPath: string, driverPath: string}} path of the driver
29
+ * and browser location
30
30
  */
31
- function getPath(service, capabilities) {
31
+ function getPath(capabilities) {
32
32
  try {
33
- return pathExists(service.getExecutable()) || driverLocation(capabilities)
33
+ return driverLocation(capabilities)
34
34
  } catch (e) {
35
35
  throw Error(
36
36
  `Unable to obtain browser driver.
37
37
  For more information on how to install drivers see
38
- https://www.selenium.dev/documentation/webdriver/getting_started/install_drivers/. ${e}`
38
+ https://www.selenium.dev/documentation/webdriver/troubleshooting/errors/driver_location/. ${e}`
39
39
  )
40
40
  }
41
41
  }
42
42
 
43
- /**
44
- * _Synchronously_ attempts to locate the driver executable on the current
45
- * system.
46
- *
47
- * @param {!string} driverPath
48
- *
49
- * @return {?string} the located executable, or `null`.
50
- */
51
- function pathExists(driverPath) {
52
- if (!driverPath || !fs.existsSync(driverPath)) {
53
- return null
54
- }
55
- return driverPath
56
- }
57
-
58
43
  // PUBLIC API
59
44
  module.exports = { getPath }