selenium-webdriver 4.0.0-alpha.7 → 4.0.0-beta.3

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.
Files changed (50) hide show
  1. package/CHANGES.md +56 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +2 -0
  4. package/README.md +2 -0
  5. package/chrome.js +69 -79
  6. package/chromium.js +231 -164
  7. package/{lib/atoms/make-atoms-module.js → devtools/CDPConnection.js} +15 -9
  8. package/edge.js +104 -146
  9. package/example/chrome_android.js +45 -0
  10. package/example/chrome_mobile_emulation.js +46 -0
  11. package/example/firefox_channels.js +84 -0
  12. package/example/google_search.js +50 -0
  13. package/example/google_search_test.js +70 -0
  14. package/example/headless.js +63 -0
  15. package/example/logging.js +64 -0
  16. package/firefox.js +199 -200
  17. package/http/index.js +128 -116
  18. package/http/util.js +56 -64
  19. package/ie.js +180 -104
  20. package/index.js +246 -199
  21. package/io/exec.js +35 -40
  22. package/io/index.js +146 -157
  23. package/io/zip.js +75 -66
  24. package/lib/atoms/find-elements.js +123 -0
  25. package/lib/atoms/get-attribute.js +75 -59
  26. package/lib/atoms/is-displayed.js +72 -72
  27. package/lib/atoms/mutation-listener.js +55 -0
  28. package/lib/by.js +192 -65
  29. package/lib/capabilities.js +76 -86
  30. package/lib/command.js +19 -35
  31. package/lib/error.js +134 -168
  32. package/lib/http.js +308 -232
  33. package/lib/input.js +192 -453
  34. package/lib/logging.js +126 -137
  35. package/lib/promise.js +53 -71
  36. package/lib/proxy.js +31 -41
  37. package/lib/session.js +12 -15
  38. package/lib/symbols.js +3 -4
  39. package/lib/until.js +162 -160
  40. package/lib/webdriver.js +1014 -549
  41. package/net/index.js +30 -36
  42. package/net/portprober.js +30 -143
  43. package/opera.js +406 -0
  44. package/package.json +15 -7
  45. package/proxy.js +2 -2
  46. package/remote/index.js +189 -187
  47. package/safari.js +40 -49
  48. package/testing/index.js +504 -0
  49. package/lib/README +0 -5
  50. package/lib/actions.js +0 -609
package/firefox.js CHANGED
@@ -79,7 +79,7 @@
79
79
  * .setFirefoxOptions(options)
80
80
  * .build();
81
81
  *
82
- * On all platforms, you may configrue WebDriver to use a Firefox specific
82
+ * On all platforms, you may configure WebDriver to use a Firefox specific
83
83
  * executable:
84
84
  *
85
85
  * let options = new firefox.Options()
@@ -89,7 +89,7 @@
89
89
  *
90
90
  * You may customize the Firefox binary and profile when running against a
91
91
  * remote Selenium server. Your custom profile will be packaged as a zip and
92
- * transfered to the remote host for use. The profile will be transferred
92
+ * transferred to the remote host for use. The profile will be transferred
93
93
  * _once for each new session_. The performance impact should be minimal if
94
94
  * you've only configured a few extra browser preferences. If you have a large
95
95
  * profile with several extensions, you should consider installing it on the
@@ -114,25 +114,19 @@
114
114
  * [PATH]: http://en.wikipedia.org/wiki/PATH_%28variable%29
115
115
  */
116
116
 
117
- 'use strict';
118
-
119
- const path = require('path');
120
- const url = require('url');
121
-
122
- const Symbols = require('./lib/symbols');
123
- const command = require('./lib/command');
124
- const exec = require('./io/exec');
125
- const http = require('./http');
126
- const httpUtil = require('./http/util');
127
- const io = require('./io');
128
- const net = require('./net');
129
- const portprober = require('./net/portprober');
130
- const remote = require('./remote');
131
- const webdriver = require('./lib/webdriver');
132
- const zip = require('./io/zip');
133
- const {Browser, Capabilities} = require('./lib/capabilities');
134
- const {Zip} = require('./io/zip');
117
+ 'use strict'
135
118
 
