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/index.js
CHANGED
|
@@ -22,27 +22,23 @@
|
|
|
22
22
|
|
|
23
23
|
'use strict';
|
|
24
24
|
|
|
25
|
-
const chrome = require('./chrome');
|
|
26
|
-
const edge = require('./edge');
|
|
27
|
-
const firefox = require('./firefox');
|
|
28
25
|
const _http = require('./http');
|
|
29
|
-
const ie = require('./ie');
|
|
30
|
-
const actions = require('./lib/actions');
|
|
31
26
|
const by = require('./lib/by');
|
|
32
27
|
const capabilities = require('./lib/capabilities');
|
|
28
|
+
const chrome = require('./chrome');
|
|
33
29
|
const command = require('./lib/command');
|
|
30
|
+
const edge = require('./edge');
|
|
34
31
|
const error = require('./lib/error');
|
|
35
|
-
const
|
|
32
|
+
const firefox = require('./firefox');
|
|
33
|
+
const ie = require('./ie');
|
|
36
34
|
const input = require('./lib/input');
|
|
37
35
|
const logging = require('./lib/logging');
|
|
38
36
|
const promise = require('./lib/promise');
|
|
37
|
+
const remote = require('./remote');
|
|
38
|
+
const safari = require('./safari');
|
|
39
39
|
const session = require('./lib/session');
|
|
40
40
|
const until = require('./lib/until');
|
|
41
41
|
const webdriver = require('./lib/webdriver');
|
|
42
|
-
const opera = require('./opera');
|
|
43
|
-
const phantomjs = require('./phantomjs');
|
|
44
|
-
const remote = require('./remote');
|
|
45
|
-
const safari = require('./safari');
|
|
46
42
|
|
|
47
43
|
const Browser = capabilities.Browser;
|
|
48
44
|
const Capabilities = capabilities.Capabilities;
|
|
@@ -107,7 +103,7 @@ function ensureFileDetectorsAreEnabled(ctor) {
|
|
|
107
103
|
* every issued command will fail.
|
|
108
104
|
*
|
|
109
105
|
* @extends {webdriver.IWebDriver}
|
|
110
|
-
* @extends {
|
|
106
|
+
* @extends {IThenable<!webdriver.IWebDriver>}
|
|
111
107
|
* @interface
|
|
112
108
|
*/
|
|
113
109
|
class ThenableWebDriver {
|
|
@@ -131,7 +127,10 @@ const THENABLE_DRIVERS = new Map;
|
|
|
131
127
|
function createDriver(ctor, ...args) {
|
|
132
128
|
let thenableWebDriverProxy = THENABLE_DRIVERS.get(ctor);
|
|
133
129
|
if (!thenableWebDriverProxy) {
|
|
134
|
-
/**
|
|
130
|
+
/**
|
|
131
|
+
* @extends {WebDriver} // Needed since `ctor` is dynamically typed.
|
|
132
|
+
* @implements {ThenableWebDriver}
|
|
133
|
+
*/
|
|
135
134
|
thenableWebDriverProxy = class extends ctor {
|
|
136
135
|
/**
|
|
137
136
|
* @param {!IThenable<!Session>} session
|
|
@@ -144,24 +143,13 @@ function createDriver(ctor, ...args) {
|
|
|
144
143
|
return new ctor(session, ...rest);
|
|
145
144
|
});
|
|
146
145
|
|
|
147
|
-
/**
|
|
148
|
-
* @param {(string|Error)=} opt_reason
|
|
149
|
-
* @override
|
|
150
|
-
*/
|
|
151
|
-
this.cancel = function(opt_reason) {
|
|
152
|
-
if (promise.CancellableThenable.isImplementation(pd)) {
|
|
153
|
-
/** @type {!promise.CancellableThenable} */(pd).cancel(opt_reason);
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
|
|
157
146
|
/** @override */
|
|
158
147
|
this.then = pd.then.bind(pd);
|
|
159
148
|
|
|
160
149
|
/** @override */
|
|
161
|
-
this.catch = pd.
|
|
150
|
+
this.catch = pd.catch.bind(pd);
|
|
162
151
|
}
|
|
163
152
|
};
|
|
164
|
-
promise.CancellableThenable.addImplementation(thenableWebDriverProxy);
|
|
165
153
|
THENABLE_DRIVERS.set(ctor, thenableWebDriverProxy);
|
|
166
154
|
}
|
|
167
155
|
return thenableWebDriverProxy.createSession(...args);
|
|
@@ -212,9 +200,6 @@ class Builder {
|
|
|
212
200
|
/** @private @const */
|
|
213
201
|
this.log_ = logging.getLogger('webdriver.Builder');
|
|
214
202
|
|
|
215
|
-
/** @private {promise.ControlFlow} */
|
|
216
|
-
this.flow_ = null;
|
|
217
|
-
|
|
218
203
|
/** @private {string} */
|
|
219
204
|
this.url_ = '';
|
|
220
205
|
|
|
@@ -227,11 +212,14 @@ class Builder {
|
|
|
227
212
|
/** @private {chrome.Options} */
|
|
228
213
|
this.chromeOptions_ = null;
|
|
229
214
|
|
|
215
|
+
/** @private {chrome.ServiceBuilder} */
|
|
216
|
+
this.chromeService_ = null;
|
|
217
|
+
|
|
230
218
|
/** @private {firefox.Options} */
|
|
231
219
|
this.firefoxOptions_ = null;
|
|
232
220
|
|
|
233
|
-
/** @private {
|
|
234
|
-
this.
|
|
221
|
+
/** @private {firefox.ServiceBuilder} */
|
|
222
|
+
this.firefoxService_ = null;
|
|
235
223
|
|
|
236
224
|
/** @private {ie.Options} */
|
|
237
225
|
this.ieOptions_ = null;
|
|
@@ -242,6 +230,9 @@ class Builder {
|
|
|
242
230
|
/** @private {edge.Options} */
|
|
243
231
|
this.edgeOptions_ = null;
|
|
244
232
|
|
|
233
|
+
/** @private {remote.DriverService.Builder} */
|
|
234
|
+
this.edgeService_ = null;
|
|
235
|
+
|
|
245
236
|
/** @private {boolean} */
|
|
246
237
|
this.ignoreEnv_ = false;
|
|
247
238
|
|
|
@@ -355,18 +346,22 @@ class Builder {
|
|
|
355
346
|
* environment variable. If set, this environment variable should be of the
|
|
356
347
|
* form `browser[:[version][:platform]]`.
|
|
357
348
|
*
|
|
358
|
-
* @param {(string
|
|
349
|
+
* @param {(string|!Browser)} name The name of the target browser;
|
|
359
350
|
* common defaults are available on the {@link webdriver.Browser} enum.
|
|
360
351
|
* @param {string=} opt_version A desired version; may be omitted if any
|
|
361
352
|
* version should be used.
|
|
362
|
-
* @param {string=} opt_platform
|
|
363
|
-
*
|
|
353
|
+
* @param {(string|!capabilities.Platform)=} opt_platform
|
|
354
|
+
* The desired platform; may be omitted if any platform may be used.
|
|
364
355
|
* @return {!Builder} A self reference.
|
|
365
356
|
*/
|
|
366
357
|
forBrowser(name, opt_version, opt_platform) {
|
|
367
|
-
this.capabilities_.
|
|
368
|
-
|
|
369
|
-
|
|
358
|
+
this.capabilities_.setBrowserName(name);
|
|
359
|
+
if (opt_version) {
|
|
360
|
+
this.capabilities_.setBrowserVersion(opt_version);
|
|
361
|
+
}
|
|
362
|
+
if (opt_platform) {
|
|
363
|
+
this.capabilities_.setPlatform(opt_platform);
|
|
364
|
+
}
|
|
370
365
|
return this;
|
|
371
366
|
}
|
|
372
367
|
|
|
@@ -375,7 +370,7 @@ class Builder {
|
|
|
375
370
|
* Any calls to {@link #withCapabilities} after this function will
|
|
376
371
|
* overwrite these settings.
|
|
377
372
|
*
|
|
378
|
-
* @param {
|
|
373
|
+
* @param {!./lib/proxy.Config} config The configuration to use.
|
|
379
374
|
* @return {!Builder} A self reference.
|
|
380
375
|
*/
|
|
381
376
|
setProxy(config) {
|
|
@@ -395,33 +390,13 @@ class Builder {
|
|
|
395
390
|
return this;
|
|
396
391
|
}
|
|
397
392
|
|
|
398
|
-
/**
|
|
399
|
-
* Sets whether native events should be used.
|
|
400
|
-
* @param {boolean} enabled Whether to enable native events.
|
|
401
|
-
* @return {!Builder} A self reference.
|
|
402
|
-
*/
|
|
403
|
-
setEnableNativeEvents(enabled) {
|
|
404
|
-
this.capabilities_.setEnableNativeEvents(enabled);
|
|
405
|
-
return this;
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
/**
|
|
409
|
-
* Sets how elements should be scrolled into view for interaction.
|
|
410
|
-
* @param {number} behavior The desired scroll behavior: either 0 to align
|
|
411
|
-
* with the top of the viewport or 1 to align with the bottom.
|
|
412
|
-
* @return {!Builder} A self reference.
|
|
413
|
-
*/
|
|
414
|
-
setScrollBehavior(behavior) {
|
|
415
|
-
this.capabilities_.setScrollBehavior(behavior);
|
|
416
|
-
return this;
|
|
417
|
-
}
|
|
418
|
-
|
|
419
393
|
/**
|
|
420
394
|
* Sets the default action to take with an unexpected alert before returning
|
|
421
395
|
* an error.
|
|
422
|
-
*
|
|
423
|
-
*
|
|
396
|
+
*
|
|
397
|
+
* @param {?capabilities.UserPromptHandler} behavior The desired behavior.
|
|
424
398
|
* @return {!Builder} A self reference.
|
|
399
|
+
* @see capabilities.Capabilities#setAlertBehavior
|
|
425
400
|
*/
|
|
426
401
|
setAlertBehavior(behavior) {
|
|
427
402
|
this.capabilities_.setAlertBehavior(behavior);
|
|
@@ -442,6 +417,29 @@ class Builder {
|
|
|
442
417
|
return this;
|
|
443
418
|
}
|
|
444
419
|
|
|
420
|
+
/**
|
|
421
|
+
* @return {chrome.Options} the Chrome specific options currently configured
|
|
422
|
+
* for this builder.
|
|
423
|
+
*/
|
|
424
|
+
getChromeOptions() {
|
|
425
|
+
return this.chromeOptions_;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Sets the service builder to use for managing the chromedriver child process
|
|
430
|
+
* when creating new Chrome sessions.
|
|
431
|
+
*
|
|
432
|
+
* @param {chrome.ServiceBuilder} service the service to use.
|
|
433
|
+
* @return {!Builder} A self reference.
|
|
434
|
+
*/
|
|
435
|
+
setChromeService(service) {
|
|
436
|
+
if (service && !(service instanceof chrome.ServiceBuilder)) {
|
|
437
|
+
throw TypeError('not a chrome.ServiceBuilder object');
|
|
438
|
+
}
|
|
439
|
+
this.chromeService_ = service;
|
|
440
|
+
return this;
|
|
441
|
+
}
|
|
442
|
+
|
|
445
443
|
/**
|
|
446
444
|
* Sets Firefox specific {@linkplain firefox.Options options} for drivers
|
|
447
445
|
* created by this builder. Any logging or proxy settings defined on the given
|
|
@@ -465,16 +463,17 @@ class Builder {
|
|
|
465
463
|
}
|
|
466
464
|
|
|
467
465
|
/**
|
|
468
|
-
* Sets
|
|
469
|
-
*
|
|
470
|
-
* will take precedence over those set through {@link #setLoggingPrefs} and
|
|
471
|
-
* {@link #setProxy}, respectively.
|
|
466
|
+
* Sets the {@link firefox.ServiceBuilder} to use to manage the geckodriver
|
|
467
|
+
* child process when creating Firefox sessions locally.
|
|
472
468
|
*
|
|
473
|
-
* @param {
|
|
474
|
-
* @return {!Builder}
|
|
469
|
+
* @param {firefox.ServiceBuilder} service the service to use.
|
|
470
|
+
* @return {!Builder} a self reference.
|
|
475
471
|
*/
|
|
476
|
-
|
|
477
|
-
|
|
472
|
+
setFirefoxService(service) {
|
|
473
|
+
if (service && !(service instanceof firefox.ServiceBuilder)) {
|
|
474
|
+
throw TypeError('not a firefox.ServiceBuilder object');
|
|
475
|
+
}
|
|
476
|
+
this.firefoxService_ = service;
|
|
478
477
|
return this;
|
|
479
478
|
}
|
|
480
479
|
|
|
@@ -505,6 +504,21 @@ class Builder {
|
|
|
505
504
|
return this;
|
|
506
505
|
}
|
|
507
506
|
|
|
507
|
+
/**
|
|
508
|
+
* Sets the {@link edge.ServiceBuilder} to use to manage the
|
|
509
|
+
* MicrosoftEdgeDriver child process when creating sessions locally.
|
|
510
|
+
*
|
|
511
|
+
* @param {edge.ServiceBuilder} service the service to use.
|
|
512
|
+
* @return {!Builder} a self reference.
|
|
513
|
+
*/
|
|
514
|
+
setEdgeService(service) {
|
|
515
|
+
if (service && !(service instanceof edge.ServiceBuilder)) {
|
|
516
|
+
throw TypeError('not a edge.ServiceBuilder object');
|
|
517
|
+
}
|
|
518
|
+
this.edgeService_ = service;
|
|
519
|
+
return this;
|
|
520
|
+
}
|
|
521
|
+
|
|
508
522
|
/**
|
|
509
523
|
* Sets Safari specific {@linkplain safari.Options options} for drivers
|
|
510
524
|
* created by this builder. Any logging settings defined on the given options
|
|
@@ -526,19 +540,6 @@ class Builder {
|
|
|
526
540
|
return this.safariOptions_;
|
|
527
541
|
}
|
|
528
542
|
|
|
529
|
-
/**
|
|
530
|
-
* Sets the control flow that created drivers should execute actions in. If
|
|
531
|
-
* the flow is never set, or is set to {@code null}, it will use the active
|
|
532
|
-
* flow at the time {@link #build()} is called.
|
|
533
|
-
* @param {promise.ControlFlow} flow The control flow to use, or
|
|
534
|
-
* {@code null} to
|
|
535
|
-
* @return {!Builder} A self reference.
|
|
536
|
-
*/
|
|
537
|
-
setControlFlow(flow) {
|
|
538
|
-
this.flow_ = flow;
|
|
539
|
-
return this;
|
|
540
|
-
}
|
|
541
|
-
|
|
542
543
|
/**
|
|
543
544
|
* Creates a new WebDriver client based on this builder's current
|
|
544
545
|
* configuration.
|
|
@@ -561,9 +562,10 @@ class Builder {
|
|
|
561
562
|
if (!this.ignoreEnv_ && process.env.SELENIUM_BROWSER) {
|
|
562
563
|
this.log_.fine(`SELENIUM_BROWSER=${process.env.SELENIUM_BROWSER}`);
|
|
563
564
|
browser = process.env.SELENIUM_BROWSER.split(/:/, 3);
|
|
564
|
-
capabilities.
|
|
565
|
-
|
|
566
|
-
capabilities.
|
|
565
|
+
capabilities.setBrowserName(browser[0]);
|
|
566
|
+
|
|
567
|
+
browser[1] && capabilities.setBrowserVersion(browser[1]);
|
|
568
|
+
browser[2] && capabilities.setPlatform(browser[2]);
|
|
567
569
|
}
|
|
568
570
|
|
|
569
571
|
browser = capabilities.get(Capability.BROWSER_NAME);
|
|
@@ -580,24 +582,29 @@ class Builder {
|
|
|
580
582
|
|
|
581
583
|
// Apply browser specific overrides.
|
|
582
584
|
if (browser === Browser.CHROME && this.chromeOptions_) {
|
|
583
|
-
capabilities.merge(this.chromeOptions_
|
|
585
|
+
capabilities.merge(this.chromeOptions_);
|
|
584
586
|
|
|
585
587
|
} else if (browser === Browser.FIREFOX && this.firefoxOptions_) {
|
|
586
|
-
capabilities.merge(this.firefoxOptions_
|
|
588
|
+
capabilities.merge(this.firefoxOptions_);
|
|
587
589
|
|
|
588
590
|
} else if (browser === Browser.INTERNET_EXPLORER && this.ieOptions_) {
|
|
589
|
-
capabilities.merge(this.ieOptions_
|
|
590
|
-
|
|
591
|
-
} else if (browser === Browser.OPERA && this.operaOptions_) {
|
|
592
|
-
capabilities.merge(this.operaOptions_.toCapabilities());
|
|
591
|
+
capabilities.merge(this.ieOptions_);
|
|
593
592
|
|
|
594
593
|
} else if (browser === Browser.SAFARI && this.safariOptions_) {
|
|
595
|
-
capabilities.merge(this.safariOptions_
|
|
594
|
+
capabilities.merge(this.safariOptions_);
|
|
596
595
|
|
|
597
596
|
} else if (browser === Browser.EDGE && this.edgeOptions_) {
|
|
598
|
-
capabilities.merge(this.edgeOptions_
|
|
597
|
+
capabilities.merge(this.edgeOptions_);
|
|
599
598
|
}
|
|
600
599
|
|
|
600
|
+
checkOptions(
|
|
601
|
+
capabilities, 'chromeOptions', chrome.Options, 'setChromeOptions');
|
|
602
|
+
checkOptions(
|
|
603
|
+
capabilities, 'moz:firefoxOptions', firefox.Options,
|
|
604
|
+
'setFirefoxOptions');
|
|
605
|
+
checkOptions(
|
|
606
|
+
capabilities, 'safari.options', safari.Options, 'setSafariOptions');
|
|
607
|
+
|
|
601
608
|
// Check for a remote browser.
|
|
602
609
|
let url = this.url_;
|
|
603
610
|
if (!this.ignoreEnv_) {
|
|
@@ -620,41 +627,47 @@ class Builder {
|
|
|
620
627
|
|
|
621
628
|
if (browser === Browser.CHROME) {
|
|
622
629
|
const driver = ensureFileDetectorsAreEnabled(chrome.Driver);
|
|
623
|
-
return createDriver(
|
|
624
|
-
driver, capabilities, executor, this.flow_);
|
|
630
|
+
return createDriver(driver, capabilities, executor);
|
|
625
631
|
}
|
|
626
632
|
|
|
627
633
|
if (browser === Browser.FIREFOX) {
|
|
628
634
|
const driver = ensureFileDetectorsAreEnabled(firefox.Driver);
|
|
629
|
-
return createDriver(
|
|
630
|
-
driver, capabilities, executor, this.flow_);
|
|
635
|
+
return createDriver(driver, capabilities, executor);
|
|
631
636
|
}
|
|
632
|
-
return createDriver(
|
|
633
|
-
WebDriver, executor, capabilities, this.flow_);
|
|
637
|
+
return createDriver(WebDriver, executor, capabilities);
|
|
634
638
|
}
|
|
635
639
|
|
|
636
640
|
// Check for a native browser.
|
|
637
641
|
switch (browser) {
|
|
638
|
-
case Browser.CHROME:
|
|
639
|
-
|
|
642
|
+
case Browser.CHROME: {
|
|
643
|
+
let service = null;
|
|
644
|
+
if (this.chromeService_) {
|
|
645
|
+
service = this.chromeService_.build();
|
|
646
|
+
}
|
|
647
|
+
return createDriver(chrome.Driver, capabilities, service);
|
|
648
|
+
}
|
|
640
649
|
|
|
641
|
-
case Browser.FIREFOX:
|
|
642
|
-
|
|
650
|
+
case Browser.FIREFOX: {
|
|
651
|
+
let service = null;
|
|
652
|
+
if (this.firefoxService_) {
|
|
653
|
+
service = this.firefoxService_.build();
|
|
654
|
+
}
|
|
655
|
+
return createDriver(firefox.Driver, capabilities, service);
|
|
656
|
+
}
|
|
643
657
|
|
|
644
658
|
case Browser.INTERNET_EXPLORER:
|
|
645
|
-
return createDriver(ie.Driver, capabilities
|
|
646
|
-
|
|
647
|
-
case Browser.EDGE:
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
return createDriver(phantomjs.Driver, capabilities, this.flow_);
|
|
659
|
+
return createDriver(ie.Driver, capabilities);
|
|
660
|
+
|
|
661
|
+
case Browser.EDGE: {
|
|
662
|
+
let service = null;
|
|
663
|
+
if (this.edgeService_) {
|
|
664
|
+
service = this.edgeService_.build();
|
|
665
|
+
}
|
|
666
|
+
return createDriver(edge.Driver, capabilities, service);
|
|
667
|
+
}
|
|
655
668
|
|
|
656
669
|
case Browser.SAFARI:
|
|
657
|
-
return createDriver(safari.Driver, capabilities
|
|
670
|
+
return createDriver(safari.Driver, capabilities);
|
|
658
671
|
|
|
659
672
|
default:
|
|
660
673
|
throw new Error('Do not know how to build driver: ' + browser
|
|
@@ -664,10 +677,66 @@ class Builder {
|
|
|
664
677
|
}
|
|
665
678
|
|
|
666
679
|
|
|
680
|
+
/**
|
|
681
|
+
* In the 3.x releases, the various browser option classes
|
|
682
|
+
* (e.g. firefox.Options) had to be manually set as an option using the
|
|
683
|
+
* Capabilties class:
|
|
684
|
+
*
|
|
685
|
+
* let ffo = new firefox.Options();
|
|
686
|
+
* // Configure firefox options...
|
|
687
|
+
*
|
|
688
|
+
* let caps = new Capabilities();
|
|
689
|
+
* caps.set('moz:firefoxOptions', ffo);
|
|
690
|
+
*
|
|
691
|
+
* let driver = new Builder()
|
|
692
|
+
* .withCapabilities(caps)
|
|
693
|
+
* .build();
|
|
694
|
+
*
|
|
695
|
+
* The options are now subclasses of Capabilities and can be used directly. A
|
|
696
|
+
* direct translation of the above is:
|
|
697
|
+
*
|
|
698
|
+
* let ffo = new firefox.Options();
|
|
699
|
+
* // Configure firefox options...
|
|
700
|
+
*
|
|
701
|
+
* let driver = new Builder()
|
|
702
|
+
* .withCapabilities(ffo)
|
|
703
|
+
* .build();
|
|
704
|
+
*
|
|
705
|
+
* You can also set the options for various browsers at once and let the builder
|
|
706
|
+
* choose the correct set at runtime (see Builder docs above):
|
|
707
|
+
*
|
|
708
|
+
* let ffo = new firefox.Options();
|
|
709
|
+
* // Configure ...
|
|
710
|
+
*
|
|
711
|
+
* let co = new chrome.Options();
|
|
712
|
+
* // Configure ...
|
|
713
|
+
*
|
|
714
|
+
* let driver = new Builder()
|
|
715
|
+
* .setChromeOptions(co)
|
|
716
|
+
* .setFirefoxOptions(ffo)
|
|
717
|
+
* .build();
|
|
718
|
+
*
|
|
719
|
+
* @param {!Capabilities} caps
|
|
720
|
+
* @param {string} key
|
|
721
|
+
* @param {function(new: Capabilities)} optionType
|
|
722
|
+
* @param {string} setMethod
|
|
723
|
+
* @throws {error.InvalidArgumentError}
|
|
724
|
+
*/
|
|
725
|
+
function checkOptions(caps, key, optionType, setMethod) {
|
|
726
|
+
let val = caps.get(key);
|
|
727
|
+
if (val instanceof optionType) {
|
|
728
|
+
throw new error.InvalidArgumentError(
|
|
729
|
+
'Options class extends Capabilities and should not be set as key '
|
|
730
|
+
+ `"${key}"; set browser-specific options with `
|
|
731
|
+
+ `Builder.${setMethod}(). For more information, see the `
|
|
732
|
+
+ 'documentation attached to the function that threw this error');
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
|
|
667
737
|
// PUBLIC API
|
|
668
738
|
|
|
669
739
|
|
|
670
|
-
exports.ActionSequence = actions.ActionSequence;
|
|
671
740
|
exports.Browser = capabilities.Browser;
|
|
672
741
|
exports.Builder = Builder;
|
|
673
742
|
exports.Button = input.Button;
|
|
@@ -675,12 +744,10 @@ exports.By = by.By;
|
|
|
675
744
|
exports.Capabilities = capabilities.Capabilities;
|
|
676
745
|
exports.Capability = capabilities.Capability;
|
|
677
746
|
exports.Condition = webdriver.Condition;
|
|
678
|
-
exports.EventEmitter = events.EventEmitter;
|
|
679
747
|
exports.FileDetector = input.FileDetector;
|
|
680
748
|
exports.Key = input.Key;
|
|
681
749
|
exports.Session = session.Session;
|
|
682
750
|
exports.ThenableWebDriver = ThenableWebDriver;
|
|
683
|
-
exports.TouchSequence = actions.TouchSequence;
|
|
684
751
|
exports.WebDriver = webdriver.WebDriver;
|
|
685
752
|
exports.WebElement = webdriver.WebElement;
|
|
686
753
|
exports.WebElementCondition = webdriver.WebElementCondition;
|
package/io/index.js
CHANGED
|
@@ -298,3 +298,62 @@ exports.mkdir = function(aPath) {
|
|
|
298
298
|
});
|
|
299
299
|
});
|
|
300
300
|
};
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Recursively creates a directory and any ancestors that do not yet exist.
|
|
305
|
+
*
|
|
306
|
+
* @param {string} dir The directory path to create.
|
|
307
|
+
* @return {!Promise<string>} A promise that will resolve with the path of the
|
|
308
|
+
* created directory.
|
|
309
|
+
*/
|
|
310
|
+
exports.mkdirp = function mkdirp(dir) {
|
|
311
|
+
return checkedCall(callback => {
|
|
312
|
+
fs.mkdir(dir, undefined, err => {
|
|
313
|
+
if (!err) {
|
|
314
|
+
callback(null, dir);
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
switch (err.code) {
|
|
319
|
+
case 'EEXIST':
|
|
320
|
+
callback(null, dir);
|
|
321
|
+
return;
|
|
322
|
+
case 'ENOENT':
|
|
323
|
+
return mkdirp(path.dirname(dir))
|
|
324
|
+
.then(() => mkdirp(dir))
|
|
325
|
+
.then(() => callback(null, dir), err => callback(err));
|
|
326
|
+
default:
|
|
327
|
+
callback(err);
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
});
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Recursively walks a directory, returning a promise that will resolve with
|
|
337
|
+
* a list of all files/directories seen.
|
|
338
|
+
*
|
|
339
|
+
* @param {string} rootPath the directory to walk.
|
|
340
|
+
* @return {!Promise<!Array<{path: string, dir: boolean}>>} a promise that will
|
|
341
|
+
* resolve with a list of entries seen. For each entry, the recorded path
|
|
342
|
+
* will be relative to `rootPath`.
|
|
343
|
+
*/
|
|
344
|
+
exports.walkDir = function(rootPath) {
|
|
345
|
+
let seen = [];
|
|
346
|
+
return (function walk(dir) {
|
|
347
|
+
return checkedCall(callback => fs.readdir(dir, callback))
|
|
348
|
+
.then(files => Promise.all(files.map(file => {
|
|
349
|
+
file = path.join(dir, file);
|
|
350
|
+
return checkedCall(cb => fs.stat(file, cb)).then(stats => {
|
|
351
|
+
seen.push({
|
|
352
|
+
path: path.relative(rootPath, file),
|
|
353
|
+
dir: stats.isDirectory()
|
|
354
|
+
});
|
|
355
|
+
return stats.isDirectory() && walk(file);
|
|
356
|
+
});
|
|
357
|
+
})));
|
|
358
|
+
})(rootPath).then(() => seen);
|
|
359
|
+
};
|