selenium-webdriver 3.0.0-beta-1 → 3.0.1
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 +109 -0
- package/LICENSE +1 -1
- package/README.md +7 -6
- package/chrome.js +31 -128
- package/edge.js +13 -91
- package/example/chrome_android.js +18 -13
- package/example/chrome_mobile_emulation.js +19 -15
- package/example/google_search.js +11 -11
- package/example/google_search_generator.js +23 -18
- package/example/google_search_test.js +31 -17
- package/example/logging.js +9 -17
- package/example/parallel_flows.js +3 -0
- package/firefox/binary.js +17 -0
- package/firefox/index.js +198 -101
- package/firefox/profile.js +24 -3
- package/http/util.js +95 -59
- package/ie.js +6 -10
- package/index.js +636 -2
- package/lib/actions.js +18 -10
- package/lib/atoms/getAttribute.js +11 -0
- package/lib/atoms/isDisplayed.js +106 -0
- package/lib/firefox/amd64/libnoblur64.so +0 -0
- package/lib/firefox/i386/libnoblur.so +0 -0
- package/lib/firefox/webdriver.xpi +0 -0
- package/lib/http.js +159 -46
- package/lib/logging.js +7 -1
- package/lib/promise.js +602 -358
- package/lib/proxy.js +28 -0
- package/lib/session.js +1 -1
- package/lib/test/build.js +26 -28
- package/lib/test/data/formPage.html +1 -0
- package/lib/test/fileserver.js +12 -10
- package/lib/test/httpserver.js +4 -6
- package/lib/test/index.js +18 -11
- package/lib/test/promise.js +79 -0
- package/lib/webdriver.js +587 -479
- package/opera.js +12 -88
- package/package.json +13 -14
- package/phantomjs.js +7 -14
- package/remote/index.js +201 -30
- package/safari.js +62 -416
- package/test/actions_test.js +9 -11
- package/test/chrome/options_test.js +8 -8
- package/test/chrome/service_test.js +2 -2
- package/test/cookie_test.js +57 -57
- package/test/element_finding_test.js +201 -185
- package/test/execute_script_test.js +108 -111
- package/test/fingerprint_test.js +16 -11
- package/test/firefox/firefox_test.js +75 -49
- package/test/firefox/profile_test.js +1 -3
- package/test/http/util_test.js +21 -27
- package/test/io_test.js +2 -5
- package/test/lib/http_test.js +8 -6
- package/test/lib/promise_aplus_test.js +48 -44
- package/test/lib/promise_error_test.js +687 -611
- package/test/lib/promise_flow_test.js +1810 -1806
- package/test/lib/promise_generator_test.js +227 -225
- package/test/lib/promise_test.js +864 -835
- package/test/lib/until_test.js +1 -1
- package/test/lib/webdriver_test.js +520 -424
- package/test/logging_test.js +43 -45
- package/test/net/portprober_test.js +23 -24
- package/test/page_loading_test.js +84 -78
- package/test/phantomjs/execute_phantomjs_test.js +11 -25
- package/test/proxy_test.js +23 -23
- package/test/remote_test.js +22 -22
- package/test/safari_test.js +108 -0
- package/test/session_test.js +11 -10
- package/test/stale_element_test.js +18 -16
- package/test/tag_name_test.js +7 -5
- package/test/testing/assert_test.js +2 -3
- package/test/testing/index_test.js +163 -117
- package/test/upload_test.js +13 -13
- package/test/window_test.js +94 -70
- package/testing/index.js +176 -37
- package/builder.js +0 -553
- package/lib/safari/client.js +0 -56
package/opera.js
CHANGED
|
@@ -98,7 +98,7 @@ const OPERADRIVER_EXE =
|
|
|
98
98
|
* [OperaDriver](https://github.com/operasoftware/operachromiumdriver)
|
|
99
99
|
* server in a child process.
|
|
100
100
|
*/
|
|
101
|
-
class ServiceBuilder {
|
|
101
|
+
class ServiceBuilder extends remote.DriverService.Builder {
|
|
102
102
|
/**
|
|
103
103
|
* @param {string=} opt_exe Path to the server executable to use. If omitted,
|
|
104
104
|
* the builder will attempt to locate the operadriver on the current
|
|
@@ -116,39 +116,8 @@ class ServiceBuilder {
|
|
|
116
116
|
'ensure it can be found on your PATH.');
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
|
|
120
|
-
this.
|
|
121
|
-
if (!fs.existsSync(this.exe_)) {
|
|
122
|
-
throw Error('File does not exist: ' + this.exe_);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/** @private {!Array.<string>} */
|
|
126
|
-
this.args_ = [];
|
|
127
|
-
|
|
128
|
-
/** @private {number} */
|
|
129
|
-
this.port_ = 0;
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* @private {(string|!Array<string|number|!stream.Stream|null|undefined>)}
|
|
133
|
-
*/
|
|
134
|
-
this.stdio_ = 'ignore';
|
|
135
|
-
|
|
136
|
-
/** @private {Object.<string, string>} */
|
|
137
|
-
this.env_ = null;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Sets the port to start the OperaDriver on.
|
|
142
|
-
* @param {number} port The port to use, or 0 for any free port.
|
|
143
|
-
* @return {!ServiceBuilder} A self reference.
|
|
144
|
-
* @throws {Error} If the port is invalid.
|
|
145
|
-
*/
|
|
146
|
-
usingPort(port) {
|
|
147
|
-
if (port < 0) {
|
|
148
|
-
throw Error('port must be >= 0: ' + port);
|
|
149
|
-
}
|
|
150
|
-
this.port_ = port;
|
|
151
|
-
return this;
|
|
119
|
+
super(exe);
|
|
120
|
+
this.setLoopback(true);
|
|
152
121
|
}
|
|
153
122
|
|
|
154
123
|
/**
|
|
@@ -158,8 +127,7 @@ class ServiceBuilder {
|
|
|
158
127
|
* @return {!ServiceBuilder} A self reference.
|
|
159
128
|
*/
|
|
160
129
|
loggingTo(path) {
|
|
161
|
-
this.
|
|
162
|
-
return this;
|
|
130
|
+
return this.addArguments('--log-path=' + path);
|
|
163
131
|
}
|
|
164
132
|
|
|
165
133
|
/**
|
|
@@ -167,8 +135,7 @@ class ServiceBuilder {
|
|
|
167
135
|
* @return {!ServiceBuilder} A self reference.
|
|
168
136
|
*/
|
|
169
137
|
enableVerboseLogging() {
|
|
170
|
-
this.
|
|
171
|
-
return this;
|
|
138
|
+
return this.addArguments('--verbose');
|
|
172
139
|
}
|
|
173
140
|
|
|
174
141
|
/**
|
|
@@ -176,54 +143,8 @@ class ServiceBuilder {
|
|
|
176
143
|
* @return {!ServiceBuilder} A self reference.
|
|
177
144
|
*/
|
|
178
145
|
silent() {
|
|
179
|
-
this.
|
|
180
|
-
return this;
|
|
146
|
+
return this.addArguments('--silent');
|
|
181
147
|
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Defines the stdio configuration for the driver service. See
|
|
185
|
-
* {@code child_process.spawn} for more information.
|
|
186
|
-
* @param {(string|!Array<string|number|!stream.Stream|null|undefined>)}
|
|
187
|
-
* config The configuration to use.
|
|
188
|
-
* @return {!ServiceBuilder} A self reference.
|
|
189
|
-
*/
|
|
190
|
-
setStdio(config) {
|
|
191
|
-
this.stdio_ = config;
|
|
192
|
-
return this;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Defines the environment to start the server under. This settings will be
|
|
197
|
-
* inherited by every browser session started by the server.
|
|
198
|
-
* @param {!Object.<string, string>} env The environment to use.
|
|
199
|
-
* @return {!ServiceBuilder} A self reference.
|
|
200
|
-
*/
|
|
201
|
-
withEnvironment(env) {
|
|
202
|
-
this.env_ = env;
|
|
203
|
-
return this;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Creates a new DriverService using this instance's current configuration.
|
|
208
|
-
* @return {!remote.DriverService} A new driver service using this instance's
|
|
209
|
-
* current configuration.
|
|
210
|
-
* @throws {Error} If the driver exectuable was not specified and a default
|
|
211
|
-
* could not be found on the current PATH.
|
|
212
|
-
*/
|
|
213
|
-
build() {
|
|
214
|
-
var port = this.port_ || portprober.findFreePort();
|
|
215
|
-
var args = this.args_.concat(); // Defensive copy.
|
|
216
|
-
|
|
217
|
-
return new remote.DriverService(this.exe_, {
|
|
218
|
-
loopback: true,
|
|
219
|
-
port: port,
|
|
220
|
-
args: Promise.resolve(port).then(function(port) {
|
|
221
|
-
return args.concat('--port=' + port);
|
|
222
|
-
}),
|
|
223
|
-
env: this.env_,
|
|
224
|
-
stdio: this.stdio_
|
|
225
|
-
});
|
|
226
|
-
};
|
|
227
148
|
}
|
|
228
149
|
|
|
229
150
|
|
|
@@ -427,14 +348,17 @@ class Options {
|
|
|
427
348
|
*/
|
|
428
349
|
class Driver extends webdriver.WebDriver {
|
|
429
350
|
/**
|
|
351
|
+
* Creates a new session for Opera.
|
|
352
|
+
*
|
|
430
353
|
* @param {(capabilities.Capabilities|Options)=} opt_config The configuration
|
|
431
354
|
* options.
|
|
432
355
|
* @param {remote.DriverService=} opt_service The session to use; will use
|
|
433
356
|
* the {@link getDefaultService default service} by default.
|
|
434
357
|
* @param {promise.ControlFlow=} opt_flow The control flow to use,
|
|
435
358
|
* or {@code null} to use the currently active flow.
|
|
359
|
+
* @return {!Driver} A new driver instance.
|
|
436
360
|
*/
|
|
437
|
-
|
|
361
|
+
static createSession(opt_config, opt_service, opt_flow) {
|
|
438
362
|
var service = opt_service || getDefaultService();
|
|
439
363
|
var client = service.start().then(url => new http.HttpClient(url));
|
|
440
364
|
var executor = new http.Executor(client);
|
|
@@ -458,8 +382,8 @@ class Driver extends webdriver.WebDriver {
|
|
|
458
382
|
caps = options.toCapabilities(caps);
|
|
459
383
|
}
|
|
460
384
|
|
|
461
|
-
|
|
462
|
-
|
|
385
|
+
return /** @type {!Driver} */(
|
|
386
|
+
webdriver.WebDriver.createSession(executor, caps, opt_flow, this));
|
|
463
387
|
}
|
|
464
388
|
|
|
465
389
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "selenium-webdriver",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.1",
|
|
4
4
|
"description": "The official WebDriver JavaScript bindings from the Selenium project",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"keywords": [
|
|
@@ -20,24 +20,23 @@
|
|
|
20
20
|
"url": "https://github.com/SeleniumHQ/selenium.git"
|
|
21
21
|
},
|
|
22
22
|
"engines": {
|
|
23
|
-
"node": ">=
|
|
23
|
+
"node": ">= 6.9.0"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"adm-zip": "0.4.
|
|
27
|
-
"rimraf": "^2.
|
|
28
|
-
"tmp": "0.0.
|
|
29
|
-
"
|
|
30
|
-
"xml2js": "0.4.4"
|
|
26
|
+
"adm-zip": "^0.4.7",
|
|
27
|
+
"rimraf": "^2.5.4",
|
|
28
|
+
"tmp": "0.0.30",
|
|
29
|
+
"xml2js": "^0.4.17"
|
|
31
30
|
},
|
|
32
31
|
"devDependencies": {
|
|
33
|
-
"express": "^4.
|
|
34
|
-
"mocha": "
|
|
35
|
-
"multer": "^
|
|
36
|
-
"promises-aplus-tests": "^2.1.
|
|
37
|
-
"serve-index": "^1.
|
|
38
|
-
"sinon": "^1.17.
|
|
32
|
+
"express": "^4.14.0",
|
|
33
|
+
"mocha": "^3.1.2",
|
|
34
|
+
"multer": "^1.2.0",
|
|
35
|
+
"promises-aplus-tests": "^2.1.2",
|
|
36
|
+
"serve-index": "^1.8.0",
|
|
37
|
+
"sinon": "^1.17.6"
|
|
39
38
|
},
|
|
40
39
|
"scripts": {
|
|
41
|
-
"test": "mocha
|
|
40
|
+
"test": "mocha -t 600000 --recursive test"
|
|
42
41
|
}
|
|
43
42
|
}
|
package/phantomjs.js
CHANGED
|
@@ -148,6 +148,8 @@ function createExecutor(url) {
|
|
|
148
148
|
*/
|
|
149
149
|
class Driver extends webdriver.WebDriver {
|
|
150
150
|
/**
|
|
151
|
+
* Creates a new PhantomJS session.
|
|
152
|
+
*
|
|
151
153
|
* @param {capabilities.Capabilities=} opt_capabilities The desired
|
|
152
154
|
* capabilities.
|
|
153
155
|
* @param {promise.ControlFlow=} opt_flow The control flow to use,
|
|
@@ -155,8 +157,9 @@ class Driver extends webdriver.WebDriver {
|
|
|
155
157
|
* @param {string=} opt_logFile Path to the log file for the phantomjs
|
|
156
158
|
* executable's output. For convenience, this may be set at runtime with
|
|
157
159
|
* the `SELENIUM_PHANTOMJS_LOG` environment variable.
|
|
160
|
+
* @return {!Driver} A new driver reference.
|
|
158
161
|
*/
|
|
159
|
-
|
|
162
|
+
static createSession(opt_capabilities, opt_flow, opt_logFile) {
|
|
160
163
|
// TODO: add an Options class for consistency with the other driver types.
|
|
161
164
|
|
|
162
165
|
var caps = opt_capabilities || capabilities.Capabilities.phantomjs();
|
|
@@ -207,7 +210,6 @@ class Driver extends webdriver.WebDriver {
|
|
|
207
210
|
var port = portprober.findFreePort();
|
|
208
211
|
var service = new remote.DriverService(exe, {
|
|
209
212
|
port: port,
|
|
210
|
-
stdio: 'inherit',
|
|
211
213
|
args: Promise.resolve(port).then(function(port) {
|
|
212
214
|
args.push('--webdriver=' + port);
|
|
213
215
|
return args;
|
|
@@ -215,17 +217,8 @@ class Driver extends webdriver.WebDriver {
|
|
|
215
217
|
});
|
|
216
218
|
|
|
217
219
|
var executor = createExecutor(service.start());
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
super(driver.getSession(), executor, driver.controlFlow());
|
|
221
|
-
|
|
222
|
-
var boundQuit = this.quit.bind(this);
|
|
223
|
-
|
|
224
|
-
/** @override */
|
|
225
|
-
this.quit = function() {
|
|
226
|
-
let killService = () => service.kill();
|
|
227
|
-
return boundQuit().then(killService, killService);
|
|
228
|
-
};
|
|
220
|
+
return /** @type {!Driver} */(webdriver.WebDriver.createSession(
|
|
221
|
+
executor, caps, opt_flow, this, () => service.kill()));
|
|
229
222
|
}
|
|
230
223
|
|
|
231
224
|
/**
|
|
@@ -265,7 +258,7 @@ class Driver extends webdriver.WebDriver {
|
|
|
265
258
|
*
|
|
266
259
|
* @param {(string|!Function)} script The script to execute.
|
|
267
260
|
* @param {...*} var_args The arguments to pass to the script.
|
|
268
|
-
* @return {!promise.
|
|
261
|
+
* @return {!promise.Thenable<T>} A promise that resolve to the
|
|
269
262
|
* script's return value.
|
|
270
263
|
* @template T
|
|
271
264
|
*/
|
package/remote/index.js
CHANGED
|
@@ -17,22 +17,33 @@
|
|
|
17
17
|
|
|
18
18
|
'use strict';
|
|
19
19
|
|
|
20
|
-
const AdmZip = require('adm-zip')
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
const AdmZip = require('adm-zip');
|
|
21
|
+
const fs = require('fs');
|
|
22
|
+
const path = require('path');
|
|
23
|
+
const url = require('url');
|
|
24
|
+
const util = require('util');
|
|
25
|
+
|
|
26
|
+
const httpUtil = require('../http/util');
|
|
27
|
+
const io = require('../io');
|
|
28
|
+
const exec = require('../io/exec');
|
|
29
|
+
const cmd = require('../lib/command');
|
|
30
|
+
const input = require('../lib/input');
|
|
31
|
+
const promise = require('../lib/promise');
|
|
32
|
+
const webdriver = require('../lib/webdriver');
|
|
33
|
+
const net = require('../net');
|
|
34
|
+
const portprober = require('../net/portprober');
|
|
25
35
|
|
|
26
|
-
const httpUtil = require('../http/util'),
|
|
27
|
-
io = require('../io'),
|
|
28
|
-
exec = require('../io/exec'),
|
|
29
|
-
cmd = require('../lib/command'),
|
|
30
|
-
input = require('../lib/input'),
|
|
31
|
-
promise = require('../lib/promise'),
|
|
32
|
-
webdriver = require('../lib/webdriver'),
|
|
33
|
-
net = require('../net'),
|
|
34
|
-
portprober = require('../net/portprober');
|
|
35
36
|
|
|
37
|
+
/**
|
|
38
|
+
* @typedef {(string|!Array<string|number|!stream.Stream|null|undefined>)}
|
|
39
|
+
*/
|
|
40
|
+
var StdIoOptions;
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @typedef {(string|!IThenable<string>)}
|
|
45
|
+
*/
|
|
46
|
+
var CommandLineFlag;
|
|
36
47
|
|
|
37
48
|
|
|
38
49
|
/**
|
|
@@ -70,7 +81,7 @@ ServiceOptions.prototype.port;
|
|
|
70
81
|
* The arguments to pass to the service. If a promise is provided, the service
|
|
71
82
|
* will wait for it to resolve before starting.
|
|
72
83
|
*
|
|
73
|
-
* @type {!(Array<
|
|
84
|
+
* @type {!(Array<CommandLineFlag>|IThenable<!Array<CommandLineFlag>>)}
|
|
74
85
|
*/
|
|
75
86
|
ServiceOptions.prototype.args;
|
|
76
87
|
|
|
@@ -94,8 +105,7 @@ ServiceOptions.prototype.env;
|
|
|
94
105
|
* IO configuration for the spawned server process. For more information, refer
|
|
95
106
|
* to the documentation of `child_process.spawn`.
|
|
96
107
|
*
|
|
97
|
-
* @type {(
|
|
98
|
-
* undefined)}
|
|
108
|
+
* @type {(StdIoOptions|undefined)}
|
|
99
109
|
* @see https://nodejs.org/dist/latest-v4.x/docs/api/child_process.html#child_process_options_stdio
|
|
100
110
|
*/
|
|
101
111
|
ServiceOptions.prototype.stdio;
|
|
@@ -128,7 +138,8 @@ class DriverService {
|
|
|
128
138
|
this.port_ = options.port;
|
|
129
139
|
|
|
130
140
|
/**
|
|
131
|
-
* @private {!(Array<
|
|
141
|
+
* @private {!(Array<CommandLineFlag>|
|
|
142
|
+
* IThenable<!Array<CommandLineFlag>>)}
|
|
132
143
|
*/
|
|
133
144
|
this.args_ = options.args;
|
|
134
145
|
|
|
@@ -199,11 +210,12 @@ class DriverService {
|
|
|
199
210
|
this.command_ = new Promise(resolve => resolveCommand = resolve);
|
|
200
211
|
|
|
201
212
|
this.address_ = new Promise((resolveAddress, rejectAddress) => {
|
|
202
|
-
resolveAddress(Promise.resolve(this.port_).then(
|
|
213
|
+
resolveAddress(Promise.resolve(this.port_).then(port => {
|
|
203
214
|
if (port <= 0) {
|
|
204
215
|
throw Error('Port must be > 0: ' + port);
|
|
205
216
|
}
|
|
206
|
-
|
|
217
|
+
|
|
218
|
+
return resolveCommandLineFlags(this.args_).then(args => {
|
|
207
219
|
var command = exec(self.executable_, {
|
|
208
220
|
args: args,
|
|
209
221
|
env: self.env_,
|
|
@@ -235,15 +247,18 @@ class DriverService {
|
|
|
235
247
|
pathname: self.path_
|
|
236
248
|
});
|
|
237
249
|
|
|
238
|
-
return new Promise(
|
|
239
|
-
|
|
240
|
-
.
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
250
|
+
return new Promise((fulfill, reject) => {
|
|
251
|
+
let cancelToken =
|
|
252
|
+
earlyTermination.catch(e => reject(Error(e.message)));
|
|
253
|
+
|
|
254
|
+
httpUtil.waitForServer(serverUrl, timeout, cancelToken)
|
|
255
|
+
.then(_ => fulfill(serverUrl), err => {
|
|
256
|
+
if (err instanceof promise.CancellationError) {
|
|
257
|
+
fulfill(serverUrl);
|
|
258
|
+
} else {
|
|
259
|
+
reject(err);
|
|
260
|
+
}
|
|
261
|
+
});
|
|
247
262
|
});
|
|
248
263
|
});
|
|
249
264
|
}));
|
|
@@ -271,7 +286,7 @@ class DriverService {
|
|
|
271
286
|
/**
|
|
272
287
|
* Schedules a task in the current control flow to stop the server if it is
|
|
273
288
|
* currently running.
|
|
274
|
-
* @return {!promise.
|
|
289
|
+
* @return {!promise.Thenable} A promise that will be resolved when
|
|
275
290
|
* the server has been stopped.
|
|
276
291
|
*/
|
|
277
292
|
stop() {
|
|
@@ -280,6 +295,17 @@ class DriverService {
|
|
|
280
295
|
}
|
|
281
296
|
|
|
282
297
|
|
|
298
|
+
/**
|
|
299
|
+
* @param {!(Array<CommandLineFlag>|IThenable<!Array<CommandLineFlag>>)} args
|
|
300
|
+
* @return {!Promise<!Array<string>>}
|
|
301
|
+
*/
|
|
302
|
+
function resolveCommandLineFlags(args) {
|
|
303
|
+
// Resolve the outer array, then the individual flags.
|
|
304
|
+
return Promise.resolve(args)
|
|
305
|
+
.then(/** !Array<CommandLineFlag> */args => Promise.all(args));
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
|
|
283
309
|
/**
|
|
284
310
|
* The default amount of time, in milliseconds, to wait for the server to
|
|
285
311
|
* start.
|
|
@@ -288,6 +314,151 @@ class DriverService {
|
|
|
288
314
|
DriverService.DEFAULT_START_TIMEOUT_MS = 30 * 1000;
|
|
289
315
|
|
|
290
316
|
|
|
317
|
+
/**
|
|
318
|
+
* Creates {@link DriverService} objects that manage a WebDriver server in a
|
|
319
|
+
* child process.
|
|
320
|
+
*/
|
|
321
|
+
DriverService.Builder = class {
|
|
322
|
+
/**
|
|
323
|
+
* @param {string} exe Path to the executable to use. This executable must
|
|
324
|
+
* accept the `--port` flag for defining the port to start the server on.
|
|
325
|
+
* @throws {Error} If the provided executable path does not exist.
|
|
326
|
+
*/
|
|
327
|
+
constructor(exe) {
|
|
328
|
+
if (!fs.existsSync(exe)) {
|
|
329
|
+
throw Error(`The specified executable path does not exist: ${exe}`);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/** @private @const {string} */
|
|
333
|
+
this.exe_ = exe;
|
|
334
|
+
|
|
335
|
+
/** @private {!ServiceOptions} */
|
|
336
|
+
this.options_ = {
|
|
337
|
+
args: [],
|
|
338
|
+
port: 0,
|
|
339
|
+
env: null,
|
|
340
|
+
stdio: 'ignore'
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Define additional command line arguments to use when starting the server.
|
|
346
|
+
*
|
|
347
|
+
* @param {...CommandLineFlag} var_args The arguments to include.
|
|
348
|
+
* @return {!THIS} A self reference.
|
|
349
|
+
* @this {THIS}
|
|
350
|
+
* @template THIS
|
|
351
|
+
*/
|
|
352
|
+
addArguments(var_args) {
|
|
353
|
+
let args = Array.prototype.slice.call(arguments, 0);
|
|
354
|
+
this.options_.args = this.options_.args.concat(args);
|
|
355
|
+
return this;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Sets the host name to access the server on. If specified, the
|
|
360
|
+
* {@linkplain #setLoopback() loopback} setting will be ignored.
|
|
361
|
+
*
|
|
362
|
+
* @param {string} hostname
|
|
363
|
+
* @return {!DriverService.Builder} A self reference.
|
|
364
|
+
*/
|
|
365
|
+
setHostname(hostname) {
|
|
366
|
+
this.options_.hostname = hostname;
|
|
367
|
+
return this;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Sets whether the service should be accessed at this host's loopback
|
|
372
|
+
* address.
|
|
373
|
+
*
|
|
374
|
+
* @param {boolean} loopback
|
|
375
|
+
* @return {!DriverService.Builder} A self reference.
|
|
376
|
+
*/
|
|
377
|
+
setLoopback(loopback) {
|
|
378
|
+
this.options_.loopback = loopback;
|
|
379
|
+
return this;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Sets the base path for WebDriver REST commands (e.g. "/wd/hub").
|
|
384
|
+
* By default, the driver will accept commands relative to "/".
|
|
385
|
+
*
|
|
386
|
+
* @param {?string} basePath The base path to use, or `null` to use the
|
|
387
|
+
* default.
|
|
388
|
+
* @return {!DriverService.Builder} A self reference.
|
|
389
|
+
*/
|
|
390
|
+
setPath(basePath) {
|
|
391
|
+
this.options_.path = basePath;
|
|
392
|
+
return this;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Sets the port to start the server on.
|
|
397
|
+
*
|
|
398
|
+
* @param {number} port The port to use, or 0 for any free port.
|
|
399
|
+
* @return {!DriverService.Builder} A self reference.
|
|
400
|
+
* @throws {Error} If an invalid port is specified.
|
|
401
|
+
*/
|
|
402
|
+
setPort(port) {
|
|
403
|
+
if (port < 0) {
|
|
404
|
+
throw Error(`port must be >= 0: ${port}`);
|
|
405
|
+
}
|
|
406
|
+
this.options_.port = port;
|
|
407
|
+
return this;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Defines the environment to start the server under. This setting will be
|
|
412
|
+
* inherited by every browser session started by the server. By default, the
|
|
413
|
+
* server will inherit the enviroment of the current process.
|
|
414
|
+
*
|
|
415
|
+
* @param {(Map<string, string>|Object<string, string>|null)} env The desired
|
|
416
|
+
* environment to use, or `null` if the server should inherit the
|
|
417
|
+
* current environment.
|
|
418
|
+
* @return {!DriverService.Builder} A self reference.
|
|
419
|
+
*/
|
|
420
|
+
setEnvironment(env) {
|
|
421
|
+
if (env instanceof Map) {
|
|
422
|
+
let tmp = {};
|
|
423
|
+
env.forEach((value, key) => tmp[key] = value);
|
|
424
|
+
env = tmp;
|
|
425
|
+
}
|
|
426
|
+
this.options_.env = env;
|
|
427
|
+
return this;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* IO configuration for the spawned server process. For more information,
|
|
432
|
+
* refer to the documentation of `child_process.spawn`.
|
|
433
|
+
*
|
|
434
|
+
* @param {StdIoOptions} config The desired IO configuration.
|
|
435
|
+
* @return {!DriverService.Builder} A self reference.
|
|
436
|
+
* @see https://nodejs.org/dist/latest-v4.x/docs/api/child_process.html#child_process_options_stdio
|
|
437
|
+
*/
|
|
438
|
+
setStdio(config) {
|
|
439
|
+
this.options_.stdio = config;
|
|
440
|
+
return this;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* Creates a new DriverService using this instance's current configuration.
|
|
445
|
+
*
|
|
446
|
+
* @return {!DriverService} A new driver service.
|
|
447
|
+
*/
|
|
448
|
+
build() {
|
|
449
|
+
let port = this.options_.port || portprober.findFreePort();
|
|
450
|
+
let args = Promise.resolve(port).then(port => {
|
|
451
|
+
return this.options_.args.concat('--port=' + port);
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
let options =
|
|
455
|
+
/** @type {!ServiceOptions} */
|
|
456
|
+
(Object.assign({}, this.options_, {args, port}));
|
|
457
|
+
return new DriverService(this.exe_, options);
|
|
458
|
+
}
|
|
459
|
+
};
|
|
460
|
+
|
|
461
|
+
|
|
291
462
|
/**
|
|
292
463
|
* Manages the life and death of the
|
|
293
464
|
* <a href="http://selenium-release.storage.googleapis.com/index.html">
|