119
+ const path = require('path')
120
+ const Symbols = require('./lib/symbols')
121
+ const command = require('./lib/command')
122
+ const http = require('./http')
123
+ const io = require('./io')
124
+ const remote = require('./remote')
125
+ const webdriver = require('./lib/webdriver')
126
+ const zip = require('./io/zip')
127
+ const cdp = require('./devtools/CDPConnection')
128
+ const { Browser, Capabilities } = require('./lib/capabilities')
129
+ const { Zip } = require('./io/zip')
136
130
 
137
131
  /**
138
132
  * Thrown when there an add-on is malformed.
@@ -141,13 +135,12 @@ const {Zip} = require('./io/zip');
141
135
  class AddonFormatError extends Error {
142
136
  /** @param {string} msg The error message. */
143
137
  constructor(msg) {
144
- super(msg);
138
+ super(msg)
145
139
  /** @override */
146
- this.name = this.constructor.name;
140
+ this.name = this.constructor.name
147
141
  }
148
142
  }
149
143
 
150
-
151
144
  /**
152
145
  * Installs an extension to the given directory.
153
146
  * @param {string} extension Path to the xpi extension file to install.
@@ -156,57 +149,53 @@ class AddonFormatError extends Error {
156
149
  * installed.
157
150
  */
158
151
  async function installExtension(extension, dir) {
159
- const ext = extension.slice(-4);
152
+ const ext = extension.slice(-4)
160
153
  if (ext !== '.xpi' && ext !== '.zip') {
161
- throw Error('File name does not end in ".zip" or ".xpi": ' + ext);
154
+ throw Error('File name does not end in ".zip" or ".xpi": ' + ext)
162
155
  }
163
156
 
164
- let archive = await zip.load(extension);
157
+ let archive = await zip.load(extension)
165
158
  if (!archive.has('manifest.json')) {
166
- throw new AddonFormatError(`Couldn't find manifest.json in ${extension}`);
159
+ throw new AddonFormatError(`Couldn't find manifest.json in ${extension}`)
167
160
  }
168
161
 
169
- let buf = await archive.getFile('manifest.json');
170
- let parsedJSON = JSON.parse(buf.toString('utf8'));
171
-
162
+ let buf = await archive.getFile('manifest.json')
163
+ let parsedJSON = JSON.parse(buf.toString('utf8'))
164
+
172
165
  let { browser_specific_settings } =
173
166
  /** @type {{browser_specific_settings:{gecko:{id:string}}}} */
174
- parsedJSON;
167
+ parsedJSON
175
168
 
176
- if (
177
- browser_specific_settings &&
178
- browser_specific_settings.gecko
179
- ) {
169
+ if (browser_specific_settings && browser_specific_settings.gecko) {
180
170
  /* browser_specific_settings is an alternative to applications
181
171
  * It is meant to facilitate cross-browser plugins since Firefox48
182
172
  * see https://bugzilla.mozilla.org/show_bug.cgi?id=1262005
183
173
  */
184
- parsedJSON.applications = browser_specific_settings;
174
+ parsedJSON.applications = browser_specific_settings
185
175
  }
186
176
 
187
177
  let { applications } =
188
178
  /** @type {{applications:{gecko:{id:string}}}} */
189
- parsedJSON;
179
+ parsedJSON
190
180
  if (!(applications && applications.gecko && applications.gecko.id)) {
191
- throw new AddonFormatError(`Could not find add-on ID for ${extension}`);
181
+ throw new AddonFormatError(`Could not find add-on ID for ${extension}`)
192
182
  }
193
183
 
194
- await io.copy(extension, `${path.join(dir, applications.gecko.id)}.xpi`);
195
- return applications.gecko.id;
184
+ await io.copy(extension, `${path.join(dir, applications.gecko.id)}.xpi`)
185
+ return applications.gecko.id
196
186
  }
197
187
 
198
-
199
188
  class Profile {
200
189
  constructor() {
201
190
  /** @private {?string} */
202
- this.template_ = null;
191
+ this.template_ = null
203
192
 
204
193
  /** @private {!Array<string>} */
205
- this.extensions_ = [];
194
+ this.extensions_ = []
206
195
  }
207
196
 
208
- addExtensions(/** !Array<string> */paths) {
209
- this.extensions_ = this.extensions_.concat(...paths);
197
+ addExtensions(/** !Array<string> */ paths) {
198
+ this.extensions_ = this.extensions_.concat(...paths)
210
199
  }
211
200
 
212
201
  /**
@@ -215,13 +204,12 @@ class Profile {
215
204
  */
216
205
  [Symbols.serialize]() {
217
206
  if (this.template_ || this.extensions_.length) {
218
- return buildProfile(this.template_, this.extensions_);
207
+ return buildProfile(this.template_, this.extensions_)
219
208
  }
220
- return undefined;
209
+ return undefined
221
210
  }
222
211
  }
223
212
 
224
-
225
213
  /**
226
214
  * @param {?string} template path to an existing profile to use as a template.
227
215
  * @param {!Array<string>} extensions paths to extensions to install in the new
@@ -229,31 +217,33 @@ class Profile {
229
217
  * @return {!Promise<string>} a promise for the base64 encoded profile.
230
218
  */
231
219
  async function buildProfile(template, extensions) {
232
- let dir = template;
220
+ let dir = template
233
221
 
234
222
  if (extensions.length) {
235
- dir = await io.tmpDir();
223
+ dir = await io.tmpDir()
236
224
  if (template) {
237
225
  await io.copyDir(
238
- /** @type {string} */(template),
239
- dir, /(parent\.lock|lock|\.parentlock)/);
226
+ /** @type {string} */(template),
227
+ dir,
228
+ /(parent\.lock|lock|\.parentlock)/
229
+ )
240
230
  }
241
231
 
242
- const extensionsDir = path.join(dir, 'extensions');
243
- await io.mkdir(extensionsDir);
232
+ const extensionsDir = path.join(dir, 'extensions')
233
+ await io.mkdir(extensionsDir)
244
234
 
245
235
  for (let i = 0; i < extensions.length; i++) {
246
- await installExtension(extensions[i], extensionsDir);
236
+ await installExtension(extensions[i], extensionsDir)
247
237
  }
248
238
  }
249
239
 
250
- let zip = new Zip;
251
- return zip.addDir(dir)
252
- .then(() => zip.toBuffer())
253
- .then(buf => buf.toString('base64'));
240
+ let zip = new Zip()
241
+ return zip
242
+ .addDir(dir)
243
+ .then(() => zip.toBuffer())
244
+ .then((buf) => buf.toString('base64'))
254
245
  }
255
246
 
256
-
257
247
  /**
258
248
  * Configuration options for the FirefoxDriver.
259
249
  */
@@ -263,8 +253,8 @@ class Options extends Capabilities {
263
253
  * capabilities to initialize this instance from.
264
254
  */
265
255
  constructor(other) {
266
- super(other);
267
- this.setBrowserName(Browser.FIREFOX);
256
+ super(other)
257
+ this.setBrowserName(Browser.FIREFOX)
268
258
  }
269
259
 
270
260
  /**
@@ -272,12 +262,12 @@ class Options extends Capabilities {
272
262
  * @private
273
263
  */
274
264
  firefoxOptions_() {
275
- let options = this.get('moz:firefoxOptions');
265
+ let options = this.get('moz:firefoxOptions')
276
266
  if (!options) {
277
- options = {};
278
- this.set('moz:firefoxOptions', options);
267
+ options = {}
268
+ this.set('moz:firefoxOptions', options)
279
269
  }
280
- return options;
270
+ return options
281
271
  }
282
272
 
283
273
  /**
@@ -285,11 +275,11 @@ class Options extends Capabilities {
285
275
  * @private
286
276
  */
287
277
  profile_() {
288
- let options = this.firefoxOptions_();
278
+ let options = this.firefoxOptions_()
289
279
  if (!options.profile) {
290
- options.profile = new Profile();
280
+ options.profile = new Profile()
291
281
  }
292
- return options.profile;
282
+ return options.profile
293
283
  }
294
284
 
295
285
  /**
@@ -301,10 +291,10 @@ class Options extends Capabilities {
301
291
  */
302
292
  addArguments(...args) {
303
293
  if (args.length) {
304
- let options = this.firefoxOptions_();
305
- options.args = options.args ? options.args.concat(...args) : args;
294
+ let options = this.firefoxOptions_()
295
+ options.args = options.args ? options.args.concat(...args) : args
306
296
  }
307
- return this;
297
+ return this
308
298
  }
309
299
 
310
300
  /**
@@ -313,7 +303,7 @@ class Options extends Capabilities {
313
303
  * @return {!Options} A self reference.
314
304
  */
315
305
  headless() {
316
- return this.addArguments('-headless');
306
+ return this.addArguments('-headless')
317
307
  }
318
308
 
319
309
  /**
@@ -325,15 +315,15 @@ class Options extends Capabilities {
325
315
  * @throws {TypeError} if width or height is unspecified, not a number, or
326
316
  * less than or equal to 0.
327
317
  */
328
- windowSize({width, height}) {
318
+ windowSize({ width, height }) {
329
319
  function checkArg(arg) {
330
320
  if (typeof arg !== 'number' || arg <= 0) {
331
- throw TypeError('Arguments must be {width, height} with numbers > 0');
321
+ throw TypeError('Arguments must be {width, height} with numbers > 0')
332
322
  }
333
323
  }
334
- checkArg(width);
335
- checkArg(height);
336
- return this.addArguments(`--width=${width}`, `--height=${height}`);
324
+ checkArg(width)
325
+ checkArg(height)
326
+ return this.addArguments(`--width=${width}`, `--height=${height}`)
337
327
  }
338
328
 
339
329
  /**
@@ -343,8 +333,8 @@ class Options extends Capabilities {
343
333
  * @return {!Options} A self reference.
344
334
  */
345
335
  addExtensions(...paths) {
346
- this.profile_().addExtensions(paths);
347
- return this;
336
+ this.profile_().addExtensions(paths)
337
+ return this
348
338
  }
349
339
 
350
340
  /**
@@ -355,18 +345,21 @@ class Options extends Capabilities {
355
345
  */
356
346
  setPreference(key, value) {
357
347
  if (typeof key !== 'string') {
358
- throw TypeError(`key must be a string, but got ${typeof key}`);
348
+ throw TypeError(`key must be a string, but got ${typeof key}`)
359
349
  }
360
- if (typeof value !== 'string'
361
- && typeof value !== 'number'
362
- && typeof value !== 'boolean') {
350
+ if (
351
+ typeof value !== 'string' &&
352
+ typeof value !== 'number' &&
353
+ typeof value !== 'boolean'
354
+ ) {
363
355
  throw TypeError(
364
- `value must be a string, number, or boolean, but got ${typeof value}`);
356
+ `value must be a string, number, or boolean, but got ${typeof value}`
357
+ )
365
358
  }
366
- let options = this.firefoxOptions_();
367
- options.prefs = options.prefs || {};
368
- options.prefs[key] = value;
369
- return this;
359
+ let options = this.firefoxOptions_()
360
+ options.prefs = options.prefs || {}
361
+ options.prefs[key] = value
362
+ return this
370
363
  }
371
364
 
372
365
  /**
@@ -380,10 +373,10 @@ class Options extends Capabilities {
380
373
  */
381
374
  setProfile(profile) {
382
375
  if (typeof profile !== 'string') {
383
- throw TypeError(`profile must be a string, but got ${typeof profile}`);
376
+ throw TypeError(`profile must be a string, but got ${typeof profile}`)
384
377
  }
385
- this.profile_().template_ = profile;
386
- return this;
378
+ this.profile_().template_ = profile
379
+ return this
387
380
  }
388
381
 
389
382
  /**
@@ -396,14 +389,13 @@ class Options extends Capabilities {
396
389
  */
397
390
  setBinary(binary) {
398
391
  if (binary instanceof Channel || typeof binary === 'string') {
399
- this.firefoxOptions_().binary = binary;
400
- return this;
392
+ this.firefoxOptions_().binary = binary
393
+ return this
401
394
  }
402
- throw TypeError('binary must be a string path or Channel object');
395
+ throw TypeError('binary must be a string path or Channel object')
403
396
  }
404
397
  }
405
398
 
406
-
407
399
  /**
408
400
  * Enum of available command contexts.
409
401
  *
@@ -415,14 +407,12 @@ class Options extends Capabilities {
415
407
  * @enum {string}
416
408
  */
417
409
  const Context = {
418
- CONTENT: "content",
419
- CHROME: "chrome",
420
- };
421
-
410
+ CONTENT: 'content',
411
+ CHROME: 'chrome',
412
+ }
422
413
 
423
414
  const GECKO_DRIVER_EXE =
424
- process.platform === 'win32' ? 'geckodriver.exe' : 'geckodriver';
425
-
415
+ process.platform === 'win32' ? 'geckodriver.exe' : 'geckodriver'
426
416
 
427
417
  /**
428
418
  * _Synchronously_ attempts to locate the geckodriver executable on the current
@@ -431,27 +421,28 @@ const GECKO_DRIVER_EXE =
431
421
  * @return {?string} the located executable, or `null`.
432
422
  */
433
423
  function locateSynchronously() {
434
- return io.findInPath(GECKO_DRIVER_EXE, true);
424
+ return io.findInPath(GECKO_DRIVER_EXE, true)
435
425
  }
436
426
 
437
-
438
427
  /**
439
428
  * @return {string} .
440
429
  * @throws {Error}
441
430
  */
442
431
  function findGeckoDriver() {
443
- let exe = locateSynchronously();
432
+ let exe = locateSynchronously()
444
433
  if (!exe) {
445
434
  throw Error(
446
- 'The ' + GECKO_DRIVER_EXE + ' executable could not be found on the current ' +
435
+ 'The ' +
436
+ GECKO_DRIVER_EXE +
437
+ ' executable could not be found on the current ' +
447
438
  'PATH. Please download the latest version from ' +
448
439
  'https://github.com/mozilla/geckodriver/releases/ ' +
449
- 'and ensure it can be found on your PATH.');
440
+ 'and ensure it can be found on your PATH.'
441
+ )
450
442
  }
451
- return exe;
443
+ return exe
452
444
  }
