selenium-webdriver 3.5.0 → 3.6.0
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 +39 -0
- package/README.md +3 -6
- package/example/async_await_test.js +5 -4
- package/example/chrome_android.js +2 -3
- package/example/chrome_mobile_emulation.js +2 -3
- package/example/firefox_channels.js +3 -3
- package/example/google_search.js +3 -3
- package/example/google_search_generator.js +2 -5
- package/example/google_search_test.js +4 -5
- package/example/{chrome_headless.js → headless.js} +15 -7
- package/example/logging.js +3 -3
- package/example/parallel_flows.js +4 -7
- package/firefox/binary.js +3 -0
- package/firefox/index.js +117 -167
- package/firefox/profile.js +7 -90
- package/lib/atoms/{getAttribute.js → get-attribute.js} +0 -0
- package/lib/capabilities.js +60 -21
- package/lib/error.js +19 -1
- package/lib/http.js +1 -1
- package/lib/promise.js +4 -12
- package/lib/test/data/content-editable.html +10 -0
- package/lib/test/data/scrolling_tests/page_with_partially_hidden_element.html +14 -0
- package/lib/test/index.js +1 -1
- package/lib/webdriver.js +29 -33
- package/package.json +1 -1
- package/remote/index.js +4 -3
- package/test/firefox/firefox_test.js +16 -33
- package/test/lib/error_test.js +1 -0
- package/testing/index.js +2 -3
- package/lib/firefox/webdriver.json +0 -70
package/firefox/index.js
CHANGED
|
@@ -124,7 +124,6 @@ const url = require('url');
|
|
|
124
124
|
|
|
125
125
|
const {Binary, Channel} = require('./binary'),
|
|
126
126
|
Profile = require('./profile').Profile,
|
|
127
|
-
decodeProfile = require('./profile').decode,
|
|
128
127
|
http = require('../http'),
|
|
129
128
|
httpUtil = require('../http/util'),
|
|
130
129
|
io = require('../io'),
|
|
@@ -138,35 +137,6 @@ const {Binary, Channel} = require('./binary'),
|
|
|
138
137
|
remote = require('../remote');
|
|
139
138
|
|
|
140
139
|
|
|
141
|
-
/**
|
|
142
|
-
* Firefox-specific capability keys. Users should use the {@linkplain Options}
|
|
143
|
-
* class instead of referencing these keys directly. _These keys are considered
|
|
144
|
-
* implementation details and may be removed or changed at any time._
|
|
145
|
-
*
|
|
146
|
-
* @enum {string}
|
|
147
|
-
*/
|
|
148
|
-
const Capability = {
|
|
149
|
-
/**
|
|
150
|
-
* Defines the Firefox binary to use. May be set to either a
|
|
151
|
-
* {@linkplain Binary} instance, or a string path to the Firefox executable.
|
|
152
|
-
*/
|
|
153
|
-
BINARY: 'firefox_binary',
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* @deprecated This will be removed in a future release. There is no
|
|
157
|
-
* replacement.
|
|
158
|
-
*/
|
|
159
|
-
MARIONETTE: 'marionette',
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Defines the Firefox profile to use. May be set to either a
|
|
163
|
-
* {@linkplain Profile} instance, or to a base-64 encoded zip of a profile
|
|
164
|
-
* directory.
|
|
165
|
-
*/
|
|
166
|
-
PROFILE: 'firefox_profile'
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
|
|
170
140
|
/**
|
|
171
141
|
* Configuration options for the FirefoxDriver.
|
|
172
142
|
*/
|
|
@@ -175,9 +145,12 @@ class Options {
|
|
|
175
145
|
/** @private {Profile} */
|
|
176
146
|
this.profile_ = null;
|
|
177
147
|
|
|
178
|
-
/** @private {Binary} */
|
|
148
|
+
/** @private {(Binary|Channel|string|null)} */
|
|
179
149
|
this.binary_ = null;
|
|
180
150
|
|
|
151
|
+
/** @private {!Array<string>} */
|
|
152
|
+
this.args_ = [];
|
|
153
|
+
|
|
181
154
|
/** @private {logging.Preferences} */
|
|
182
155
|
this.logPrefs_ = null;
|
|
183
156
|
|
|
@@ -185,6 +158,47 @@ class Options {
|
|
|
185
158
|
this.proxy_ = null;
|
|
186
159
|
}
|
|
187
160
|
|
|
161
|
+
/**
|
|
162
|
+
* Specify additional command line arguments that should be used when starting
|
|
163
|
+
* the Firefox browser.
|
|
164
|
+
*
|
|
165
|
+
* @param {...(string|!Array<string>)} args The arguments to include.
|
|
166
|
+
* @return {!Options} A self reference.
|
|
167
|
+
*/
|
|
168
|
+
addArguments(...args) {
|
|
169
|
+
this.args_ = this.args_.concat(...args);
|
|
170
|
+
return this;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Configures the geckodriver to start Firefox in headless mode.
|
|
175
|
+
*
|
|
176
|
+
* @return {!Options} A self reference.
|
|
177
|
+
*/
|
|
178
|
+
headless() {
|
|
179
|
+
return this.addArguments('-headless');
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Sets the initial window size when running in
|
|
184
|
+
* {@linkplain #headless headless} mode.
|
|
185
|
+
*
|
|
186
|
+
* @param {{width: number, height: number}} size The desired window size.
|
|
187
|
+
* @return {!Options} A self reference.
|
|
188
|
+
* @throws {TypeError} if width or height is unspecified, not a number, or
|
|
189
|
+
* less than or equal to 0.
|
|
190
|
+
*/
|
|
191
|
+
windowSize({width, height}) {
|
|
192
|
+
function checkArg(arg) {
|
|
193
|
+
if (typeof arg !== 'number' || arg <= 0) {
|
|
194
|
+
throw TypeError('Arguments must be {width, height} with numbers > 0');
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
checkArg(width);
|
|
198
|
+
checkArg(height);
|
|
199
|
+
return this.addArguments(`--window-size=${width},${height}`);
|
|
200
|
+
}
|
|
201
|
+
|
|
188
202
|
/**
|
|
189
203
|
* Sets the profile to use. The profile may be specified as a
|
|
190
204
|
* {@link Profile} object or as the path to an existing Firefox profile to use
|
|
@@ -211,17 +225,14 @@ class Options {
|
|
|
211
225
|
* @throws {TypeError} If `binary` is an invalid type.
|
|
212
226
|
*/
|
|
213
227
|
setBinary(binary) {
|
|
214
|
-
if (
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
throw TypeError(
|
|
220
|
-
'binary must be a string path, Channel, or Binary object');
|
|
228
|
+
if (binary instanceof Binary
|
|
229
|
+
|| binary instanceof Channel
|
|
230
|
+
|| typeof binary === 'string') {
|
|
231
|
+
this.binary_ = binary;
|
|
232
|
+
return this;
|
|
221
233
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
return this;
|
|
234
|
+
throw TypeError(
|
|
235
|
+
'binary must be a string path, Channel, or Binary object');
|
|
225
236
|
}
|
|
226
237
|
|
|
227
238
|
/**
|
|
@@ -245,33 +256,69 @@ class Options {
|
|
|
245
256
|
return this;
|
|
246
257
|
}
|
|
247
258
|
|
|
248
|
-
/**
|
|
249
|
-
* @deprecated This method has been deprecated and will be removed in the next
|
|
250
|
-
* release. It is a no-op.
|
|
251
|
-
*/
|
|
252
|
-
useGeckoDriver(enable) {
|
|
253
|
-
return this;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
259
|
/**
|
|
257
260
|
* Converts these options to a {@link capabilities.Capabilities} instance.
|
|
258
261
|
*
|
|
259
262
|
* @return {!capabilities.Capabilities} A new capabilities object.
|
|
260
263
|
*/
|
|
261
264
|
toCapabilities() {
|
|
262
|
-
|
|
265
|
+
let caps = capabilities.Capabilities.firefox();
|
|
266
|
+
let firefoxOptions = {};
|
|
267
|
+
caps.set('moz:firefoxOptions', firefoxOptions);
|
|
268
|
+
|
|
263
269
|
if (this.logPrefs_) {
|
|
264
270
|
caps.set(capabilities.Capability.LOGGING_PREFS, this.logPrefs_);
|
|
265
271
|
}
|
|
272
|
+
|
|
266
273
|
if (this.proxy_) {
|
|
267
274
|
caps.set(capabilities.Capability.PROXY, this.proxy_);
|
|
268
275
|
}
|
|
276
|
+
|
|
277
|
+
if (this.args_.length) {
|
|
278
|
+
firefoxOptions['args'] = this.args_.concat();
|
|
279
|
+
}
|
|
280
|
+
|
|
269
281
|
if (this.binary_) {
|
|
270
|
-
|
|
282
|
+
if (this.binary_ instanceof Binary) {
|
|
283
|
+
let exe = this.binary_.getExe();
|
|
284
|
+
if (exe) {
|
|
285
|
+
firefoxOptions['binary'] = exe;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
let args = this.binary_.getArguments();
|
|
289
|
+
if (args.length) {
|
|
290
|
+
if (this.args_.length) {
|
|
291
|
+
throw Error(
|
|
292
|
+
'You may specify browser arguments with Options.addArguments'
|
|
293
|
+
+ ' (preferred) or Binary.addArguments, but not both');
|
|
294
|
+
}
|
|
295
|
+
firefoxOptions['args'] = args;
|
|
296
|
+
}
|
|
297
|
+
} else if (this.binary_ instanceof Channel) {
|
|
298
|
+
firefoxOptions['binary'] = this.binary_.locate();
|
|
299
|
+
|
|
300
|
+
} else if (typeof this.binary_ === 'string') {
|
|
301
|
+
firefoxOptions['binary'] = this.binary_;
|
|
302
|
+
}
|
|
271
303
|
}
|
|
304
|
+
|
|
272
305
|
if (this.profile_) {
|
|
273
|
-
|
|
306
|
+
// If the user specified a template directory or any extensions to
|
|
307
|
+
// install, we need to encode the profile as a base64 string (which
|
|
308
|
+
// requires writing it to disk first). Otherwise, if the user just
|
|
309
|
+
// specified some custom preferences, we can send those directly.
|
|
310
|
+
let profile = this.profile_;
|
|
311
|
+
if (profile.getTemplateDir() || profile.getExtensions().length) {
|
|
312
|
+
firefoxOptions['profile'] = profile.encode();
|
|
313
|
+
|
|
314
|
+
} else {
|
|
315
|
+
let prefs = profile.getPreferences();
|
|
316
|
+
if (Object.keys(prefs).length) {
|
|
317
|
+
firefoxOptions['prefs'] = prefs;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
274
320
|
}
|
|
321
|
+
|
|
275
322
|
return caps;
|
|
276
323
|
}
|
|
277
324
|
}
|
|
@@ -410,111 +457,6 @@ class ServiceBuilder extends remote.DriverService.Builder {
|
|
|
410
457
|
enableVerboseLogging(opt_trace) {
|
|
411
458
|
return this.addArguments(opt_trace ? '-vv' : '-v');
|
|
412
459
|
}
|
|
413
|
-
|
|
414
|
-
/**
|
|
415
|
-
* Sets the path to the executable Firefox binary that the geckodriver should
|
|
416
|
-
* use. If this method is not called, this builder will attempt to locate
|
|
417
|
-
* Firefox in the default installation location for the current platform.
|
|
418
|
-
*
|
|
419
|
-
* @param {(string|!Binary)} binary Path to the executable Firefox binary to use.
|
|
420
|
-
* @return {!ServiceBuilder} A self reference.
|
|
421
|
-
* @see Binary#locate()
|
|
422
|
-
*/
|
|
423
|
-
setFirefoxBinary(binary) {
|
|
424
|
-
let exe = typeof binary === 'string'
|
|
425
|
-
? Promise.resolve(binary) : binary.locate();
|
|
426
|
-
return this.addArguments('-b', exe);
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
/**
|
|
432
|
-
* @typedef {{executor: !command.Executor,
|
|
433
|
-
* capabilities: (!capabilities.Capabilities|
|
|
434
|
-
* {desired: (capabilities.Capabilities|undefined),
|
|
435
|
-
* required: (capabilities.Capabilities|undefined)}),
|
|
436
|
-
* onQuit: function(this: void): ?}}
|
|
437
|
-
*/
|
|
438
|
-
var DriverSpec;
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
/**
|
|
442
|
-
* @param {(http.Executor|remote.DriverService|undefined)} executor
|
|
443
|
-
* @param {!capabilities.Capabilities} caps
|
|
444
|
-
* @param {Profile} profile
|
|
445
|
-
* @param {Binary} binary
|
|
446
|
-
* @return {DriverSpec}
|
|
447
|
-
*/
|
|
448
|
-
function createGeckoDriver(executor, caps, profile, binary) {
|
|
449
|
-
let firefoxOptions = caps.get('moz:firefoxOptions') || {};
|
|
450
|
-
caps.set('moz:firefoxOptions', firefoxOptions);
|
|
451
|
-
|
|
452
|
-
if (binary) {
|
|
453
|
-
if (binary.getExe()) {
|
|
454
|
-
firefoxOptions['binary'] = binary.getExe();
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
let args = binary.getArguments();
|
|
458
|
-
if (args.length) {
|
|
459
|
-
firefoxOptions['args'] = args;
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
if (profile) {
|
|
464
|
-
// If the user specified a template directory or any extensions to install,
|
|
465
|
-
// we need to encode the profile as a base64 string (which requires writing
|
|
466
|
-
// it to disk first). Otherwise, if the user just specified some custom
|
|
467
|
-
// preferences, we can send those directly.
|
|
468
|
-
if (profile.getTemplateDir() || profile.getExtensions().length) {
|
|
469
|
-
firefoxOptions['profile'] = profile.encode();
|
|
470
|
-
|
|
471
|
-
} else {
|
|
472
|
-
let prefs = profile.getPreferences();
|
|
473
|
-
if (Object.keys(prefs).length) {
|
|
474
|
-
firefoxOptions['prefs'] = prefs;
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
let sessionCaps = caps;
|
|
480
|
-
if (caps.has(capabilities.Capability.PROXY)) {
|
|
481
|
-
let proxy = normalizeProxyConfiguration(
|
|
482
|
-
caps.get(capabilities.Capability.PROXY));
|
|
483
|
-
|
|
484
|
-
// Marionette requires proxy settings to be specified as required
|
|
485
|
-
// capabilities. See mozilla/geckodriver#97
|
|
486
|
-
let required = new capabilities.Capabilities()
|
|
487
|
-
.set(capabilities.Capability.PROXY, proxy);
|
|
488
|
-
|
|
489
|
-
caps.delete(capabilities.Capability.PROXY);
|
|
490
|
-
sessionCaps = {required, desired: caps};
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
/** @type {!command.Executor} */
|
|
494
|
-
let cmdExecutor;
|
|
495
|
-
let onQuit = function() {};
|
|
496
|
-
|
|
497
|
-
if (executor instanceof http.Executor) {
|
|
498
|
-
configureExecutor(executor);
|
|
499
|
-
cmdExecutor = executor;
|
|
500
|
-
} else if (executor instanceof remote.DriverService) {
|
|
501
|
-
cmdExecutor = createExecutor(executor.start());
|
|
502
|
-
onQuit = () => executor.kill();
|
|
503
|
-
} else {
|
|
504
|
-
let builder = new ServiceBuilder();
|
|
505
|
-
if (binary) {
|
|
506
|
-
builder.setFirefoxBinary(binary);
|
|
507
|
-
}
|
|
508
|
-
let service = builder.build();
|
|
509
|
-
cmdExecutor = createExecutor(service.start());
|
|
510
|
-
onQuit = () => service.kill();
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
return {
|
|
514
|
-
executor: cmdExecutor,
|
|
515
|
-
capabilities: sessionCaps,
|
|
516
|
-
onQuit
|
|
517
|
-
};
|
|
518
460
|
}
|
|
519
461
|
|
|
520
462
|
|
|
@@ -555,21 +497,29 @@ class Driver extends webdriver.WebDriver {
|
|
|
555
497
|
caps = new capabilities.Capabilities(opt_config);
|
|
556
498
|
}
|
|
557
499
|
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
500
|
+
if (caps.has(capabilities.Capability.PROXY)) {
|
|
501
|
+
let proxy =
|
|
502
|
+
normalizeProxyConfiguration(caps.get(capabilities.Capability.PROXY));
|
|
503
|
+
caps.set(capabilities.Capability.PROXY, proxy);
|
|
562
504
|
}
|
|
563
505
|
|
|
564
|
-
let
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
506
|
+
let executor;
|
|
507
|
+
let onQuit;
|
|
508
|
+
|
|
509
|
+
if (opt_executor instanceof http.Executor) {
|
|
510
|
+
executor = opt_executor;
|
|
511
|
+
configureExecutor(executor);
|
|
512
|
+
} else if (opt_executor instanceof remote.DriverService) {
|
|
513
|
+
executor = createExecutor(opt_executor.start());
|
|
514
|
+
onQuit = () => opt_executor.kill();
|
|
515
|
+
} else {
|
|
516
|
+
let service = new ServiceBuilder().build();
|
|
517
|
+
executor = createExecutor(service.start());
|
|
518
|
+
onQuit = () => service.kill();
|
|
568
519
|
}
|
|
569
520
|
|
|
570
|
-
let spec = createGeckoDriver(opt_executor, caps, profile, binary);
|
|
571
521
|
return /** @type {!Driver} */(super.createSession(
|
|
572
|
-
|
|
522
|
+
executor, caps, opt_flow, onQuit));
|
|
573
523
|
}
|
|
574
524
|
|
|
575
525
|
/**
|
package/firefox/profile.js
CHANGED
|
@@ -33,28 +33,6 @@ const isDevMode = require('../lib/devmode'),
|
|
|
33
33
|
extension = require('./extension');
|
|
34
34
|
|
|
35
35
|
|
|
36
|
-
/** @const */
|
|
37
|
-
const WEBDRIVER_PREFERENCES_PATH = isDevMode
|
|
38
|
-
? path.join(__dirname, '../../../firefox-driver/webdriver.json')
|
|
39
|
-
: path.join(__dirname, '../lib/firefox/webdriver.json');
|
|
40
|
-
|
|
41
|
-
/** @type {Object} */
|
|
42
|
-
var defaultPreferences = null;
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Synchronously loads the default preferences used for the FirefoxDriver.
|
|
46
|
-
* @return {!Object} The default preferences JSON object.
|
|
47
|
-
*/
|
|
48
|
-
function getDefaultPreferences() {
|
|
49
|
-
if (!defaultPreferences) {
|
|
50
|
-
var contents = /** @type {string} */(
|
|
51
|
-
fs.readFileSync(WEBDRIVER_PREFERENCES_PATH, 'utf8'));
|
|
52
|
-
defaultPreferences = /** @type {!Object} */(JSON.parse(contents));
|
|
53
|
-
}
|
|
54
|
-
return defaultPreferences;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
|
|
58
36
|
/**
|
|
59
37
|
* Parses a user.js file in a Firefox profile directory.
|
|
60
38
|
* @param {string} f Path to the file to parse.
|
|
@@ -96,9 +74,13 @@ function writeUserPrefs(prefs, dir) {
|
|
|
96
74
|
var userPrefs = path.join(dir, 'user.js');
|
|
97
75
|
return loadUserPrefs(userPrefs).then(function(overrides) {
|
|
98
76
|
Object.assign(prefs, overrides);
|
|
99
|
-
Object.assign(prefs, getDefaultPreferences()['frozen']);
|
|
100
77
|
|
|
101
|
-
|
|
78
|
+
let keys = Object.keys(prefs);
|
|
79
|
+
if (!keys.length) {
|
|
80
|
+
return dir;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
let contents = Object.keys(prefs).map(function(key) {
|
|
102
84
|
return 'user_pref(' + JSON.stringify(key) + ', ' +
|
|
103
85
|
JSON.stringify(prefs[key]) + ');';
|
|
104
86
|
}).join('\n');
|
|
@@ -146,22 +128,6 @@ function installExtensions(extensions, dir) {
|
|
|
146
128
|
}
|
|
147
129
|
|
|
148
130
|
|
|
149
|
-
/**
|
|
150
|
-
* Decodes a base64 encoded profile.
|
|
151
|
-
* @param {string} data The base64 encoded string.
|
|
152
|
-
* @return {!Promise<string>} A promise for the path to the decoded profile
|
|
153
|
-
* directory.
|
|
154
|
-
*/
|
|
155
|
-
function decode(data) {
|
|
156
|
-
return io.tmpFile().then(function(file) {
|
|
157
|
-
let buf = new Buffer(data, 'base64');
|
|
158
|
-
return io.write(file, buf)
|
|
159
|
-
.then(io.tmpDir)
|
|
160
|
-
.then(dir => unzip(file, dir));
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
|
|
165
131
|
|
|
166
132
|
/**
|
|
167
133
|
* Models a Firefox profile directory for use with the FirefoxDriver. The
|
|
@@ -178,15 +144,9 @@ class Profile {
|
|
|
178
144
|
/** @private {!Object} */
|
|
179
145
|
this.preferences_ = {};
|
|
180
146
|
|
|
181
|
-
/** @private {boolean} */
|
|
182
|
-
this.nativeEventsEnabled_ = true;
|
|
183
|
-
|
|
184
147
|
/** @private {(string|undefined)} */
|
|
185
148
|
this.template_ = opt_dir;
|
|
186
149
|
|
|
187
|
-
/** @private {number} */
|
|
188
|
-
this.port_ = 0;
|
|
189
|
-
|
|
190
150
|
/** @private {!Array<string>} */
|
|
191
151
|
this.extensions_ = [];
|
|
192
152
|
}
|
|
@@ -222,12 +182,6 @@ class Profile {
|
|
|
222
182
|
* @throws {Error} If attempting to set a frozen preference.
|
|
223
183
|
*/
|
|
224
184
|
setPreference(key, value) {
|
|
225
|
-
var frozen = getDefaultPreferences()['frozen'];
|
|
226
|
-
if (frozen.hasOwnProperty(key) && frozen[key] !== value) {
|
|
227
|
-
throw Error('You may not set ' + key + '=' + JSON.stringify(value)
|
|
228
|
-
+ '; value is frozen for proper WebDriver functionality ('
|
|
229
|
-
+ key + '=' + JSON.stringify(frozen[key]) + ')');
|
|
230
|
-
}
|
|
231
185
|
this.preferences_[key] = value;
|
|
232
186
|
}
|
|
233
187
|
|
|
@@ -262,23 +216,6 @@ class Profile {
|
|
|
262
216
|
this.preferences_['webdriver_firefox_allowed_hosts'] = host;
|
|
263
217
|
}
|
|
264
218
|
|
|
265
|
-
/**
|
|
266
|
-
* @return {number} The port this profile is currently configured to use, or
|
|
267
|
-
* 0 if the port will be selected at random when the profile is written
|
|
268
|
-
* to disk.
|
|
269
|
-
*/
|
|
270
|
-
getPort() {
|
|
271
|
-
return this.port_;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
/**
|
|
275
|
-
* Sets the port to use for the WebDriver extension loaded by this profile.
|
|
276
|
-
* @param {number} port The desired port, or 0 to use any free port.
|
|
277
|
-
*/
|
|
278
|
-
setPort(port) {
|
|
279
|
-
this.port_ = port;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
219
|
/**
|
|
283
220
|
* @return {boolean} Whether the FirefoxDriver is configured to automatically
|
|
284
221
|
* accept untrusted SSL certificates.
|
|
@@ -312,22 +249,6 @@ class Profile {
|
|
|
312
249
|
return !!this.preferences_['webdriver_assume_untrusted_issuer'];
|
|
313
250
|
}
|
|
314
251
|
|
|
315
|
-
/**
|
|
316
|
-
* Sets whether to use native events with this profile.
|
|
317
|
-
* @param {boolean} enabled .
|
|
318
|
-
*/
|
|
319
|
-
setNativeEventsEnabled(enabled) {
|
|
320
|
-
this.nativeEventsEnabled_ = enabled;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* Returns whether native events are enabled in this profile.
|
|
325
|
-
* @return {boolean} .
|
|
326
|
-
*/
|
|
327
|
-
nativeEventsEnabled() {
|
|
328
|
-
return this.nativeEventsEnabled_;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
252
|
/**
|
|
332
253
|
* Writes this profile to disk.
|
|
333
254
|
* @return {!Promise<string>} A promise for the path to the new profile
|
|
@@ -344,10 +265,7 @@ class Profile {
|
|
|
344
265
|
}
|
|
345
266
|
|
|
346
267
|
// Freeze preferences for async operations.
|
|
347
|
-
|
|
348
|
-
Object.assign(prefs, getDefaultPreferences()['mutable']);
|
|
349
|
-
Object.assign(prefs, getDefaultPreferences()['frozen']);
|
|
350
|
-
Object.assign(prefs, this.preferences_);
|
|
268
|
+
let prefs = Object.assign({}, this.preferences_);
|
|
351
269
|
|
|
352
270
|
// Freeze extensions for async operations.
|
|
353
271
|
var extensions = this.extensions_.concat();
|
|
@@ -390,5 +308,4 @@ class Profile {
|
|
|
390
308
|
|
|
391
309
|
|
|
392
310
|
exports.Profile = Profile;
|
|
393
|
-
exports.decode = decode;
|
|
394
311
|
exports.loadUserPrefs = loadUserPrefs;
|
|
File without changes
|
package/lib/capabilities.js
CHANGED
|
@@ -204,16 +204,19 @@ function toMap(hash) {
|
|
|
204
204
|
/**
|
|
205
205
|
* Describes a set of capabilities for a WebDriver session.
|
|
206
206
|
*/
|
|
207
|
-
class Capabilities
|
|
207
|
+
class Capabilities {
|
|
208
208
|
/**
|
|
209
|
-
* @param {(Capabilities|Map<string, ?>|Object)=}
|
|
209
|
+
* @param {(Capabilities|Map<string, ?>|Object)=} other Another set of
|
|
210
210
|
* capabilities to initialize this instance from.
|
|
211
211
|
*/
|
|
212
|
-
constructor(
|
|
213
|
-
if (
|
|
214
|
-
|
|
212
|
+
constructor(other = undefined) {
|
|
213
|
+
if (other instanceof Capabilities) {
|
|
214
|
+
other = other.map_;
|
|
215
|
+
} else if (other && !(other instanceof Map)) {
|
|
216
|
+
other = toMap(other);
|
|
215
217
|
}
|
|
216
|
-
|
|
218
|
+
/** @private @const {!Map<string, ?>} */
|
|
219
|
+
this.map_ = new Map(other);
|
|
217
220
|
}
|
|
218
221
|
|
|
219
222
|
/**
|
|
@@ -221,8 +224,7 @@ class Capabilities extends Map {
|
|
|
221
224
|
*/
|
|
222
225
|
static android() {
|
|
223
226
|
return new Capabilities()
|
|
224
|
-
.set(Capability.BROWSER_NAME, Browser.ANDROID)
|
|
225
|
-
.set(Capability.PLATFORM, 'ANDROID');
|
|
227
|
+
.set(Capability.BROWSER_NAME, Browser.ANDROID);
|
|
226
228
|
}
|
|
227
229
|
|
|
228
230
|
/**
|
|
@@ -237,8 +239,7 @@ class Capabilities extends Map {
|
|
|
237
239
|
*/
|
|
238
240
|
static edge() {
|
|
239
241
|
return new Capabilities()
|
|
240
|
-
.set(Capability.BROWSER_NAME, Browser.EDGE)
|
|
241
|
-
.set(Capability.PLATFORM, 'WINDOWS');
|
|
242
|
+
.set(Capability.BROWSER_NAME, Browser.EDGE);
|
|
242
243
|
}
|
|
243
244
|
|
|
244
245
|
/**
|
|
@@ -253,8 +254,7 @@ class Capabilities extends Map {
|
|
|
253
254
|
*/
|
|
254
255
|
static ie() {
|
|
255
256
|
return new Capabilities().
|
|
256
|
-
set(Capability.BROWSER_NAME, Browser.INTERNET_EXPLORER)
|
|
257
|
-
set(Capability.PLATFORM, 'WINDOWS');
|
|
257
|
+
set(Capability.BROWSER_NAME, Browser.INTERNET_EXPLORER);
|
|
258
258
|
}
|
|
259
259
|
|
|
260
260
|
/**
|
|
@@ -262,8 +262,7 @@ class Capabilities extends Map {
|
|
|
262
262
|
*/
|
|
263
263
|
static ipad() {
|
|
264
264
|
return new Capabilities().
|
|
265
|
-
set(Capability.BROWSER_NAME, Browser.IPAD)
|
|
266
|
-
set(Capability.PLATFORM, 'MAC');
|
|
265
|
+
set(Capability.BROWSER_NAME, Browser.IPAD);
|
|
267
266
|
}
|
|
268
267
|
|
|
269
268
|
/**
|
|
@@ -271,8 +270,7 @@ class Capabilities extends Map {
|
|
|
271
270
|
*/
|
|
272
271
|
static iphone() {
|
|
273
272
|
return new Capabilities().
|
|
274
|
-
set(Capability.BROWSER_NAME, Browser.IPHONE)
|
|
275
|
-
set(Capability.PLATFORM, 'MAC');
|
|
273
|
+
set(Capability.BROWSER_NAME, Browser.IPHONE);
|
|
276
274
|
}
|
|
277
275
|
|
|
278
276
|
/**
|
|
@@ -296,8 +294,7 @@ class Capabilities extends Map {
|
|
|
296
294
|
*/
|
|
297
295
|
static safari() {
|
|
298
296
|
return new Capabilities().
|
|
299
|
-
set(Capability.BROWSER_NAME, Browser.SAFARI)
|
|
300
|
-
set(Capability.PLATFORM, 'MAC');
|
|
297
|
+
set(Capability.BROWSER_NAME, Browser.SAFARI);
|
|
301
298
|
}
|
|
302
299
|
|
|
303
300
|
/**
|
|
@@ -328,6 +325,35 @@ class Capabilities extends Map {
|
|
|
328
325
|
return serialize(this);
|
|
329
326
|
}
|
|
330
327
|
|
|
328
|
+
/**
|
|
329
|
+
* @param {string} key the parameter key to get.
|
|
330
|
+
* @return {T} the stored parameter value.
|
|
331
|
+
* @template T
|
|
332
|
+
*/
|
|
333
|
+
get(key) {
|
|
334
|
+
return this.map_.get(key);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* @param {string} key the key to test.
|
|
339
|
+
* @return {boolean} whether this capability set has the specified key.
|
|
340
|
+
*/
|
|
341
|
+
has(key) {
|
|
342
|
+
return this.map_.has(key);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* @return {!Iterator<string>} an iterator of the keys set.
|
|
347
|
+
*/
|
|
348
|
+
keys() {
|
|
349
|
+
return this.map_.keys();
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/** @return {number} The number of capabilities set. */
|
|
353
|
+
get size() {
|
|
354
|
+
return this.map_.size;
|
|
355
|
+
}
|
|
356
|
+
|
|
331
357
|
/**
|
|
332
358
|
* Merges another set of capabilities into this instance.
|
|
333
359
|
* @param {!(Capabilities|Map<String, ?>|Object<string, ?>)} other The other
|
|
@@ -339,7 +365,12 @@ class Capabilities extends Map {
|
|
|
339
365
|
throw new TypeError('no capabilities provided for merge');
|
|
340
366
|
}
|
|
341
367
|
|
|
342
|
-
|
|
368
|
+
let map;
|
|
369
|
+
if (other instanceof Capabilities) {
|
|
370
|
+
map = other.map_;
|
|
371
|
+
} else if (other instanceof Map) {
|
|
372
|
+
map = other;
|
|
373
|
+
} else {
|
|
343
374
|
other = toMap(other);
|
|
344
375
|
}
|
|
345
376
|
|
|
@@ -350,18 +381,26 @@ class Capabilities extends Map {
|
|
|
350
381
|
return this;
|
|
351
382
|
}
|
|
352
383
|
|
|
384
|
+
/**
|
|
385
|
+
* Deletes an entry from this set of capabilities.
|
|
386
|
+
*
|
|
387
|
+
* @param {string} key the capability key to delete.
|
|
388
|
+
*/
|
|
389
|
+
delete(key) {
|
|
390
|
+
this.map_.delete(key);
|
|
391
|
+
}
|
|
392
|
+
|
|
353
393
|
/**
|
|
354
394
|
* @param {string} key The capability key.
|
|
355
395
|
* @param {*} value The capability value.
|
|
356
396
|
* @return {!Capabilities} A self reference.
|
|
357
397
|
* @throws {TypeError} If the `key` is not a string.
|
|
358
|
-
* @override
|
|
359
398
|
*/
|
|
360
399
|
set(key, value) {
|
|
361
400
|
if (typeof key !== 'string') {
|
|
362
401
|
throw new TypeError('Capability keys must be strings: ' + typeof key);
|
|
363
402
|
}
|
|
364
|
-
|
|
403
|
+
this.map_.set(key, value);
|
|
365
404
|
return this;
|
|
366
405
|
}
|
|
367
406
|
|