selenium-webdriver 4.0.0-alpha.4 → 4.0.0-alpha.8
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/.eslintrc.js +27 -0
- package/.prettierrc +4 -0
- package/CHANGES.md +22 -1
- package/README.md +4 -4
- package/chrome.js +72 -590
- package/chromium.js +1024 -0
- package/devtools/CDPConnection.js +37 -0
- package/devtools/generator/protocol-dts-generator.js +429 -0
- package/edge.js +124 -86
- package/firefox.js +201 -202
- package/http/index.js +131 -115
- package/http/util.js +56 -64
- package/ie.js +180 -104
- package/index.js +246 -199
- package/io/exec.js +34 -39
- package/io/index.js +141 -151
- package/io/zip.js +75 -65
- package/lib/README +5 -0
- package/lib/actions.js +138 -121
- package/lib/atoms/find-elements.js +123 -0
- package/lib/atoms/get-attribute.js +79 -60
- package/lib/atoms/is-displayed.js +72 -73
- package/{example/chrome_mobile_emulation.js → lib/atoms/make-atoms-module.js} +16 -23
- package/lib/by.js +192 -65
- package/lib/capabilities.js +82 -78
- package/lib/command.js +18 -20
- package/lib/error.js +134 -168
- package/lib/http.js +324 -230
- package/lib/input.js +325 -302
- package/lib/logging.js +127 -138
- package/lib/promise.js +60 -66
- package/lib/proxy.js +31 -41
- package/lib/session.js +12 -15
- package/lib/symbols.js +3 -4
- package/lib/until.js +162 -162
- package/lib/webdriver.js +733 -522
- package/net/index.js +30 -36
- package/net/portprober.js +31 -144
- package/opera.js +406 -0
- package/package.json +18 -11
- package/proxy.js +2 -2
- package/remote/index.js +190 -187
- package/safari.js +40 -49
- package/LICENSE +0 -202
- package/NOTICE +0 -2
- package/example/chrome_android.js +0 -42
- package/example/firefox_channels.js +0 -77
- package/example/google_search.js +0 -50
- package/example/google_search_test.js +0 -72
- package/example/headless.js +0 -55
- package/example/logging.js +0 -68
- package/testing/index.js +0 -498
package/remote/index.js
CHANGED
|
@@ -15,35 +15,30 @@
|
|
|
15
15
|
// specific language governing permissions and limitations
|
|
16
16
|
// under the License.
|
|
17
17
|
|
|
18
|
-
'use strict'
|
|
18
|
+
'use strict'
|
|
19
19
|
|
|
20
|
-
const fs = require('fs')
|
|
21
|
-
const path = require('path')
|
|
22
|
-
const url = require('url')
|
|
23
|
-
const util = require('util');
|
|
24
|
-
|
|
25
|
-
const httpUtil = require('../http/util');
|
|
26
|
-
const io = require('../io');
|
|
27
|
-
const exec = require('../io/exec');
|
|
28
|
-
const {Zip} = require('../io/zip');
|
|
29
|
-
const cmd = require('../lib/command');
|
|
30
|
-
const input = require('../lib/input');
|
|
31
|
-
const webdriver = require('../lib/webdriver');
|
|
32
|
-
const net = require('../net');
|
|
33
|
-
const portprober = require('../net/portprober');
|
|
20
|
+
const fs = require('fs')
|
|
21
|
+
const path = require('path')
|
|
22
|
+
const url = require('url')
|
|
34
23
|
|
|
24
|
+
const httpUtil = require('../http/util')
|
|
25
|
+
const io = require('../io')
|
|
26
|
+
const exec = require('../io/exec')
|
|
27
|
+
const { Zip } = require('../io/zip')
|
|
28
|
+
const cmd = require('../lib/command')
|
|
29
|
+
const input = require('../lib/input')
|
|
30
|
+
const net = require('../net')
|
|
31
|
+
const portprober = require('../net/portprober')
|
|
35
32
|
|
|
36
33
|
/**
|
|
37
34
|
* @typedef {(string|!Array<string|number|!stream.Stream|null|undefined>)}
|
|
38
35
|
*/
|
|
39
|
-
var StdIoOptions
|
|
40
|
-
|
|
36
|
+
var StdIoOptions // eslint-disable-line
|
|
41
37
|
|
|
42
38
|
/**
|
|
43
39
|
* @typedef {(string|!IThenable<string>)}
|
|
44
40
|
*/
|
|
45
|
-
var CommandLineFlag
|
|
46
|
-
|
|
41
|
+
var CommandLineFlag // eslint-disable-line
|
|
47
42
|
|
|
48
43
|
/**
|
|
49
44
|
* A record object that defines the configuration options for a DriverService
|
|
@@ -58,7 +53,7 @@ function ServiceOptions() {}
|
|
|
58
53
|
*
|
|
59
54
|
* @type {(boolean|undefined)}
|
|
60
55
|
*/
|
|
61
|
-
ServiceOptions.prototype.loopback
|
|
56
|
+
ServiceOptions.prototype.loopback
|
|
62
57
|
|
|
63
58
|
/**
|
|
64
59
|
* The host name to access the server on. If this option is specified, the
|
|
@@ -66,7 +61,7 @@ ServiceOptions.prototype.loopback;
|
|
|
66
61
|
*
|
|
67
62
|
* @type {(string|undefined)}
|
|
68
63
|
*/
|
|
69
|
-
ServiceOptions.prototype.hostname
|
|
64
|
+
ServiceOptions.prototype.hostname
|
|
70
65
|
|
|
71
66
|
/**
|
|
72
67
|
* The port to start the server on (must be > 0). If the port is provided as a
|
|
@@ -74,7 +69,7 @@ ServiceOptions.prototype.hostname;
|
|
|
74
69
|
*
|
|
75
70
|
* @type {(number|!IThenable<number>)}
|
|
76
71
|
*/
|
|
77
|
-
ServiceOptions.prototype.port
|
|
72
|
+
ServiceOptions.prototype.port
|
|
78
73
|
|
|
79
74
|
/**
|
|
80
75
|
* The arguments to pass to the service. If a promise is provided, the service
|
|
@@ -82,7 +77,7 @@ ServiceOptions.prototype.port;
|
|
|
82
77
|
*
|
|
83
78
|
* @type {!(Array<CommandLineFlag>|IThenable<!Array<CommandLineFlag>>)}
|
|
84
79
|
*/
|
|
85
|
-
ServiceOptions.prototype.args
|
|
80
|
+
ServiceOptions.prototype.args
|
|
86
81
|
|
|
87
82
|
/**
|
|
88
83
|
* The base path on the server for the WebDriver wire protocol (e.g. '/wd/hub').
|
|
@@ -90,7 +85,7 @@ ServiceOptions.prototype.args;
|
|
|
90
85
|
*
|
|
91
86
|
* @type {(string|undefined|null)}
|
|
92
87
|
*/
|
|
93
|
-
ServiceOptions.prototype.path
|
|
88
|
+
ServiceOptions.prototype.path
|
|
94
89
|
|
|
95
90
|
/**
|
|
96
91
|
* The environment variables that should be visible to the server process.
|
|
@@ -98,7 +93,7 @@ ServiceOptions.prototype.path;
|
|
|
98
93
|
*
|
|
99
94
|
* @type {(Object<string, string>|undefined)}
|
|
100
95
|
*/
|
|
101
|
-
ServiceOptions.prototype.env
|
|
96
|
+
ServiceOptions.prototype.env
|
|
102
97
|
|
|
103
98
|
/**
|
|
104
99
|
* IO configuration for the spawned server process. For more information, refer
|
|
@@ -107,8 +102,7 @@ ServiceOptions.prototype.env;
|
|
|
107
102
|
* @type {(StdIoOptions|undefined)}
|
|
108
103
|
* @see https://nodejs.org/dist/latest-v4.x/docs/api/child_process.html#child_process_options_stdio
|
|
109
104
|
*/
|
|
110
|
-
ServiceOptions.prototype.stdio
|
|
111
|
-
|
|
105
|
+
ServiceOptions.prototype.stdio
|
|
112
106
|
|
|
113
107
|
/**
|
|
114
108
|
* Manages the life and death of a native executable WebDriver server.
|
|
@@ -125,40 +119,40 @@ class DriverService {
|
|
|
125
119
|
*/
|
|
126
120
|
constructor(executable, options) {
|
|
127
121
|
/** @private {string} */
|
|
128
|
-
this.executable_ = executable
|
|
122
|
+
this.executable_ = executable
|
|
129
123
|
|
|
130
124
|
/** @private {boolean} */
|
|
131
|
-
this.loopbackOnly_ = !!options.loopback
|
|
125
|
+
this.loopbackOnly_ = !!options.loopback
|
|
132
126
|
|
|
133
127
|
/** @private {(string|undefined)} */
|
|
134
|
-
this.hostname_ = options.hostname
|
|
128
|
+
this.hostname_ = options.hostname
|
|
135
129
|
|
|
136
130
|
/** @private {(number|!IThenable<number>)} */
|
|
137
|
-
this.port_ = options.port
|
|
131
|
+
this.port_ = options.port
|
|
138
132
|
|
|
139
133
|
/**
|
|
140
134
|
* @private {!(Array<CommandLineFlag>|
|
|
141
135
|
* IThenable<!Array<CommandLineFlag>>)}
|
|
142
136
|
*/
|
|
143
|
-
this.args_ = options.args
|
|
137
|
+
this.args_ = options.args
|
|
144
138
|
|
|
145
139
|
/** @private {string} */
|
|
146
|
-
this.path_ = options.path || '/'
|
|
140
|
+
this.path_ = options.path || '/'
|
|
147
141
|
|
|
148
142
|
/** @private {!Object<string, string>} */
|
|
149
|
-
this.env_ = options.env || process.env
|
|
143
|
+
this.env_ = options.env || process.env
|
|
150
144
|
|
|
151
145
|
/**
|
|
152
146
|
* @private {(string|!Array<string|number|!stream.Stream|null|undefined>)}
|
|
153
147
|
*/
|
|
154
|
-
this.stdio_ = options.stdio || 'ignore'
|
|
148
|
+
this.stdio_ = options.stdio || 'ignore'
|
|
155
149
|
|
|
156
150
|
/**
|
|
157
151
|
* A promise for the managed subprocess, or null if the server has not been
|
|
158
152
|
* started yet. This promise will never be rejected.
|
|
159
153
|
* @private {Promise<!exec.Command>}
|
|
160
154
|
*/
|
|
161
|
-
this.command_ = null
|
|
155
|
+
this.command_ = null
|
|
162
156
|
|
|
163
157
|
/**
|
|
164
158
|
* Promise that resolves to the server's address or null if the server has
|
|
@@ -166,7 +160,7 @@ class DriverService {
|
|
|
166
160
|
* before it starts accepting WebDriver requests.
|
|
167
161
|
* @private {Promise<string>}
|
|
168
162
|
*/
|
|
169
|
-
this.address_ = null
|
|
163
|
+
this.address_ = null
|
|
170
164
|
}
|
|
171
165
|
|
|
172
166
|
/**
|
|
@@ -175,9 +169,9 @@ class DriverService {
|
|
|
175
169
|
*/
|
|
176
170
|
address() {
|
|
177
171
|
if (this.address_) {
|
|
178
|
-
return this.address_
|
|
172
|
+
return this.address_
|
|
179
173
|
}
|
|
180
|
-
throw Error('Server has not been started.')
|
|
174
|
+
throw Error('Server has not been started.')
|
|
181
175
|
}
|
|
182
176
|
|
|
183
177
|
/**
|
|
@@ -186,7 +180,7 @@ class DriverService {
|
|
|
186
180
|
* @return {boolean} Whether the underlying service process is running.
|
|
187
181
|
*/
|
|
188
182
|
isRunning() {
|
|
189
|
-
return !!this.address_
|
|
183
|
+
return !!this.address_
|
|
190
184
|
}
|
|
191
185
|
|
|
192
186
|
/**
|
|
@@ -199,71 +193,78 @@ class DriverService {
|
|
|
199
193
|
*/
|
|
200
194
|
start(opt_timeoutMs) {
|
|
201
195
|
if (this.address_) {
|
|
202
|
-
return this.address_
|
|
196
|
+
return this.address_
|
|
203
197
|
}
|
|
204
198
|
|
|
205
|
-
var timeout = opt_timeoutMs || DriverService.DEFAULT_START_TIMEOUT_MS
|
|
206
|
-
var self = this
|
|
199
|
+
var timeout = opt_timeoutMs || DriverService.DEFAULT_START_TIMEOUT_MS
|
|
200
|
+
var self = this
|
|
207
201
|
|
|
208
|
-
let resolveCommand
|
|
209
|
-
this.command_ = new Promise(resolve => resolveCommand = resolve)
|
|
202
|
+
let resolveCommand
|
|
203
|
+
this.command_ = new Promise((resolve) => (resolveCommand = resolve))
|
|
210
204
|
|
|
211
205
|
this.address_ = new Promise((resolveAddress, rejectAddress) => {
|
|
212
|
-
resolveAddress(
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
return resolveCommandLineFlags(this.args_).then(args => {
|
|
218
|
-
var command = exec(self.executable_, {
|
|
219
|
-
args: args,
|
|
220
|
-
env: self.env_,
|
|
221
|
-
stdio: self.stdio_
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
resolveCommand(command);
|
|
225
|
-
|
|
226
|
-
var earlyTermination = command.result().then(function(result) {
|
|
227
|
-
var error = result.code == null ?
|
|
228
|
-
Error('Server was killed with ' + result.signal) :
|
|
229
|
-
Error('Server terminated early with status ' + result.code);
|
|
230
|
-
rejectAddress(error);
|
|
231
|
-
self.address_ = null;
|
|
232
|
-
self.command_ = null;
|
|
233
|
-
throw error;
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
var hostname = self.hostname_;
|
|
237
|
-
if (!hostname) {
|
|
238
|
-
hostname = !self.loopbackOnly_ && net.getAddress()
|
|
239
|
-
|| net.getLoopbackAddress();
|
|
206
|
+
resolveAddress(
|
|
207
|
+
Promise.resolve(this.port_).then((port) => {
|
|
208
|
+
if (port <= 0) {
|
|
209
|
+
throw Error('Port must be > 0: ' + port)
|
|
240
210
|
}
|
|
241
211
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
212
|
+
return resolveCommandLineFlags(this.args_).then((args) => {
|
|
213
|
+
var command = exec(self.executable_, {
|
|
214
|
+
args: args,
|
|
215
|
+
env: self.env_,
|
|
216
|
+
stdio: self.stdio_,
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
resolveCommand(command)
|
|
220
|
+
|
|
221
|
+
var earlyTermination = command.result().then(function (result) {
|
|
222
|
+
var error =
|
|
223
|
+
result.code == null
|
|
224
|
+
? Error('Server was killed with ' + result.signal)
|
|
225
|
+
: Error('Server terminated early with status ' + result.code)
|
|
226
|
+
rejectAddress(error)
|
|
227
|
+
self.address_ = null
|
|
228
|
+
self.command_ = null
|
|
229
|
+
throw error
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
var hostname = self.hostname_
|
|
233
|
+
if (!hostname) {
|
|
234
|
+
hostname =
|
|
235
|
+
(!self.loopbackOnly_ && net.getAddress()) ||
|
|
236
|
+
net.getLoopbackAddress()
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
var serverUrl = url.format({
|
|
240
|
+
protocol: 'http',
|
|
241
|
+
hostname: hostname,
|
|
242
|
+
port: port + '',
|
|
243
|
+
pathname: self.path_,
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
return new Promise((fulfill, reject) => {
|
|
247
|
+
let cancelToken = earlyTermination.catch((e) =>
|
|
248
|
+
reject(Error(e.message))
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
httpUtil.waitForServer(serverUrl, timeout, cancelToken).then(
|
|
252
|
+
(_) => fulfill(serverUrl),
|
|
253
|
+
(err) => {
|
|
255
254
|
if (err instanceof httpUtil.CancellationError) {
|
|
256
|
-
fulfill(serverUrl)
|
|
255
|
+
fulfill(serverUrl)
|
|
257
256
|
} else {
|
|
258
|
-
reject(err)
|
|
257
|
+
reject(err)
|
|
259
258
|
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
259
|
+
}
|
|
260
|
+
)
|
|
261
|
+
})
|
|
262
|
+
})
|
|
263
|
+
})
|
|
264
|
+
)
|
|
265
|
+
})
|
|
266
|
+
|
|
267
|
+
return this.address_
|
|
267
268
|
}
|
|
268
269
|
|
|
269
270
|
/**
|
|
@@ -275,34 +276,32 @@ class DriverService {
|
|
|
275
276
|
*/
|
|
276
277
|
kill() {
|
|
277
278
|
if (!this.address_ || !this.command_) {
|
|
278
|
-
return Promise.resolve()
|
|
279
|
+
return Promise.resolve() // Not currently running.
|
|
279
280
|
}
|
|
280
|
-
let cmd = this.command_
|
|
281
|
-
this.address_ = null
|
|
282
|
-
this.command_ = null
|
|
283
|
-
return cmd.then(c => c.kill('SIGTERM'))
|
|
281
|
+
let cmd = this.command_
|
|
282
|
+
this.address_ = null
|
|
283
|
+
this.command_ = null
|
|
284
|
+
return cmd.then((c) => c.kill('SIGTERM'))
|
|
284
285
|
}
|
|
285
286
|
}
|
|
286
287
|
|
|
287
|
-
|
|
288
288
|
/**
|
|
289
289
|
* @param {!(Array<CommandLineFlag>|IThenable<!Array<CommandLineFlag>>)} args
|
|
290
290
|
* @return {!Promise<!Array<string>>}
|
|
291
291
|
*/
|
|
292
292
|
function resolveCommandLineFlags(args) {
|
|
293
293
|
// Resolve the outer array, then the individual flags.
|
|
294
|
-
return Promise.resolve(args)
|
|
295
|
-
|
|
294
|
+
return Promise.resolve(args).then(
|
|
295
|
+
/** !Array<CommandLineFlag> */ (args) => Promise.all(args)
|
|
296
|
+
)
|
|
296
297
|
}
|
|
297
298
|
|
|
298
|
-
|
|
299
299
|
/**
|
|
300
300
|
* The default amount of time, in milliseconds, to wait for the server to
|
|
301
301
|
* start.
|
|
302
302
|
* @const {number}
|
|
303
303
|
*/
|
|
304
|
-
DriverService.DEFAULT_START_TIMEOUT_MS = 30 * 1000
|
|
305
|
-
|
|
304
|
+
DriverService.DEFAULT_START_TIMEOUT_MS = 30 * 1000
|
|
306
305
|
|
|
307
306
|
/**
|
|
308
307
|
* Creates {@link DriverService} objects that manage a WebDriver server in a
|
|
@@ -316,19 +315,19 @@ DriverService.Builder = class {
|
|
|
316
315
|
*/
|
|
317
316
|
constructor(exe) {
|
|
318
317
|
if (!fs.existsSync(exe)) {
|
|
319
|
-
throw Error(`The specified executable path does not exist: ${exe}`)
|
|
318
|
+
throw Error(`The specified executable path does not exist: ${exe}`)
|
|
320
319
|
}
|
|
321
320
|
|
|
322
321
|
/** @private @const {string} */
|
|
323
|
-
this.exe_ = exe
|
|
322
|
+
this.exe_ = exe
|
|
324
323
|
|
|
325
324
|
/** @private {!ServiceOptions} */
|
|
326
325
|
this.options_ = {
|
|
327
326
|
args: [],
|
|
328
327
|
port: 0,
|
|
329
328
|
env: null,
|
|
330
|
-
stdio: 'ignore'
|
|
331
|
-
}
|
|
329
|
+
stdio: 'ignore',
|
|
330
|
+
}
|
|
332
331
|
}
|
|
333
332
|
|
|
334
333
|
/**
|
|
@@ -339,10 +338,10 @@ DriverService.Builder = class {
|
|
|
339
338
|
* @this {THIS}
|
|
340
339
|
* @template THIS
|
|
341
340
|
*/
|
|
342
|
-
addArguments(var_args) {
|
|
343
|
-
let args = Array.prototype.slice.call(arguments, 0)
|
|
344
|
-
this.options_.args = this.options_.args.concat(args)
|
|
345
|
-
return this
|
|
341
|
+
addArguments(var_args) { // eslint-disable-line
|
|
342
|
+
let args = Array.prototype.slice.call(arguments, 0)
|
|
343
|
+
this.options_.args = this.options_.args.concat(args)
|
|
344
|
+
return this
|
|
346
345
|
}
|
|
347
346
|
|
|
348
347
|
/**
|
|
@@ -353,8 +352,8 @@ DriverService.Builder = class {
|
|
|
353
352
|
* @return {!DriverService.Builder} A self reference.
|
|
354
353
|
*/
|
|
355
354
|
setHostname(hostname) {
|
|
356
|
-
this.options_.hostname = hostname
|
|
357
|
-
return this
|
|
355
|
+
this.options_.hostname = hostname
|
|
356
|
+
return this
|
|
358
357
|
}
|
|
359
358
|
|
|
360
359
|
/**
|
|
@@ -365,8 +364,8 @@ DriverService.Builder = class {
|
|
|
365
364
|
* @return {!DriverService.Builder} A self reference.
|
|
366
365
|
*/
|
|
367
366
|
setLoopback(loopback) {
|
|
368
|
-
this.options_.loopback = loopback
|
|
369
|
-
return this
|
|
367
|
+
this.options_.loopback = loopback
|
|
368
|
+
return this
|
|
370
369
|
}
|
|
371
370
|
|
|
372
371
|
/**
|
|
@@ -378,8 +377,8 @@ DriverService.Builder = class {
|
|
|
378
377
|
* @return {!DriverService.Builder} A self reference.
|
|
379
378
|
*/
|
|
380
379
|
setPath(basePath) {
|
|
381
|
-
this.options_.path = basePath
|
|
382
|
-
return this
|
|
380
|
+
this.options_.path = basePath
|
|
381
|
+
return this
|
|
383
382
|
}
|
|
384
383
|
|
|
385
384
|
/**
|
|
@@ -391,10 +390,10 @@ DriverService.Builder = class {
|
|
|
391
390
|
*/
|
|
392
391
|
setPort(port) {
|
|
393
392
|
if (port < 0) {
|
|
394
|
-
throw Error(`port must be >= 0: ${port}`)
|
|
393
|
+
throw Error(`port must be >= 0: ${port}`)
|
|
395
394
|
}
|
|
396
|
-
this.options_.port = port
|
|
397
|
-
return this
|
|
395
|
+
this.options_.port = port
|
|
396
|
+
return this
|
|
398
397
|
}
|
|
399
398
|
|
|
400
399
|
/**
|
|
@@ -409,12 +408,12 @@ DriverService.Builder = class {
|
|
|
409
408
|
*/
|
|
410
409
|
setEnvironment(env) {
|
|
411
410
|
if (env instanceof Map) {
|
|
412
|
-
let tmp = {}
|
|
413
|
-
env.forEach((value, key) => tmp[key] = value)
|
|
414
|
-
env = tmp
|
|
411
|
+
let tmp = {}
|
|
412
|
+
env.forEach((value, key) => (tmp[key] = value))
|
|
413
|
+
env = tmp
|
|
415
414
|
}
|
|
416
|
-
this.options_.env = env
|
|
417
|
-
return this
|
|
415
|
+
this.options_.env = env
|
|
416
|
+
return this
|
|
418
417
|
}
|
|
419
418
|
|
|
420
419
|
/**
|
|
@@ -426,8 +425,8 @@ DriverService.Builder = class {
|
|
|
426
425
|
* @see https://nodejs.org/dist/latest-v4.x/docs/api/child_process.html#child_process_options_stdio
|
|
427
426
|
*/
|
|
428
427
|
setStdio(config) {
|
|
429
|
-
this.options_.stdio = config
|
|
430
|
-
return this
|
|
428
|
+
this.options_.stdio = config
|
|
429
|
+
return this
|
|
431
430
|
}
|
|
432
431
|
|
|
433
432
|
/**
|
|
@@ -436,18 +435,17 @@ DriverService.Builder = class {
|
|
|
436
435
|
* @return {!DriverService} A new driver service.
|
|
437
436
|
*/
|
|
438
437
|
build() {
|
|
439
|
-
let port = this.options_.port || portprober.findFreePort()
|
|
440
|
-
let args = Promise.resolve(port).then(port => {
|
|
441
|
-
return this.options_.args.concat('--port=' + port)
|
|
442
|
-
})
|
|
438
|
+
let port = this.options_.port || portprober.findFreePort()
|
|
439
|
+
let args = Promise.resolve(port).then((port) => {
|
|
440
|
+
return this.options_.args.concat('--port=' + port)
|
|
441
|
+
})
|
|
443
442
|
|
|
444
443
|
let options =
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
return new DriverService(this.exe_, options)
|
|
444
|
+
/** @type {!ServiceOptions} */
|
|
445
|
+
(Object.assign({}, this.options_, { args, port }))
|
|
446
|
+
return new DriverService(this.exe_, options)
|
|
448
447
|
}
|
|
449
|
-
}
|
|
450
|
-
|
|
448
|
+
}
|
|
451
449
|
|
|
452
450
|
/**
|
|
453
451
|
* Manages the life and death of the
|
|
@@ -464,27 +462,30 @@ class SeleniumServer extends DriverService {
|
|
|
464
462
|
*/
|
|
465
463
|
constructor(jar, opt_options) {
|
|
466
464
|
if (!jar) {
|
|
467
|
-
throw Error('Path to the Selenium jar not specified')
|
|
465
|
+
throw Error('Path to the Selenium jar not specified')
|
|
468
466
|
}
|
|
469
467
|
|
|
470
|
-
var options = opt_options || {}
|
|
468
|
+
var options = opt_options || {}
|
|
471
469
|
|
|
472
470
|
if (options.port < 0) {
|
|
473
|
-
throw Error('Port must be >= 0: ' + options.port)
|
|
471
|
+
throw Error('Port must be >= 0: ' + options.port)
|
|
474
472
|
}
|
|
475
473
|
|
|
476
|
-
let port = options.port || portprober.findFreePort()
|
|
477
|
-
let args = Promise.all([
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
474
|
+
let port = options.port || portprober.findFreePort()
|
|
475
|
+
let args = Promise.all([
|
|
476
|
+
port,
|
|
477
|
+
options.jvmArgs || [],
|
|
478
|
+
options.args || [],
|
|
479
|
+
]).then((resolved) => {
|
|
480
|
+
let port = resolved[0]
|
|
481
|
+
let jvmArgs = resolved[1]
|
|
482
|
+
let args = resolved[2]
|
|
483
|
+
return jvmArgs.concat('-jar', jar, '-port', port).concat(args)
|
|
484
|
+
})
|
|
485
|
+
|
|
486
|
+
let java = 'java'
|
|
486
487
|
if (process.env['JAVA_HOME']) {
|
|
487
|
-
java = path.join(process.env['JAVA_HOME'], 'bin/java')
|
|
488
|
+
java = path.join(process.env['JAVA_HOME'], 'bin/java')
|
|
488
489
|
}
|
|
489
490
|
|
|
490
491
|
super(java, {
|
|
@@ -493,12 +494,11 @@ class SeleniumServer extends DriverService {
|
|
|
493
494
|
args: args,
|
|
494
495
|
path: '/wd/hub',
|
|
495
496
|
env: options.env,
|
|
496
|
-
stdio: options.stdio
|
|
497
|
-
})
|
|
497
|
+
stdio: options.stdio,
|
|
498
|
+
})
|
|
498
499
|
}
|
|
499
500
|
}
|
|
500
501
|
|
|
501
|
-
|
|
502
502
|
/**
|
|
503
503
|
* A record object describing configuration options for a {@link SeleniumServer}
|
|
504
504
|
* instance.
|
|
@@ -513,7 +513,7 @@ SeleniumServer.Options = class {
|
|
|
513
513
|
*
|
|
514
514
|
* @type {(boolean|undefined)}
|
|
515
515
|
*/
|
|
516
|
-
this.loopback
|
|
516
|
+
this.loopback
|
|
517
517
|
|
|
518
518
|
/**
|
|
519
519
|
* The port to start the server on (must be > 0). If the port is provided as
|
|
@@ -522,7 +522,7 @@ SeleniumServer.Options = class {
|
|
|
522
522
|
*
|
|
523
523
|
* @type {(number|!IThenable<number>)}
|
|
524
524
|
*/
|
|
525
|
-
this.port
|
|
525
|
+
this.port
|
|
526
526
|
|
|
527
527
|
/**
|
|
528
528
|
* The arguments to pass to the service. If a promise is provided,
|
|
@@ -530,7 +530,7 @@ SeleniumServer.Options = class {
|
|
|
530
530
|
*
|
|
531
531
|
* @type {!(Array<string>|IThenable<!Array<string>>)}
|
|
532
532
|
*/
|
|
533
|
-
this.args
|
|
533
|
+
this.args
|
|
534
534
|
|
|
535
535
|
/**
|
|
536
536
|
* The arguments to pass to the JVM. If a promise is provided,
|
|
@@ -538,7 +538,7 @@ SeleniumServer.Options = class {
|
|
|
538
538
|
*
|
|
539
539
|
* @type {(!Array<string>|!IThenable<!Array<string>>|undefined)}
|
|
540
540
|
*/
|
|
541
|
-
this.jvmArgs
|
|
541
|
+
this.jvmArgs
|
|
542
542
|
|
|
543
543
|
/**
|
|
544
544
|
* The environment variables that should be visible to the server
|
|
@@ -546,7 +546,7 @@ SeleniumServer.Options = class {
|
|
|
546
546
|
*
|
|
547
547
|
* @type {(!Object<string, string>|undefined)}
|
|
548
548
|
*/
|
|
549
|
-
this.env
|
|
549
|
+
this.env
|
|
550
550
|
|
|
551
551
|
/**
|
|
552
552
|
* IO configuration for the spawned server process. If unspecified, IO will
|
|
@@ -556,11 +556,9 @@ SeleniumServer.Options = class {
|
|
|
556
556
|
* undefined)}
|
|
557
557
|
* @see <https://nodejs.org/dist/latest-v8.x/docs/api/child_process.html#child_process_options_stdio>
|
|
558
558
|
*/
|
|
559
|
-
this.stdio
|
|
559
|
+
this.stdio
|
|
560
560
|
}
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
|
|
561
|
+
}
|
|
564
562
|
|
|
565
563
|
/**
|
|
566
564
|
* A {@link webdriver.FileDetector} that may be used when running
|
|
@@ -590,33 +588,38 @@ class FileDetector extends input.FileDetector {
|
|
|
590
588
|
* @override
|
|
591
589
|
*/
|
|
592
590
|
handleFile(driver, file) {
|
|
593
|
-
return io.stat(file).then(
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
591
|
+
return io.stat(file).then(
|
|
592
|
+
function (stats) {
|
|
593
|
+
if (stats.isDirectory()) {
|
|
594
|
+
return file // Not a valid file, return original input.
|
|
595
|
+
}
|
|
597
596
|
|
|
598
|
-
|
|
599
|
-
|
|
597
|
+
let zip = new Zip()
|
|
598
|
+
return zip
|
|
599
|
+
.addFile(file)
|
|
600
600
|
.then(() => zip.toBuffer())
|
|
601
|
-
.then(buf => buf.toString('base64'))
|
|
602
|
-
.then(encodedZip => {
|
|
603
|
-
let command = new cmd.Command(cmd.Name.UPLOAD_FILE)
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
601
|
+
.then((buf) => buf.toString('base64'))
|
|
602
|
+
.then((encodedZip) => {
|
|
603
|
+
let command = new cmd.Command(cmd.Name.UPLOAD_FILE).setParameter(
|
|
604
|
+
'file',
|
|
605
|
+
encodedZip
|
|
606
|
+
)
|
|
607
|
+
return driver.execute(command)
|
|
608
|
+
})
|
|
609
|
+
},
|
|
610
|
+
function (err) {
|
|
611
|
+
if (err.code === 'ENOENT') {
|
|
612
|
+
return file // Not a file; return original input.
|
|
613
|
+
}
|
|
614
|
+
throw err
|
|
610
615
|
}
|
|
611
|
-
|
|
612
|
-
});
|
|
616
|
+
)
|
|
613
617
|
}
|
|
614
618
|
}
|
|
615
619
|
|
|
616
|
-
|
|
617
620
|
// PUBLIC API
|
|
618
621
|
|
|
619
|
-
exports.DriverService = DriverService
|
|
620
|
-
exports.FileDetector = FileDetector
|
|
621
|
-
exports.SeleniumServer = SeleniumServer
|
|
622
|
-
exports.ServiceOptions = ServiceOptions
|
|
622
|
+
exports.DriverService = DriverService
|
|
623
|
+
exports.FileDetector = FileDetector
|
|
624
|
+
exports.SeleniumServer = SeleniumServer
|
|
625
|
+
exports.ServiceOptions = ServiceOptions // Exported for API docs.
|