453
445
 
454
-
455
446
  /**
456
447
  * @param {string} file Path to the file to find, relative to the program files
457
448
  * root.
@@ -461,24 +452,24 @@ function findGeckoDriver() {
461
452
  function findInProgramFiles(file) {
462
453
  let files = [
463
454
  process.env['PROGRAMFILES'] || 'C:\\Program Files',
464
- process.env['PROGRAMFILES(X86)'] || 'C:\\Program Files (x86)'
465
- ].map(prefix => path.join(prefix, file));
466
- return io.exists(files[0]).then(function(exists) {
467
- return exists ? files[0] : io.exists(files[1]).then(function(exists) {
468
- return exists ? files[1] : null;
469
- });
470
- });
455
+ process.env['PROGRAMFILES(X86)'] || 'C:\\Program Files (x86)',
456
+ ].map((prefix) => path.join(prefix, file))
457
+ return io.exists(files[0]).then(function (exists) {
458
+ return exists
459
+ ? files[0]
460
+ : io.exists(files[1]).then(function (exists) {
461
+ return exists ? files[1] : null
462
+ })
463
+ })
471
464
  }
472
465
 
473
-
474
466
  /** @enum {string} */
475
467
  const ExtensionCommand = {
476
468
  GET_CONTEXT: 'getContext',
477
469
  SET_CONTEXT: 'setContext',
478
470
  INSTALL_ADDON: 'install addon',
479
471
  UNINSTALL_ADDON: 'uninstall addon',
480
- };
481
-
472
+ }
482
473
 
