selenium-webdriver 4.0.0 → 4.1.2
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 +523 -552
- package/LICENSE +1 -1
- package/NOTICE +1 -1
- package/README.md +4 -4
- package/chrome.js +10 -6
- package/chromium.js +91 -30
- package/devtools/CDPConnection.js +9 -4
- package/devtools/networkinterceptor.js +60 -61
- package/edge.js +10 -8
- package/example/google_search.js +1 -1
- package/firefox.js +32 -17
- package/http/index.js +13 -14
- package/http/util.js +14 -20
- package/index.js +15 -15
- package/io/index.js +58 -55
- package/io/zip.js +1 -3
- package/lib/atoms/find-elements.js +2 -2
- package/lib/by.js +9 -10
- package/lib/capabilities.js +1 -1
- package/lib/command.js +6 -11
- package/lib/error.js +24 -19
- package/lib/http.js +62 -153
- package/lib/input.js +71 -5
- package/lib/promise.js +12 -17
- package/lib/proxy.js +15 -5
- package/lib/session.js +1 -1
- package/lib/webdriver.js +410 -226
- package/net/index.js +14 -7
- package/net/portprober.js +5 -4
- package/opera.js +19 -22
- package/package.json +2 -3
- package/remote/index.js +13 -10
- package/testing/index.js +21 -16
package/LICENSE
CHANGED
|
@@ -187,7 +187,7 @@
|
|
|
187
187
|
same "printed page" as the copyright notice for easier
|
|
188
188
|
identification within third-party archives.
|
|
189
189
|
|
|
190
|
-
Copyright
|
|
190
|
+
Copyright 2022 Software Freedom Conservancy (SFC)
|
|
191
191
|
|
|
192
192
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
193
193
|
you may not use this file except in compliance with the License.
|
package/NOTICE
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Copyright 2011-
|
|
1
|
+
Copyright 2011-2022 Software Freedom Conservancy
|
|
2
2
|
Copyright 2004-2011 Selenium committers
|
package/README.md
CHANGED
|
@@ -33,10 +33,10 @@ The sample below and others are included in the `example` directory. You may
|
|
|
33
33
|
also find the tests for selenium-webdriver informative.
|
|
34
34
|
|
|
35
35
|
```javascript
|
|
36
|
-
const {Builder, By, Key, until} = require('selenium-webdriver');
|
|
36
|
+
const {Builder, Browser, By, Key, until} = require('selenium-webdriver');
|
|
37
37
|
|
|
38
38
|
(async function example() {
|
|
39
|
-
let driver = await new Builder().forBrowser(
|
|
39
|
+
let driver = await new Builder().forBrowser(Browser.FIREFOX).build();
|
|
40
40
|
try {
|
|
41
41
|
await driver.get('http://www.google.com/ncr');
|
|
42
42
|
await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN);
|
|
@@ -60,7 +60,7 @@ const chrome = require('selenium-webdriver/chrome');
|
|
|
60
60
|
const firefox = require('selenium-webdriver/firefox');
|
|
61
61
|
|
|
62
62
|
let driver = new webdriver.Builder()
|
|
63
|
-
.forBrowser(
|
|
63
|
+
.forBrowser(webdriver.Browser.FIREFOX)
|
|
64
64
|
.setChromeOptions(/* ... */)
|
|
65
65
|
.setFirefoxOptions(/* ... */)
|
|
66
66
|
.build();
|
|
@@ -99,7 +99,7 @@ API:
|
|
|
99
99
|
|
|
100
100
|
```javascript
|
|
101
101
|
let driver = new webdriver.Builder()
|
|
102
|
-
.forBrowser(
|
|
102
|
+
.forBrowser(webdriver.Browser.FIREFOX)
|
|
103
103
|
.usingServer('http://localhost:4444/wd/hub')
|
|
104
104
|
.build();
|
|
105
105
|
```
|
package/chrome.js
CHANGED
|
@@ -286,9 +286,13 @@ Driver.getDefaultService = getDefaultService
|
|
|
286
286
|
Driver.prototype.VENDOR_COMMAND_PREFIX = 'goog'
|
|
287
287
|
|
|
288
288
|
// PUBLIC API
|
|
289
|
-
|
|
290
|
-
exports
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
289
|
+
|
|
290
|
+
module.exports = {
|
|
291
|
+
Driver: Driver,
|
|
292
|
+
Options,
|
|
293
|
+
ServiceBuilder ,
|
|
294
|
+
getDefaultService,
|
|
295
|
+
setDefaultService,
|
|
296
|
+
locateSynchronously
|
|
297
|
+
}
|
|
298
|
+
|
package/chromium.js
CHANGED
|
@@ -92,11 +92,13 @@ const Command = {
|
|
|
92
92
|
LAUNCH_APP: 'launchApp',
|
|
93
93
|
GET_NETWORK_CONDITIONS: 'getNetworkConditions',
|
|
94
94
|
SET_NETWORK_CONDITIONS: 'setNetworkConditions',
|
|
95
|
+
DELETE_NETWORK_CONDITIONS: 'deleteNetworkConditions',
|
|
95
96
|
SEND_DEVTOOLS_COMMAND: 'sendDevToolsCommand',
|
|
96
97
|
SEND_AND_GET_DEVTOOLS_COMMAND: 'sendAndGetDevToolsCommand',
|
|
97
98
|
SET_PERMISSION: 'setPermission',
|
|
98
99
|
GET_CAST_SINKS: 'getCastSinks',
|
|
99
100
|
SET_CAST_SINK_TO_USE: 'setCastSinkToUse',
|
|
101
|
+
START_CAST_DESKTOP_MIRRORING: 'startDesktopMirroring',
|
|
100
102
|
START_CAST_TAB_MIRRORING: 'setCastTabMirroring',
|
|
101
103
|
GET_CAST_ISSUE_MESSAGE: 'getCastIssueMessage',
|
|
102
104
|
STOP_CASTING: 'stopCasting',
|
|
@@ -105,6 +107,7 @@ const Command = {
|
|
|
105
107
|
/**
|
|
106
108
|
* Creates a command executor with support for Chromium's custom commands.
|
|
107
109
|
* @param {!Promise<string>} url The server's URL.
|
|
110
|
+
* @param vendorPrefix
|
|
108
111
|
* @return {!command.Executor} The new command executor.
|
|
109
112
|
*/
|
|
110
113
|
function createExecutor(url, vendorPrefix) {
|
|
@@ -135,6 +138,11 @@ function configureExecutor(executor, vendorPrefix) {
|
|
|
135
138
|
'POST',
|
|
136
139
|
'/session/:sessionId/chromium/network_conditions'
|
|
137
140
|
)
|
|
141
|
+
executor.defineCommand(
|
|
142
|
+
Command.DELETE_NETWORK_CONDITIONS,
|
|
143
|
+
'DELETE',
|
|
144
|
+
'/session/:sessionId/chromium/network_conditions'
|
|
145
|
+
)
|
|
138
146
|
executor.defineCommand(
|
|
139
147
|
Command.SEND_DEVTOOLS_COMMAND,
|
|
140
148
|
'POST',
|
|
@@ -160,6 +168,11 @@ function configureExecutor(executor, vendorPrefix) {
|
|
|
160
168
|
'POST',
|
|
161
169
|
`/session/:sessionId/${vendorPrefix}/cast/set_sink_to_use`
|
|
162
170
|
)
|
|
171
|
+
executor.defineCommand(
|
|
172
|
+
Command.START_CAST_DESKTOP_MIRRORING,
|
|
173
|
+
'POST',
|
|
174
|
+
`/session/:sessionId/${vendorPrefix}/cast/start_desktop_mirroring`
|
|
175
|
+
)
|
|
163
176
|
executor.defineCommand(
|
|
164
177
|
Command.START_CAST_TAB_MIRRORING,
|
|
165
178
|
'POST',
|
|
@@ -217,8 +230,8 @@ class ServiceBuilder extends remote.DriverService.Builder {
|
|
|
217
230
|
* Enables Chrome logging.
|
|
218
231
|
* @returns {!ServiceBuilder} A self reference.
|
|
219
232
|
*/
|
|
220
|
-
|
|
221
|
-
return this.addArguments('--enable-chrome-logs')
|
|
233
|
+
enableChromeLogging() {
|
|
234
|
+
return this.addArguments('--enable-chrome-logs')
|
|
222
235
|
}
|
|
223
236
|
|
|
224
237
|
/**
|
|
@@ -292,7 +305,7 @@ class Options extends Capabilities {
|
|
|
292
305
|
* @return {!Options} A self reference.
|
|
293
306
|
*/
|
|
294
307
|
debuggerAddress(address) {
|
|
295
|
-
this.options_.debuggerAddress = address
|
|
308
|
+
this.options_.debuggerAddress = address
|
|
296
309
|
return this
|
|
297
310
|
}
|
|
298
311
|
|
|
@@ -358,8 +371,11 @@ class Options extends Capabilities {
|
|
|
358
371
|
* @return {!Options} A self reference.
|
|
359
372
|
*/
|
|
360
373
|
addExtensions(...args) {
|
|
361
|
-
let
|
|
362
|
-
|
|
374
|
+
let extensions = this.options_.extensions || new Extensions()
|
|
375
|
+
extensions.add(...args)
|
|
376
|
+
if (extensions.length) {
|
|
377
|
+
this.options_.extensions = extensions
|
|
378
|
+
}
|
|
363
379
|
return this
|
|
364
380
|
}
|
|
365
381
|
|
|
@@ -584,28 +600,47 @@ class Options extends Capabilities {
|
|
|
584
600
|
}
|
|
585
601
|
return this
|
|
586
602
|
}
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
/**
|
|
606
|
+
* A list of extensions to install when launching the browser.
|
|
607
|
+
*/
|
|
608
|
+
class Extensions {
|
|
609
|
+
constructor() {
|
|
610
|
+
this.extensions = []
|
|
611
|
+
}
|
|
587
612
|
|
|
588
613
|
/**
|
|
589
|
-
*
|
|
590
|
-
|
|
614
|
+
* @return {number} The length of the extensions list.
|
|
615
|
+
*/
|
|
616
|
+
get length() {
|
|
617
|
+
return this.extensions.length
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
/**
|
|
621
|
+
* Add additional extensions to install when launching the browser. Each
|
|
622
|
+
* extension should be specified as the path to the packed CRX file, or a
|
|
623
|
+
* Buffer for an extension.
|
|
591
624
|
*
|
|
592
|
-
* @
|
|
593
|
-
*
|
|
625
|
+
* @param {...(string|!Buffer|!Array<(string|!Buffer)>)} args The
|
|
626
|
+
* extensions to add.
|
|
627
|
+
*/
|
|
628
|
+
add(...args) {
|
|
629
|
+
this.extensions = this.extensions.concat(...args)
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
/**
|
|
633
|
+
* @return {!Object} A serialized representation of this Extensions object.
|
|
594
634
|
*/
|
|
595
635
|
[Symbols.serialize]() {
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
extension
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
.read(/** @type {string} */ (extension))
|
|
605
|
-
.then((buffer) => buffer.toString('base64'))
|
|
606
|
-
})
|
|
607
|
-
}
|
|
608
|
-
return super[Symbols.serialize]()
|
|
636
|
+
return this.extensions.map(function (extension) {
|
|
637
|
+
if (Buffer.isBuffer(extension)) {
|
|
638
|
+
return extension.toString('base64')
|
|
639
|
+
}
|
|
640
|
+
return io
|
|
641
|
+
.read(/** @type {string} */ (extension))
|
|
642
|
+
.then((buffer) => buffer.toString('base64'))
|
|
643
|
+
})
|
|
609
644
|
}
|
|
610
645
|
}
|
|
611
646
|
|
|
@@ -626,14 +661,12 @@ class Driver extends webdriver.WebDriver {
|
|
|
626
661
|
*/
|
|
627
662
|
static createSession(caps, opt_serviceExecutor) {
|
|
628
663
|
let executor
|
|
629
|
-
let onQuit
|
|
630
664
|
if (opt_serviceExecutor instanceof http.Executor) {
|
|
631
665
|
executor = opt_serviceExecutor
|
|
632
666
|
configureExecutor(executor, this.VENDOR_COMMAND_PREFIX)
|
|
633
667
|
} else {
|
|
634
668
|
let service = opt_serviceExecutor || this.getDefaultService()
|
|
635
669
|
executor = createExecutor(service.start(), this.VENDOR_COMMAND_PREFIX)
|
|
636
|
-
onQuit = () => service.kill()
|
|
637
670
|
}
|
|
638
671
|
|
|
639
672
|
// W3C spec requires noProxy value to be an array of strings, but Chromium
|
|
@@ -646,7 +679,7 @@ class Driver extends webdriver.WebDriver {
|
|
|
646
679
|
}
|
|
647
680
|
}
|
|
648
681
|
|
|
649
|
-
return /** @type {!Driver} */ (super.createSession(executor, caps
|
|
682
|
+
return /** @type {!Driver} */ (super.createSession(executor, caps))
|
|
650
683
|
}
|
|
651
684
|
|
|
652
685
|
/**
|
|
@@ -677,6 +710,15 @@ class Driver extends webdriver.WebDriver {
|
|
|
677
710
|
return this.execute(new command.Command(Command.GET_NETWORK_CONDITIONS))
|
|
678
711
|
}
|
|
679
712
|
|
|
713
|
+
/**
|
|
714
|
+
* Schedules a command to delete Chromium network emulation settings.
|
|
715
|
+
* @return {!Promise} A promise that will be resolved when network
|
|
716
|
+
* emulation settings have been deleted.
|
|
717
|
+
*/
|
|
718
|
+
deleteNetworkConditions() {
|
|
719
|
+
return this.execute(new command.Command(Command.DELETE_NETWORK_CONDITIONS))
|
|
720
|
+
}
|
|
721
|
+
|
|
680
722
|
/**
|
|
681
723
|
* Schedules a command to set Chromium network emulation settings.
|
|
682
724
|
*
|
|
@@ -725,11 +767,11 @@ class Driver extends webdriver.WebDriver {
|
|
|
725
767
|
}
|
|
726
768
|
|
|
727
769
|
/**
|
|
728
|
-
*
|
|
770
|
+
* Sends an arbitrary devtools command to the browser and get the result.
|
|
729
771
|
*
|
|
730
772
|
* @param {string} cmd The name of the command to send.
|
|
731
773
|
* @param {Object=} params The command parameters.
|
|
732
|
-
* @return {!Promise<
|
|
774
|
+
* @return {!Promise<string>} A promise that will be resolved when the command
|
|
733
775
|
* has finished.
|
|
734
776
|
* @see <https://chromedevtools.github.io/devtools-protocol/>
|
|
735
777
|
*/
|
|
@@ -811,6 +853,23 @@ class Driver extends webdriver.WebDriver {
|
|
|
811
853
|
)
|
|
812
854
|
}
|
|
813
855
|
|
|
856
|
+
/**
|
|
857
|
+
* Initiates desktop mirroring for the current browser tab on the specified device.
|
|
858
|
+
*
|
|
859
|
+
* @param {String} deviceName name of the target device.
|
|
860
|
+
* @return {!promise.Thenable<void>} A promise that will be resolved
|
|
861
|
+
* when the mirror command has been issued to the device.
|
|
862
|
+
*/
|
|
863
|
+
startDesktopMirroring(deviceName) {
|
|
864
|
+
return this.schedule(
|
|
865
|
+
new command.Command(Command.START_CAST_DESKTOP_MIRRORING).setParameter(
|
|
866
|
+
'sinkName',
|
|
867
|
+
deviceName
|
|
868
|
+
),
|
|
869
|
+
'Driver.startDesktopMirroring(' + deviceName + ')'
|
|
870
|
+
)
|
|
871
|
+
}
|
|
872
|
+
|
|
814
873
|
/**
|
|
815
874
|
* Initiates tab mirroring for the current browser tab on the specified device.
|
|
816
875
|
*
|
|
@@ -860,6 +919,8 @@ class Driver extends webdriver.WebDriver {
|
|
|
860
919
|
|
|
861
920
|
// PUBLIC API
|
|
862
921
|
|
|
863
|
-
exports
|
|
864
|
-
|
|
865
|
-
|
|
922
|
+
module.exports = {
|
|
923
|
+
Driver,
|
|
924
|
+
Options,
|
|
925
|
+
ServiceBuilder,
|
|
926
|
+
}
|
|
@@ -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,
|
|
24
|
-
|
|
26
|
+
execute(method, params, callback) {
|
|
27
|
+
let message = {
|
|
25
28
|
method,
|
|
26
|
-
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
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
get headers() {
|
|
43
|
+
return this.returnHeaders
|
|
44
|
+
}
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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
|
-
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
get status() {
|
|
56
|
+
return this.returnStatus
|
|
57
|
+
}
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
get body() {
|
|
69
|
+
let buff = Buffer.from(this.returnBody, 'utf-8')
|
|
70
|
+
return buff.toString('base64')
|
|
71
|
+
}
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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/edge.js
CHANGED
|
@@ -94,7 +94,7 @@ let defaultService = null
|
|
|
94
94
|
|
|
95
95
|
/**
|
|
96
96
|
* Creates {@link selenium-webdriver/remote.DriverService} instances that manage
|
|
97
|
-
* a [
|
|
97
|
+
* a [MSEdgeDriver](https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/)
|
|
98
98
|
* server in a child process.
|
|
99
99
|
*/
|
|
100
100
|
class ServiceBuilder extends chromium.ServiceBuilder {
|
|
@@ -130,7 +130,7 @@ class Options extends chromium.Options {
|
|
|
130
130
|
* The binary path be absolute or relative to the msedgedriver server
|
|
131
131
|
* executable, but it must exist on the machine that will launch edge chromium.
|
|
132
132
|
*
|
|
133
|
-
* @param {string} path The path to the
|
|
133
|
+
* @param {string} path The path to the msedgedriver binary to use.
|
|
134
134
|
* @return {!Options} A self reference.
|
|
135
135
|
*/
|
|
136
136
|
setEdgeChromiumBinaryPath(path) {
|
|
@@ -210,9 +210,11 @@ Driver.getDefaultService = getDefaultService
|
|
|
210
210
|
|
|
211
211
|
// PUBLIC API
|
|
212
212
|
|
|
213
|
-
exports
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
213
|
+
module.exports = {
|
|
214
|
+
Driver,
|
|
215
|
+
Options,
|
|
216
|
+
ServiceBuilder,
|
|
217
|
+
getDefaultService,
|
|
218
|
+
setDefaultService,
|
|
219
|
+
locateSynchronously,
|
|
220
|
+
}
|
package/example/google_search.js
CHANGED
package/firefox.js
CHANGED
|
@@ -116,6 +116,7 @@
|
|
|
116
116
|
|
|
117
117
|
'use strict'
|
|
118
118
|
|
|
119
|
+
const fs = require('fs')
|
|
119
120
|
const path = require('path')
|
|
120
121
|
const Symbols = require('./lib/symbols')
|
|
121
122
|
const command = require('./lib/command')
|
|
@@ -222,7 +223,7 @@ async function buildProfile(template, extensions) {
|
|
|
222
223
|
dir = await io.tmpDir()
|
|
223
224
|
if (template) {
|
|
224
225
|
await io.copyDir(
|
|
225
|
-
/** @type {string} */(template),
|
|
226
|
+
/** @type {string} */ (template),
|
|
226
227
|
dir,
|
|
227
228
|
/(parent\.lock|lock|\.parentlock)/
|
|
228
229
|
)
|
|
@@ -400,7 +401,11 @@ class Options extends Capabilities {
|
|
|
400
401
|
* @param {string} androidPackage The package to use
|
|
401
402
|
* @return {!Options} A self reference
|
|
402
403
|
*/
|
|
403
|
-
enableMobile(
|
|
404
|
+
enableMobile(
|
|
405
|
+
androidPackage = 'org.mozilla.firefox',
|
|
406
|
+
androidActivity = null,
|
|
407
|
+
deviceSerial = null
|
|
408
|
+
) {
|
|
404
409
|
this.firefoxOptions_().androidPackage = androidPackage
|
|
405
410
|
|
|
406
411
|
if (androidActivity) {
|
|
@@ -457,11 +462,11 @@ function findGeckoDriver() {
|
|
|
457
462
|
if (!exe) {
|
|
458
463
|
throw Error(
|
|
459
464
|
'The ' +
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
+
GECKO_DRIVER_EXE +
|
|
466
|
+
' executable could not be found on the current ' +
|
|
467
|
+
'PATH. Please download the latest version from ' +
|
|
468
|
+
'https://github.com/mozilla/geckodriver/releases/ ' +
|
|
469
|
+
'and ensure it can be found on your PATH.'
|
|
465
470
|
)
|
|
466
471
|
}
|
|
467
472
|
return exe
|
|
@@ -482,8 +487,8 @@ function findInProgramFiles(file) {
|
|
|
482
487
|
return exists
|
|
483
488
|
? files[0]
|
|
484
489
|
: io.exists(files[1]).then(function (exists) {
|
|
485
|
-
|
|
486
|
-
|
|
490
|
+
return exists ? files[1] : null
|
|
491
|
+
})
|
|
487
492
|
})
|
|
488
493
|
}
|
|
489
494
|
|
|
@@ -617,7 +622,7 @@ class Driver extends webdriver.WebDriver {
|
|
|
617
622
|
* implementation.
|
|
618
623
|
* @override
|
|
619
624
|
*/
|
|
620
|
-
setFileDetector() {
|
|
625
|
+
setFileDetector() {}
|
|
621
626
|
|
|
622
627
|
/**
|
|
623
628
|
* Get the context that is currently in effect.
|
|
@@ -666,7 +671,15 @@ class Driver extends webdriver.WebDriver {
|
|
|
666
671
|
* @see #uninstallAddon
|
|
667
672
|
*/
|
|
668
673
|
async installAddon(path, temporary = false) {
|
|
669
|
-
let
|
|
674
|
+
let stats = fs.statSync(path)
|
|
675
|
+
let buf;
|
|
676
|
+
if (stats.isDirectory()) {
|
|
677
|
+
let zip = new Zip()
|
|
678
|
+
await zip.addDir(path)
|
|
679
|
+
buf = await zip.toBuffer('DEFLATE')
|
|
680
|
+
} else {
|
|
681
|
+
buf = await io.read(path)
|
|
682
|
+
}
|
|
670
683
|
return this.execute(
|
|
671
684
|
new command.Command(ExtensionCommand.INSTALL_ADDON)
|
|
672
685
|
.setParameter('addon', buf.toString('base64'))
|
|
@@ -805,9 +818,11 @@ Channel.NIGHTLY = new Channel(
|
|
|
805
818
|
|
|
806
819
|
// PUBLIC API
|
|
807
820
|
|
|
808
|
-
exports
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
821
|
+
module.exports = {
|
|
822
|
+
Channel,
|
|
823
|
+
Context,
|
|
824
|
+
Driver,
|
|
825
|
+
Options,
|
|
826
|
+
ServiceBuilder,
|
|
827
|
+
locateSynchronously,
|
|
828
|
+
}
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
267
|
+
const body = []
|
|
269
268
|
response.on('data', body.push.bind(body))
|
|
270
269
|
response.on('end', function () {
|
|
271
|
-
|
|
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
|
-
|
|
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
|