selenium-webdriver 3.3.0 → 4.0.0-alpha.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 +273 -0
- package/NOTICE +1 -1
- package/README.md +28 -36
- package/chrome.js +221 -146
- package/edge.js +43 -118
- package/example/chrome_android.js +8 -9
- package/example/chrome_mobile_emulation.js +9 -10
- package/example/firefox_channels.js +23 -19
- package/example/google_search.js +3 -3
- package/example/google_search_test.js +39 -27
- package/example/headless.js +55 -0
- package/example/logging.js +40 -7
- package/firefox.js +769 -0
- package/http/index.js +41 -4
- package/http/util.js +11 -6
- package/ie.js +57 -98
- package/index.js +182 -115
- package/io/index.js +59 -0
- package/io/zip.js +214 -0
- package/jasmine.json +11 -0
- package/lib/actions.js +68 -63
- package/lib/atoms/get-attribute.js +9 -0
- package/lib/atoms/is-displayed.js +73 -78
- package/lib/by.js +9 -1
- package/lib/capabilities.js +303 -201
- package/lib/command.js +28 -50
- package/lib/error.js +113 -42
- package/lib/http.js +167 -135
- package/lib/input.js +1044 -8
- package/lib/promise.js +222 -3331
- package/lib/proxy.js +134 -39
- package/lib/test/bootstrap_jasmine.js +28 -0
- package/lib/test/data/actions/click.html +24 -0
- package/lib/test/data/actions/drag.html +77 -0
- package/lib/test/data/actions/record_click.html +21 -0
- package/lib/test/data/chrome/download.html +2 -0
- package/lib/test/data/click_tests/disabled_element.html +12 -0
- package/lib/test/data/content-editable.html +10 -0
- package/lib/test/data/firefox/webextension.xpi +0 -0
- package/lib/test/data/inputs.html +42 -0
- package/lib/test/data/key_logger.html +34 -0
- package/lib/test/data/nestedElements.html +10 -1
- package/lib/test/data/scrolling_tests/page_with_partially_hidden_element.html +14 -0
- package/lib/test/data/selectPage.html +12 -0
- package/lib/test/data/simpleTest.html +5 -0
- package/lib/test/data/single_text_input.html +12 -0
- package/lib/test/data/upload_invisible.html +45 -0
- package/lib/test/fileserver.js +23 -19
- package/lib/test/index.js +30 -244
- package/lib/test/resources.js +0 -1
- package/lib/webdriver.js +770 -939
- package/net/index.js +21 -25
- package/net/portprober.js +51 -68
- package/package.json +6 -4
- package/remote/index.js +18 -30
- package/safari.js +42 -129
- package/test/actions_test.js +173 -18
- package/test/builder_test.js +106 -0
- package/test/chrome/devtools_test.js +93 -0
- package/test/chrome/options_test.js +48 -154
- package/test/chrome/service_test.js +7 -7
- package/test/cookie_test.js +77 -63
- package/test/element_finding_test.js +206 -201
- package/test/execute_script_test.js +115 -114
- package/test/fingerprint_test.js +16 -15
- package/test/firefox_test.js +251 -0
- package/test/http/http_test.js +18 -1
- package/test/http/util_test.js +2 -2
- package/test/{io_test.js → io/io_test.js} +40 -1
- package/test/io/zip_test.js +127 -0
- package/test/lib/by_test.js +21 -0
- package/test/lib/error_test.js +55 -8
- package/test/lib/http_test.js +18 -130
- package/test/lib/input_test.js +1379 -0
- package/test/lib/promise_test.js +473 -908
- package/test/lib/webdriver_test.js +357 -825
- package/test/logging_test.js +37 -43
- package/test/page_loading_test.js +70 -86
- package/test/proxy_test.js +64 -72
- package/test/rect_test.js +14 -25
- package/test/remote_test.js +13 -32
- package/test/safari_test.js +7 -71
- package/test/stale_element_test.js +20 -23
- package/test/tag_name_test.js +10 -9
- package/test/upload_test.js +27 -35
- package/test/window_test.js +72 -85
- package/testing/index.js +386 -315
- package/.npmignore +0 -2
- package/example/async_await_test.js +0 -68
- package/example/google_search_generator.js +0 -50
- package/example/parallel_flows.js +0 -54
- package/firefox/binary.js +0 -344
- package/firefox/extension.js +0 -187
- package/firefox/index.js +0 -722
- package/firefox/profile.js +0 -430
- package/lib/atoms/getAttribute.js +0 -12
- package/lib/events.js +0 -210
- package/lib/firefox/webdriver.json +0 -70
- package/lib/firefox/webdriver.xpi +0 -0
- package/lib/test/data/firefox/jetpack-sample.xpi +0 -0
- package/lib/test/data/firefox/sample.xpi +0 -0
- package/lib/test/promise.js +0 -79
- package/opera.js +0 -405
- package/phantomjs.js +0 -282
- package/test/firefox/extension_test.js +0 -96
- package/test/firefox/firefox_test.js +0 -226
- package/test/firefox/profile_test.js +0 -185
- package/test/lib/events_test.js +0 -177
- package/test/lib/promise_aplus_test.js +0 -78
- package/test/lib/promise_error_test.js +0 -884
- package/test/lib/promise_flow_test.js +0 -2288
- package/test/lib/promise_generator_test.js +0 -310
- package/test/phantomjs/execute_phantomjs_test.js +0 -59
- package/test/session_test.js +0 -54
- package/test/testing/assert_test.js +0 -373
- package/test/testing/index_test.js +0 -224
- package/testing/assert.js +0 -378
package/chrome.js
CHANGED
|
@@ -36,6 +36,20 @@
|
|
|
36
36
|
* a unique browser session with a clean user profile (unless otherwise
|
|
37
37
|
* configured through the {@link Options} class).
|
|
38
38
|
*
|
|
39
|
+
* __Headless Chrome__ <a id="headless"></a>
|
|
40
|
+
*
|
|
41
|
+
* To start Chrome in headless mode, simply call
|
|
42
|
+
* {@linkplain Options#headless Options.headless()}. Note, starting in headless
|
|
43
|
+
* mode currently also disables GPU acceleration.
|
|
44
|
+
*
|
|
45
|
+
* let chrome = require('selenium-webdriver/chrome');
|
|
46
|
+
* let {Builder} = require('selenium-webdriver');
|
|
47
|
+
*
|
|
48
|
+
* let driver = new Builder()
|
|
49
|
+
* .forBrowser('chrome')
|
|
50
|
+
* .setChromeOptions(new chrome.Options().headless())
|
|
51
|
+
* .build();
|
|
52
|
+
*
|
|
39
53
|
* __Customizing the ChromeDriver Server__ <a id="custom-server"></a>
|
|
40
54
|
*
|
|
41
55
|
* By default, every Chrome session will use a single driver service, which is
|
|
@@ -114,19 +128,20 @@
|
|
|
114
128
|
|
|
115
129
|
'use strict';
|
|
116
130
|
|
|
117
|
-
const fs = require('fs')
|
|
118
|
-
|
|
131
|
+
const fs = require('fs');
|
|
132
|
+
const util = require('util');
|
|
119
133
|
|
|
120
|
-
const http = require('./http')
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
134
|
+
const http = require('./http');
|
|
135
|
+
const io = require('./io');
|
|
136
|
+
const {Browser, Capabilities, Capability} = require('./lib/capabilities');
|
|
137
|
+
const command = require('./lib/command');
|
|
138
|
+
const error = require('./lib/error');
|
|
139
|
+
const logging = require('./lib/logging');
|
|
140
|
+
const promise = require('./lib/promise');
|
|
141
|
+
const Symbols = require('./lib/symbols');
|
|
142
|
+
const webdriver = require('./lib/webdriver');
|
|
143
|
+
const portprober = require('./net/portprober');
|
|
144
|
+
const remote = require('./remote');
|
|
130
145
|
|
|
131
146
|
|
|
132
147
|
/**
|
|
@@ -143,7 +158,10 @@ const CHROMEDRIVER_EXE =
|
|
|
143
158
|
* @enum {string}
|
|
144
159
|
*/
|
|
145
160
|
const Command = {
|
|
146
|
-
LAUNCH_APP: 'launchApp'
|
|
161
|
+
LAUNCH_APP: 'launchApp',
|
|
162
|
+
GET_NETWORK_CONDITIONS: 'getNetworkConditions',
|
|
163
|
+
SET_NETWORK_CONDITIONS: 'setNetworkConditions',
|
|
164
|
+
SEND_DEVTOOLS_COMMAND: 'sendDevToolsCommand',
|
|
147
165
|
};
|
|
148
166
|
|
|
149
167
|
|
|
@@ -169,6 +187,29 @@ function configureExecutor(executor) {
|
|
|
169
187
|
Command.LAUNCH_APP,
|
|
170
188
|
'POST',
|
|
171
189
|
'/session/:sessionId/chromium/launch_app');
|
|
190
|
+
executor.defineCommand(
|
|
191
|
+
Command.GET_NETWORK_CONDITIONS,
|
|
192
|
+
'GET',
|
|
193
|
+
'/session/:sessionId/chromium/network_conditions');
|
|
194
|
+
executor.defineCommand(
|
|
195
|
+
Command.SET_NETWORK_CONDITIONS,
|
|
196
|
+
'POST',
|
|
197
|
+
'/session/:sessionId/chromium/network_conditions');
|
|
198
|
+
executor.defineCommand(
|
|
199
|
+
Command.SEND_DEVTOOLS_COMMAND,
|
|
200
|
+
'POST',
|
|
201
|
+
'/session/:sessionId/chromium/send_command');
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* _Synchronously_ attempts to locate the chromedriver executable on the current
|
|
207
|
+
* system.
|
|
208
|
+
*
|
|
209
|
+
* @return {?string} the located executable, or `null`.
|
|
210
|
+
*/
|
|
211
|
+
function locateSynchronously() {
|
|
212
|
+
return io.findInPath(CHROMEDRIVER_EXE, true);
|
|
172
213
|
}
|
|
173
214
|
|
|
174
215
|
|
|
@@ -186,7 +227,7 @@ class ServiceBuilder extends remote.DriverService.Builder {
|
|
|
186
227
|
* cannot be found on the PATH.
|
|
187
228
|
*/
|
|
188
229
|
constructor(opt_exe) {
|
|
189
|
-
let exe = opt_exe ||
|
|
230
|
+
let exe = opt_exe || locateSynchronously();
|
|
190
231
|
if (!exe) {
|
|
191
232
|
throw Error(
|
|
192
233
|
'The ChromeDriver could not be found on the current PATH. Please ' +
|
|
@@ -283,68 +324,25 @@ function getDefaultService() {
|
|
|
283
324
|
}
|
|
284
325
|
|
|
285
326
|
|
|
286
|
-
|
|
287
|
-
* @type {string}
|
|
288
|
-
* @const
|
|
289
|
-
*/
|
|
290
|
-
let OPTIONS_CAPABILITY_KEY = 'chromeOptions';
|
|
327
|
+
const OPTIONS_CAPABILITY_KEY = 'chromeOptions';
|
|
291
328
|
|
|
292
329
|
|
|
293
330
|
/**
|
|
294
331
|
* Class for managing ChromeDriver specific options.
|
|
295
332
|
*/
|
|
296
|
-
class Options {
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
/** @private {?logging.Preferences} */
|
|
305
|
-
this.logPrefs_ = null;
|
|
306
|
-
|
|
307
|
-
/** @private {?./lib/capabilities.ProxyConfig} */
|
|
308
|
-
this.proxy_ = null;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
/**
|
|
312
|
-
* Extracts the ChromeDriver specific options from the given capabilities
|
|
313
|
-
* object.
|
|
314
|
-
* @param {!Capabilities} caps The capabilities object.
|
|
315
|
-
* @return {!Options} The ChromeDriver options.
|
|
316
|
-
*/
|
|
317
|
-
static fromCapabilities(caps) {
|
|
318
|
-
let options = new Options();
|
|
319
|
-
|
|
320
|
-
let o = caps.get(OPTIONS_CAPABILITY_KEY);
|
|
321
|
-
if (o instanceof Options) {
|
|
322
|
-
options = o;
|
|
323
|
-
} else if (o) {
|
|
324
|
-
options.
|
|
325
|
-
addArguments(o.args || []).
|
|
326
|
-
addExtensions(o.extensions || []).
|
|
327
|
-
detachDriver(o.detach).
|
|
328
|
-
excludeSwitches(o.excludeSwitches || []).
|
|
329
|
-
setChromeBinaryPath(o.binary).
|
|
330
|
-
setChromeLogFile(o.logPath).
|
|
331
|
-
setChromeMinidumpPath(o.minidumpPath).
|
|
332
|
-
setLocalState(o.localState).
|
|
333
|
-
setMobileEmulation(o.mobileEmulation).
|
|
334
|
-
setUserPreferences(o.prefs).
|
|
335
|
-
setPerfLoggingPrefs(o.perfLoggingPrefs);
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
if (caps.has(Capability.PROXY)) {
|
|
339
|
-
options.setProxy(caps.get(Capability.PROXY));
|
|
340
|
-
}
|
|
333
|
+
class Options extends Capabilities {
|
|
334
|
+
/**
|
|
335
|
+
* @param {(Capabilities|Map<string, ?>|Object)=} other Another set of
|
|
336
|
+
* capabilities to initialize this instance from.
|
|
337
|
+
*/
|
|
338
|
+
constructor(other = undefined) {
|
|
339
|
+
super(other);
|
|
341
340
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
caps.get(Capability.LOGGING_PREFS));
|
|
345
|
-
}
|
|
341
|
+
/** @private {!Object} */
|
|
342
|
+
this.options_ = this.get(OPTIONS_CAPABILITY_KEY) || {};
|
|
346
343
|
|
|
347
|
-
|
|
344
|
+
this.setBrowserName(Browser.CHROME);
|
|
345
|
+
this.set(OPTIONS_CAPABILITY_KEY, this.options_);
|
|
348
346
|
}
|
|
349
347
|
|
|
350
348
|
/**
|
|
@@ -352,28 +350,67 @@ class Options {
|
|
|
352
350
|
* browser. Each argument may be specified with or without the "--" prefix
|
|
353
351
|
* (e.g. "--foo" and "foo"). Arguments with an associated value should be
|
|
354
352
|
* delimited by an "=": "foo=bar".
|
|
355
|
-
*
|
|
353
|
+
*
|
|
354
|
+
* @param {...(string|!Array<string>)} args The arguments to add.
|
|
356
355
|
* @return {!Options} A self reference.
|
|
357
356
|
*/
|
|
358
|
-
addArguments(
|
|
359
|
-
let
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
this.options_.args = args;
|
|
357
|
+
addArguments(...args) {
|
|
358
|
+
let newArgs = (this.options_.args || []).concat(...args);
|
|
359
|
+
if (newArgs.length) {
|
|
360
|
+
this.options_.args = newArgs;
|
|
363
361
|
}
|
|
364
362
|
return this;
|
|
365
363
|
}
|
|
366
364
|
|
|
365
|
+
/**
|
|
366
|
+
* Configures the chromedriver to start Chrome in headless mode.
|
|
367
|
+
*
|
|
368
|
+
* > __NOTE:__ Resizing the browser window in headless mode is only supported
|
|
369
|
+
* > in Chrome 60. Users are encouraged to set an initial window size with
|
|
370
|
+
* > the {@link #windowSize windowSize({width, height})} option.
|
|
371
|
+
*
|
|
372
|
+
* > __NOTE__: For security, Chrome disables downloads by default when
|
|
373
|
+
* > in headless mode (to prevent sites from silently downloading files to
|
|
374
|
+
* > your machine). After creating a session, you may call
|
|
375
|
+
* > {@link ./chrome.Driver#setDownloadPath setDownloadPath} to re-enable
|
|
376
|
+
* > downloads, saving files in the specified directory.
|
|
377
|
+
*
|
|
378
|
+
* @return {!Options} A self reference.
|
|
379
|
+
*/
|
|
380
|
+
headless() {
|
|
381
|
+
// TODO(jleyba): Remove `disable-gpu` once head Chrome no longer requires
|
|
382
|
+
// that to be set.
|
|
383
|
+
return this.addArguments('headless', 'disable-gpu');
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Sets the initial window size.
|
|
388
|
+
*
|
|
389
|
+
* @param {{width: number, height: number}} size The desired window size.
|
|
390
|
+
* @return {!Options} A self reference.
|
|
391
|
+
* @throws {TypeError} if width or height is unspecified, not a number, or
|
|
392
|
+
* less than or equal to 0.
|
|
393
|
+
*/
|
|
394
|
+
windowSize({width, height}) {
|
|
395
|
+
function checkArg(arg) {
|
|
396
|
+
if (typeof arg !== 'number' || arg <= 0) {
|
|
397
|
+
throw TypeError('Arguments must be {width, height} with numbers > 0');
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
checkArg(width);
|
|
401
|
+
checkArg(height);
|
|
402
|
+
return this.addArguments(`window-size=${width},${height}`);
|
|
403
|
+
}
|
|
404
|
+
|
|
367
405
|
/**
|
|
368
406
|
* List of Chrome command line switches to exclude that ChromeDriver by default
|
|
369
407
|
* passes when starting Chrome. Do not prefix switches with "--".
|
|
370
408
|
*
|
|
371
|
-
* @param {...(string|!Array<string>)}
|
|
409
|
+
* @param {...(string|!Array<string>)} args The switches to exclude.
|
|
372
410
|
* @return {!Options} A self reference.
|
|
373
411
|
*/
|
|
374
|
-
excludeSwitches(
|
|
375
|
-
let switches = this.options_.excludeSwitches || [];
|
|
376
|
-
switches = switches.concat.apply(switches, arguments);
|
|
412
|
+
excludeSwitches(...args) {
|
|
413
|
+
let switches = (this.options_.excludeSwitches || []).concat(...args);
|
|
377
414
|
if (switches.length) {
|
|
378
415
|
this.options_.excludeSwitches = switches;
|
|
379
416
|
}
|
|
@@ -384,13 +421,13 @@ class Options {
|
|
|
384
421
|
* Add additional extensions to install when launching Chrome. Each extension
|
|
385
422
|
* should be specified as the path to the packed CRX file, or a Buffer for an
|
|
386
423
|
* extension.
|
|
387
|
-
* @param {...(string|!Buffer|!Array<(string|!Buffer)>)}
|
|
424
|
+
* @param {...(string|!Buffer|!Array<(string|!Buffer)>)} args The
|
|
388
425
|
* extensions to add.
|
|
389
426
|
* @return {!Options} A self reference.
|
|
390
427
|
*/
|
|
391
|
-
addExtensions(
|
|
392
|
-
this.
|
|
393
|
-
|
|
428
|
+
addExtensions(...args) {
|
|
429
|
+
let current = this.options_.extensions || [];
|
|
430
|
+
this.options_.extensions = current.concat(...args);
|
|
394
431
|
return this;
|
|
395
432
|
}
|
|
396
433
|
|
|
@@ -434,16 +471,6 @@ class Options {
|
|
|
434
471
|
return this;
|
|
435
472
|
}
|
|
436
473
|
|
|
437
|
-
/**
|
|
438
|
-
* Sets the logging preferences for the new session.
|
|
439
|
-
* @param {!logging.Preferences} prefs The logging preferences.
|
|
440
|
-
* @return {!Options} A self reference.
|
|
441
|
-
*/
|
|
442
|
-
setLoggingPrefs(prefs) {
|
|
443
|
-
this.logPrefs_ = prefs;
|
|
444
|
-
return this;
|
|
445
|
-
}
|
|
446
|
-
|
|
447
474
|
/**
|
|
448
475
|
* Sets the performance logging preferences. Options include:
|
|
449
476
|
*
|
|
@@ -621,54 +648,25 @@ class Options {
|
|
|
621
648
|
return this;
|
|
622
649
|
}
|
|
623
650
|
|
|
624
|
-
/**
|
|
625
|
-
* Sets the proxy settings for the new session.
|
|
626
|
-
* @param {./lib/capabilities.ProxyConfig} proxy The proxy configuration to
|
|
627
|
-
* use.
|
|
628
|
-
* @return {!Options} A self reference.
|
|
629
|
-
*/
|
|
630
|
-
setProxy(proxy) {
|
|
631
|
-
this.proxy_ = proxy;
|
|
632
|
-
return this;
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
/**
|
|
636
|
-
* Converts this options instance to a {@link Capabilities} object.
|
|
637
|
-
* @param {Capabilities=} opt_capabilities The capabilities to merge
|
|
638
|
-
* these options into, if any.
|
|
639
|
-
* @return {!Capabilities} The capabilities.
|
|
640
|
-
*/
|
|
641
|
-
toCapabilities(opt_capabilities) {
|
|
642
|
-
let caps = opt_capabilities || Capabilities.chrome();
|
|
643
|
-
caps.
|
|
644
|
-
set(Capability.PROXY, this.proxy_).
|
|
645
|
-
set(Capability.LOGGING_PREFS, this.logPrefs_).
|
|
646
|
-
set(OPTIONS_CAPABILITY_KEY, this);
|
|
647
|
-
return caps;
|
|
648
|
-
}
|
|
649
|
-
|
|
650
651
|
/**
|
|
651
652
|
* Converts this instance to its JSON wire protocol representation. Note this
|
|
652
653
|
* function is an implementation not intended for general use.
|
|
654
|
+
*
|
|
653
655
|
* @return {!Object} The JSON wire protocol representation of this instance.
|
|
656
|
+
* @suppress {checkTypes} Suppress [] access on a struct.
|
|
654
657
|
*/
|
|
655
658
|
[Symbols.serialize]() {
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
return extension.toString('base64');
|
|
666
|
-
}
|
|
667
|
-
return io.read(/** @type {string} */(extension))
|
|
668
|
-
.then(buffer => buffer.toString('base64'));
|
|
669
|
-
});
|
|
659
|
+
if (this.options_.extensions && this.options_.extensions.length) {
|
|
660
|
+
this.options_.extensions =
|
|
661
|
+
this.options_.extensions.map(function(extension) {
|
|
662
|
+
if (Buffer.isBuffer(extension)) {
|
|
663
|
+
return extension.toString('base64');
|
|
664
|
+
}
|
|
665
|
+
return io.read(/** @type {string} */(extension))
|
|
666
|
+
.then(buffer => buffer.toString('base64'));
|
|
667
|
+
});
|
|
670
668
|
}
|
|
671
|
-
return
|
|
669
|
+
return super[Symbols.serialize]();
|
|
672
670
|
}
|
|
673
671
|
}
|
|
674
672
|
|
|
@@ -687,11 +685,9 @@ class Driver extends webdriver.WebDriver {
|
|
|
687
685
|
* for an externally managed endpoint. If neither is provided, the
|
|
688
686
|
* {@linkplain ##getDefaultService default service} will be used by
|
|
689
687
|
* default.
|
|
690
|
-
* @param {promise.ControlFlow=} opt_flow The control flow to use, or `null`
|
|
691
|
-
* to use the currently active flow.
|
|
692
688
|
* @return {!Driver} A new driver instance.
|
|
693
689
|
*/
|
|
694
|
-
static createSession(opt_config, opt_serviceExecutor
|
|
690
|
+
static createSession(opt_config, opt_serviceExecutor) {
|
|
695
691
|
let executor;
|
|
696
692
|
if (opt_serviceExecutor instanceof http.Executor) {
|
|
697
693
|
executor = opt_serviceExecutor;
|
|
@@ -701,12 +697,19 @@ class Driver extends webdriver.WebDriver {
|
|
|
701
697
|
executor = createExecutor(service.start());
|
|
702
698
|
}
|
|
703
699
|
|
|
704
|
-
let caps =
|
|
705
|
-
|
|
706
|
-
|
|
700
|
+
let caps = opt_config || Capabilities.chrome();
|
|
701
|
+
|
|
702
|
+
// W3C spec requires noProxy value to be an array of strings, but Chrome
|
|
703
|
+
// expects a single host as a string.
|
|
704
|
+
let proxy = caps.get(Capability.PROXY);
|
|
705
|
+
if (proxy && Array.isArray(proxy.noProxy)) {
|
|
706
|
+
proxy.noProxy = proxy.noProxy[0];
|
|
707
|
+
if (!proxy.noProxy) {
|
|
708
|
+
proxy.noProxy = undefined;
|
|
709
|
+
}
|
|
710
|
+
}
|
|
707
711
|
|
|
708
|
-
return /** @type {!Driver} */(
|
|
709
|
-
webdriver.WebDriver.createSession(executor, caps, opt_flow, this));
|
|
712
|
+
return /** @type {!Driver} */(super.createSession(executor, caps));
|
|
710
713
|
}
|
|
711
714
|
|
|
712
715
|
/**
|
|
@@ -719,13 +722,84 @@ class Driver extends webdriver.WebDriver {
|
|
|
719
722
|
/**
|
|
720
723
|
* Schedules a command to launch Chrome App with given ID.
|
|
721
724
|
* @param {string} id ID of the App to launch.
|
|
722
|
-
* @return {!
|
|
725
|
+
* @return {!Promise<void>} A promise that will be resolved
|
|
723
726
|
* when app is launched.
|
|
724
727
|
*/
|
|
725
728
|
launchApp(id) {
|
|
726
|
-
return this.
|
|
727
|
-
new command.Command(Command.LAUNCH_APP).setParameter('id', id)
|
|
728
|
-
|
|
729
|
+
return this.execute(
|
|
730
|
+
new command.Command(Command.LAUNCH_APP).setParameter('id', id));
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* Schedules a command to get Chrome network emulation settings.
|
|
735
|
+
* @return {!Promise} A promise that will be resolved when network
|
|
736
|
+
* emulation settings are retrievied.
|
|
737
|
+
*/
|
|
738
|
+
getNetworkConditions() {
|
|
739
|
+
return this.execute(new command.Command(Command.GET_NETWORK_CONDITIONS));
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
/**
|
|
743
|
+
* Schedules a command to set Chrome network emulation settings.
|
|
744
|
+
*
|
|
745
|
+
* __Sample Usage:__
|
|
746
|
+
*
|
|
747
|
+
* driver.setNetworkConditions({
|
|
748
|
+
* offline: false,
|
|
749
|
+
* latency: 5, // Additional latency (ms).
|
|
750
|
+
* download_throughput: 500 * 1024, // Maximal aggregated download throughput.
|
|
751
|
+
* upload_throughput: 500 * 1024 // Maximal aggregated upload throughput.
|
|
752
|
+
* });
|
|
753
|
+
*
|
|
754
|
+
* @param {Object} spec Defines the network conditions to set
|
|
755
|
+
* @return {!Promise<void>} A promise that will be resolved when network
|
|
756
|
+
* emulation settings are set.
|
|
757
|
+
*/
|
|
758
|
+
setNetworkConditions(spec) {
|
|
759
|
+
if (!spec || typeof spec !== 'object') {
|
|
760
|
+
throw TypeError('setNetworkConditions called with non-network-conditions parameter');
|
|
761
|
+
}
|
|
762
|
+
return this.execute(
|
|
763
|
+
new command.Command(Command.SET_NETWORK_CONDITIONS)
|
|
764
|
+
.setParameter('network_conditions', spec));
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
/**
|
|
768
|
+
* Sends an arbitrary devtools command to the browser.
|
|
769
|
+
*
|
|
770
|
+
* @param {string} cmd The name of the command to send.
|
|
771
|
+
* @param {Object=} params The command parameters.
|
|
772
|
+
* @return {!Promise<void>} A promise that will be resolved when the command
|
|
773
|
+
* has finished.
|
|
774
|
+
* @see <https://chromedevtools.github.io/devtools-protocol/>
|
|
775
|
+
*/
|
|
776
|
+
sendDevToolsCommand(cmd, params = {}) {
|
|
777
|
+
return this.execute(
|
|
778
|
+
new command.Command(Command.SEND_DEVTOOLS_COMMAND)
|
|
779
|
+
.setParameter('cmd', cmd)
|
|
780
|
+
.setParameter('params', params));
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
/**
|
|
784
|
+
* Sends a DevTools command to change Chrome's download directory.
|
|
785
|
+
*
|
|
786
|
+
* @param {string} path The desired download directory.
|
|
787
|
+
* @return {!Promise<void>} A promise that will be resolved when the command
|
|
788
|
+
* has finished.
|
|
789
|
+
* @see #sendDevToolsCommand
|
|
790
|
+
*/
|
|
791
|
+
async setDownloadPath(path) {
|
|
792
|
+
if (!path || typeof path !== 'string') {
|
|
793
|
+
throw new error.InvalidArgumentError('invalid download path');
|
|
794
|
+
}
|
|
795
|
+
const stat = await io.stat(path);
|
|
796
|
+
if (!stat.isDirectory()) {
|
|
797
|
+
throw new error.InvalidArgumentError('not a directory: ' + path);
|
|
798
|
+
}
|
|
799
|
+
return this.sendDevToolsCommand('Page.setDownloadBehavior', {
|
|
800
|
+
'behavior': 'allow',
|
|
801
|
+
'downloadPath': path
|
|
802
|
+
});
|
|
729
803
|
}
|
|
730
804
|
}
|
|
731
805
|
|
|
@@ -738,3 +812,4 @@ exports.Options = Options;
|
|
|
738
812
|
exports.ServiceBuilder = ServiceBuilder;
|
|
739
813
|
exports.getDefaultService = getDefaultService;
|
|
740
814
|
exports.setDefaultService = setDefaultService;
|
|
815
|
+
exports.locateSynchronously = locateSynchronously;
|