483
474
  /**
484
475
  * Creates a command executor with support for Marionette's custom commands.
@@ -486,40 +477,42 @@ const ExtensionCommand = {
486
477
  * @return {!command.Executor} The new command executor.
487
478
  */
488
479
  function createExecutor(serverUrl) {
489
- let client = serverUrl.then(url => new http.HttpClient(url));
490
- let executor = new http.Executor(client);
491
- configureExecutor(executor);
492
- return executor;
480
+ let client = serverUrl.then((url) => new http.HttpClient(url))
481
+ let executor = new http.Executor(client)
482
+ configureExecutor(executor)
483
+ return executor
493
484
  }
494
485
 
495
-
496
486
  /**
497
487
  * Configures the given executor with Firefox-specific commands.
498
488
  * @param {!http.Executor} executor the executor to configure.
499
489
  */
500
490
  function configureExecutor(executor) {
501
491
  executor.defineCommand(
502
- ExtensionCommand.GET_CONTEXT,
503
- 'GET',
504
- '/session/:sessionId/moz/context');
492
+ ExtensionCommand.GET_CONTEXT,
493
+ 'GET',
494
+ '/session/:sessionId/moz/context'
495
+ )
505
496
 
506
497
  executor.defineCommand(
507
- ExtensionCommand.SET_CONTEXT,
508
- 'POST',
509
- '/session/:sessionId/moz/context');
498
+ ExtensionCommand.SET_CONTEXT,
499
+ 'POST',
500
+ '/session/:sessionId/moz/context'
501
+ )
510
502
 
511
503
  executor.defineCommand(
512
- ExtensionCommand.INSTALL_ADDON,
513
- 'POST',
514
- '/session/:sessionId/moz/addon/install');
504
+ ExtensionCommand.INSTALL_ADDON,
505
+ 'POST',
506
+ '/session/:sessionId/moz/addon/install'
507
+ )
515
508
 
516
509
  executor.defineCommand(
517
- ExtensionCommand.UNINSTALL_ADDON,
518
- 'POST',
519
- '/session/:sessionId/moz/addon/uninstall');
510
+ ExtensionCommand.UNINSTALL_ADDON,
511
+ 'POST',
512
+ '/session/:sessionId/moz/addon/uninstall'
513
+ )
520
514
  }
521
515
 
522
-
523
516
  /**
524
517
  * Creates {@link selenium-webdriver/remote.DriverService} instances that manage
525
518
  * a [geckodriver](https://github.com/mozilla/geckodriver) server in a child
@@ -531,8 +524,8 @@ class ServiceBuilder extends remote.DriverService.Builder {
531
524
  * the builder will attempt to locate the geckodriver on the system PATH.
532
525
  */
533
526
  constructor(opt_exe) {
534
- super(opt_exe || findGeckoDriver());
535
- this.setLoopback(true); // Required.
527
+ super(opt_exe || findGeckoDriver())
528
+ this.setLoopback(true) // Required.
536
529
  }
537
530
 
538
531
  /**
@@ -543,11 +536,10 @@ class ServiceBuilder extends remote.DriverService.Builder {
543
536
  * @return {!ServiceBuilder} A self reference.
544
537
  */
545
538
  enableVerboseLogging(opt_trace) {
546
- return this.addArguments(opt_trace ? '-vv' : '-v');
539
+ return this.addArguments(opt_trace ? '-vv' : '-v')
547
540
  }
548
541
  }
549
542
 
550
-
551
543
  /**
552
544
  * A WebDriver client for Firefox.
553
545
  */
@@ -576,25 +568,24 @@ class Driver extends webdriver.WebDriver {
576
568
  */
577
569
  static createSession(opt_config, opt_executor) {
578
570
  let caps =
579
- opt_config instanceof Capabilities
580
- ? opt_config : new Options(opt_config);
571
+ opt_config instanceof Capabilities ? opt_config : new Options(opt_config)
581
572
 
582
- let executor;
583
- let onQuit;
573
+ let executor
574
+ let onQuit
584
575
 
585
576
  if (opt_executor instanceof http.Executor) {
586
- executor = opt_executor;
587
- configureExecutor(executor);
577
+ executor = opt_executor
578
+ configureExecutor(executor)
588
579
  } else if (opt_executor instanceof remote.DriverService) {
589
- executor = createExecutor(opt_executor.start());
590
- onQuit = () => opt_executor.kill();
580
+ executor = createExecutor(opt_executor.start())
581
+ onQuit = () => opt_executor.kill()
591
582
  } else {
592
- let service = new ServiceBuilder().build();
593
- executor = createExecutor(service.start());
594
- onQuit = () => service.kill();
583
+ let service = new ServiceBuilder().build()
584
+ executor = createExecutor(service.start())
585
+ onQuit = () => service.kill()
595
586
  }
596
587
 
597
- return /** @type {!Driver} */(super.createSession(executor, caps, onQuit));
588
+ return /** @type {!Driver} */ (super.createSession(executor, caps, onQuit))
598
589
  }
599
590
 
600
591
  /**
@@ -602,8 +593,7 @@ class Driver extends webdriver.WebDriver {
602
593
  * implementation.
603
594
  * @override
604
595
  */
605
- setFileDetector() {
606
- }
596
+ setFileDetector() { }
607
597
 
608
598
  /**
609
599
  * Get the context that is currently in effect.
@@ -611,7 +601,7 @@ class Driver extends webdriver.WebDriver {
611
601
  * @return {!Promise<Context>} Current context.
612
602
  */
613
603
  getContext() {
614
- return this.execute(new command.Command(ExtensionCommand.GET_CONTEXT));
604
+ return this.execute(new command.Command(ExtensionCommand.GET_CONTEXT))
615
605
  }
616
606
 
617
607
  /**
@@ -630,8 +620,11 @@ class Driver extends webdriver.WebDriver {
630
620
  */
631
621
  setContext(ctx) {
632
622
  return this.execute(
633
- new command.Command(ExtensionCommand.SET_CONTEXT)
634
- .setParameter("context", ctx));
623
+ new command.Command(ExtensionCommand.SET_CONTEXT).setParameter(
624
+ 'context',
625
+ ctx
626
+ )
627
+ )
635
628
  }
636
629
 
637
630
  /**
@@ -642,18 +635,19 @@ class Driver extends webdriver.WebDriver {
642
635
  *
643
636
  * @param {string} path Path on the local filesystem to the web extension to
644
637
  * install.
645
- * @param {boolean} temporary Flag indicating whether the extension should be
638
+ * @param {boolean} temporary Flag indicating whether the extension should be
646
639
  * installed temporarily - gets removed on restart
647
640
  * @return {!Promise<string>} A promise that will resolve to an ID for the
648
641
  * newly installed addon.
649
642
  * @see #uninstallAddon
650
643
  */
651
- async installAddon(path, temporary=false) {
652
- let buf = await io.read(path);
644
+ async installAddon(path, temporary = false) {
645
+ let buf = await io.read(path)
653
646
  return this.execute(
654
- new command.Command(ExtensionCommand.INSTALL_ADDON)
655
- .setParameter('addon', buf.toString('base64'))
656
- .setParameter('temporary', temporary));
647
+ new command.Command(ExtensionCommand.INSTALL_ADDON)
648
+ .setParameter('addon', buf.toString('base64'))
649
+ .setParameter('temporary', temporary)
650
+ )
657
651
  }
658
652
 
659
653
  /**
@@ -665,14 +659,16 @@ class Driver extends webdriver.WebDriver {
665
659
  * @see #installAddon
666
660
  */
667
661
  async uninstallAddon(id) {
668
- id = await Promise.resolve(id);
662
+ id = await Promise.resolve(id)
669
663
  return this.execute(
670
- new command.Command(ExtensionCommand.UNINSTALL_ADDON)
671
- .setParameter('id', id));
664
+ new command.Command(ExtensionCommand.UNINSTALL_ADDON).setParameter(
665
+ 'id',
666
+ id
667
+ )
668
+ )
672
669
  }
673
670
  }
674
671
 
675
-
676
672
  /**
677
673
  * Provides methods for locating the executable for a Firefox release channel
678
674
  * on Windows and MacOS. For other systems (i.e. Linux), Firefox will always
@@ -686,10 +682,10 @@ class Channel {
686
682
  * @param {string} win32 The path to check when running on Windows.
687
683
  */
688
684
  constructor(darwin, win32) {
689
- /** @private @const */ this.darwin_ = darwin;
690
- /** @private @const */ this.win32_ = win32;
685
+ /** @private @const */ this.darwin_ = darwin
686
+ /** @private @const */ this.win32_ = win32
691
687
  /** @private {Promise<string>} */
692
- this.found_ = null;
688
+ this.found_ = null
693
689
  }
694
690
 
695
691
  /**
@@ -703,43 +699,44 @@ class Channel {
703
699
  */
704
700
  locate() {
705
701
  if (this.found_) {
706
- return this.found_;
702
+ return this.found_
707
703
  }
708
704
 
709
- let found;
705
+ let found
710
706
  switch (process.platform) {
711
707
  case 'darwin':
712
- found = io.exists(this.darwin_)
713
- .then(exists => exists ? this.darwin_ : io.findInPath('firefox'));
714
- break;
708
+ found = io
709
+ .exists(this.darwin_)
710
+ .then((exists) => (exists ? this.darwin_ : io.findInPath('firefox')))
711
+ break
715
712
 
716
713
  case 'win32':
717
- found = findInProgramFiles(this.win32_)
718
- .then(found => found || io.findInPath('firefox.exe'));
719
- break;
714
+ found = findInProgramFiles(this.win32_).then(
715
+ (found) => found || io.findInPath('firefox.exe')
716
+ )
717
+ break
720
718
 
721
719
  default:
722
- found = Promise.resolve(io.findInPath('firefox'));
723
- break;
720
+ found = Promise.resolve(io.findInPath('firefox'))
721
+ break
724
722
  }
725
723
 
726
- this.found_ = found.then(found => {
724
+ this.found_ = found.then((found) => {
727
725
  if (found) {
728
726
  // TODO: verify version info.
729
- return found;
727
+ return found
730
728
  }
731
- throw Error('Could not locate Firefox on the current system');
732
- });
733
- return this.found_;
729
+ throw Error('Could not locate Firefox on the current system')
730
+ })
731
+ return this.found_
734
732
  }
735
733
 
736
734
  /** @return {!Promise<string>} */
737
735
  [Symbols.serialize]() {
738
- return this.locate();
736
+ return this.locate()
739
737
  }
740
738
  }
741
739
 
742
-
743
740
  /**
744
741
  * Firefox's developer channel.
745
742
  * @const
@@ -747,7 +744,8 @@ class Channel {
747
744
  */
748
745
  Channel.AURORA = new Channel(
749
746
  '/Applications/FirefoxDeveloperEdition.app/Contents/MacOS/firefox-bin',
750
- 'Firefox Developer Edition\\firefox.exe');
747
+ 'Firefox Developer Edition\\firefox.exe'
748
+ )
751
749
 
752
750
  /**
753
751
  * Firefox's beta channel. Note this is provided mainly for convenience as
@@ -758,7 +756,8 @@ Channel.AURORA = new Channel(
758
756
  */
759
757
  Channel.BETA = new Channel(
760
758
  '/Applications/Firefox.app/Contents/MacOS/firefox-bin',
761
- 'Mozilla Firefox\\firefox.exe');
759
+ 'Mozilla Firefox\\firefox.exe'
760
+ )
762
761
 
763
762
  /**
764
763
  * Firefox's release channel.
@@ -767,7 +766,8 @@ Channel.BETA = new Channel(
767
766
  */
768
767
  Channel.RELEASE = new Channel(
769
768
  '/Applications/Firefox.app/Contents/MacOS/firefox-bin',
770
- 'Mozilla Firefox\\firefox.exe');
769
+ 'Mozilla Firefox\\firefox.exe'
770
+ )
771
771
 
772
772
  /**
773
773
  * Firefox's nightly release channel.
@@ -776,15 +776,14 @@ Channel.RELEASE = new Channel(
776
776
  */
777
777
  Channel.NIGHTLY = new Channel(
778
778
  '/Applications/Firefox Nightly.app/Contents/MacOS/firefox-bin',
779
- 'Nightly\\firefox.exe');
780
-
779
+ 'Nightly\\firefox.exe'
780
+ )
781
781
 
782
782
  // PUBLIC API
783
783
 
784
-
785
- exports.Channel = Channel;
786
- exports.Context = Context;
787
- exports.Driver = Driver;
788
- exports.Options = Options;
789
- exports.ServiceBuilder = ServiceBuilder;
790
- exports.locateSynchronously = locateSynchronously;
784
+ exports.Channel = Channel
785
+ exports.Context = Context
786
+ exports.Driver = Driver
787
+ exports.Options = Options
788
+ exports.ServiceBuilder = ServiceBuilder
789
+ exports.locateSynchronously = locateSynchronously