codeceptjs 3.6.4 → 3.6.5-beta.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.
Files changed (88) hide show
  1. package/bin/codecept.js +84 -63
  2. package/lib/assert/empty.js +19 -19
  3. package/lib/assert/equal.js +32 -30
  4. package/lib/assert/error.js +14 -14
  5. package/lib/assert/include.js +42 -42
  6. package/lib/assert/throws.js +13 -11
  7. package/lib/assert/truth.js +17 -18
  8. package/lib/command/configMigrate.js +57 -52
  9. package/lib/command/definitions.js +88 -88
  10. package/lib/command/dryRun.js +65 -63
  11. package/lib/command/generate.js +191 -181
  12. package/lib/command/info.js +39 -37
  13. package/lib/command/init.js +289 -286
  14. package/lib/command/interactive.js +32 -32
  15. package/lib/command/list.js +26 -26
  16. package/lib/command/run-multiple.js +113 -93
  17. package/lib/command/run-rerun.js +22 -22
  18. package/lib/command/run-workers.js +63 -63
  19. package/lib/command/run.js +24 -26
  20. package/lib/command/utils.js +64 -63
  21. package/lib/data/context.js +60 -60
  22. package/lib/data/dataScenarioConfig.js +47 -47
  23. package/lib/data/dataTableArgument.js +29 -29
  24. package/lib/data/table.js +26 -20
  25. package/lib/helper/AI.js +67 -65
  26. package/lib/helper/ApiDataFactory.js +72 -69
  27. package/lib/helper/Appium.js +409 -379
  28. package/lib/helper/ExpectHelper.js +214 -248
  29. package/lib/helper/FileSystem.js +77 -78
  30. package/lib/helper/GraphQL.js +44 -43
  31. package/lib/helper/GraphQLDataFactory.js +49 -50
  32. package/lib/helper/JSONResponse.js +64 -62
  33. package/lib/helper/Mochawesome.js +28 -28
  34. package/lib/helper/MockServer.js +12 -12
  35. package/lib/helper/Nightmare.js +664 -572
  36. package/lib/helper/Playwright.js +1320 -1211
  37. package/lib/helper/Protractor.js +663 -629
  38. package/lib/helper/Puppeteer.js +1232 -1124
  39. package/lib/helper/REST.js +87 -72
  40. package/lib/helper/TestCafe.js +490 -491
  41. package/lib/helper/WebDriver.js +1294 -1156
  42. package/lib/interfaces/bdd.js +38 -51
  43. package/lib/interfaces/featureConfig.js +19 -19
  44. package/lib/interfaces/gherkin.js +122 -111
  45. package/lib/interfaces/scenarioConfig.js +29 -29
  46. package/lib/listener/artifacts.js +9 -9
  47. package/lib/listener/config.js +24 -23
  48. package/lib/listener/exit.js +12 -12
  49. package/lib/listener/helpers.js +42 -42
  50. package/lib/listener/mocha.js +11 -11
  51. package/lib/listener/retry.js +32 -30
  52. package/lib/listener/steps.js +50 -51
  53. package/lib/listener/timeout.js +53 -53
  54. package/lib/plugin/allure.js +14 -14
  55. package/lib/plugin/autoDelay.js +29 -36
  56. package/lib/plugin/autoLogin.js +70 -66
  57. package/lib/plugin/commentStep.js +18 -18
  58. package/lib/plugin/coverage.js +92 -77
  59. package/lib/plugin/customLocator.js +20 -19
  60. package/lib/plugin/debugErrors.js +24 -24
  61. package/lib/plugin/eachElement.js +37 -37
  62. package/lib/plugin/fakerTransform.js +6 -6
  63. package/lib/plugin/heal.js +66 -63
  64. package/lib/plugin/pauseOnFail.js +10 -10
  65. package/lib/plugin/retryFailedStep.js +31 -38
  66. package/lib/plugin/retryTo.js +28 -28
  67. package/lib/plugin/screenshotOnFail.js +107 -86
  68. package/lib/plugin/selenoid.js +131 -117
  69. package/lib/plugin/standardActingHelpers.js +2 -8
  70. package/lib/plugin/stepByStepReport.js +102 -92
  71. package/lib/plugin/stepTimeout.js +23 -22
  72. package/lib/plugin/subtitles.js +34 -34
  73. package/lib/plugin/tryTo.js +39 -29
  74. package/lib/plugin/wdio.js +77 -72
  75. package/lib/template/heal.js +11 -14
  76. package/package.json +4 -2
  77. package/translations/de-DE.js +1 -1
  78. package/translations/fr-FR.js +1 -1
  79. package/translations/index.js +9 -9
  80. package/translations/it-IT.js +1 -1
  81. package/translations/ja-JP.js +1 -1
  82. package/translations/pl-PL.js +1 -1
  83. package/translations/pt-BR.js +1 -1
  84. package/translations/ru-RU.js +1 -1
  85. package/translations/zh-CN.js +1 -1
  86. package/translations/zh-TW.js +1 -1
  87. package/typings/promiseBasedTypes.d.ts +238 -0
  88. package/typings/types.d.ts +32 -0
@@ -1,15 +1,15 @@
1
- let webdriverio;
2
-
3
- const assert = require('assert');
4
- const path = require('path');
5
-
6
- const Helper = require('@codeceptjs/helper');
7
- const promiseRetry = require('promise-retry');
8
- const stringIncludes = require('../assert/include').includes;
9
- const { urlEquals, equals } = require('../assert/equal');
10
- const { debug } = require('../output');
11
- const { empty } = require('../assert/empty');
12
- const { truth } = require('../assert/truth');
1
+ let webdriverio
2
+
3
+ const assert = require('assert')
4
+ const path = require('path')
5
+
6
+ const Helper = require('@codeceptjs/helper')
7
+ const promiseRetry = require('promise-retry')
8
+ const stringIncludes = require('../assert/include').includes
9
+ const { urlEquals, equals } = require('../assert/equal')
10
+ const { debug } = require('../output')
11
+ const { empty } = require('../assert/empty')
12
+ const { truth } = require('../assert/truth')
13
13
  const {
14
14
  xpathLocator,
15
15
  fileExists,
@@ -19,26 +19,30 @@ const {
19
19
  screenshotOutputFolder,
20
20
  getNormalizedKeyAttributeValue,
21
21
  modifierKeys,
22
- } = require('../utils');
22
+ } = require('../utils')
23
+ const { isColorProperty, convertColorToRGBA } = require('../colorUtils')
24
+ const ElementNotFound = require('./errors/ElementNotFound')
25
+ const ConnectionRefused = require('./errors/ConnectionRefused')
26
+ const Locator = require('../locator')
27
+ const { highlightElement } = require('./scripts/highlightElement')
28
+ const { focusElement } = require('./scripts/focusElement')
29
+ const { blurElement } = require('./scripts/blurElement')
23
30
  const {
24
- isColorProperty,
25
- convertColorToRGBA,
26
- } = require('../colorUtils');
27
- const ElementNotFound = require('./errors/ElementNotFound');
28
- const ConnectionRefused = require('./errors/ConnectionRefused');
29
- const Locator = require('../locator');
30
- const { highlightElement } = require('./scripts/highlightElement');
31
- const { focusElement } = require('./scripts/focusElement');
32
- const { blurElement } = require('./scripts/blurElement');
31
+ dontSeeElementError,
32
+ seeElementError,
33
+ seeElementInDOMError,
34
+ dontSeeElementInDOMError,
35
+ } = require('./errors/ElementAssertion')
33
36
  const {
34
- dontSeeElementError, seeElementError, seeElementInDOMError, dontSeeElementInDOMError,
35
- } = require('./errors/ElementAssertion');
36
- const {
37
- dontSeeTraffic, seeTraffic, grabRecordedNetworkTraffics, stopRecordingTraffic, flushNetworkTraffics,
38
- } = require('./network/actions');
37
+ dontSeeTraffic,
38
+ seeTraffic,
39
+ grabRecordedNetworkTraffics,
40
+ stopRecordingTraffic,
41
+ flushNetworkTraffics,
42
+ } = require('./network/actions')
39
43
 
40
- const SHADOW = 'shadow';
41
- const webRoot = 'body';
44
+ const SHADOW = 'shadow'
45
+ const webRoot = 'body'
42
46
 
43
47
  /**
44
48
  * ## Configuration
@@ -70,7 +74,7 @@ const webRoot = 'body';
70
74
  * @prop {string} [logLevel=silent] - level of logging verbosity. Default: silent. Options: trace | debug | info | warn | error | silent. More info: https://webdriver.io/docs/configuration/#loglevel
71
75
  * @prop {boolean} [devtoolsProtocol=false] - enable devtools protocol. Default: false. More info: https://webdriver.io/docs/automationProtocols/#devtools-protocol.
72
76
  */
73
- const config = {};
77
+ const config = {}
74
78
 
75
79
  /**
76
80
  * WebDriver helper which wraps [webdriverio](http://webdriver.io/) library to
@@ -441,34 +445,34 @@ const config = {};
441
445
  */
442
446
  class WebDriver extends Helper {
443
447
  constructor(config) {
444
- super(config);
445
- webdriverio = require('webdriverio');
448
+ super(config)
449
+ webdriverio = require('webdriverio')
446
450
 
447
451
  // set defaults
448
- this.root = webRoot;
449
- this.isWeb = true;
450
- this.isRunning = false;
451
- this.sessionWindows = {};
452
- this.activeSessionName = '';
453
- this.customLocatorStrategies = config.customLocatorStrategies;
452
+ this.root = webRoot
453
+ this.isWeb = true
454
+ this.isRunning = false
455
+ this.sessionWindows = {}
456
+ this.activeSessionName = ''
457
+ this.customLocatorStrategies = config.customLocatorStrategies
454
458
 
455
459
  // for network stuff
456
- this.requests = [];
457
- this.recording = false;
458
- this.recordedAtLeastOnce = false;
460
+ this.requests = []
461
+ this.recording = false
462
+ this.recordedAtLeastOnce = false
459
463
 
460
- this._setConfig(config);
464
+ this._setConfig(config)
461
465
 
462
466
  Locator.addFilter((locator, result) => {
463
467
  if (typeof locator === 'string' && locator.indexOf('~') === 0) {
464
468
  // accessibility locator
465
469
  if (this.isWeb) {
466
- result.value = `[aria-label="${locator.slice(1)}"]`;
467
- result.type = 'css';
468
- result.output = `aria-label=${locator.slice(1)}`;
470
+ result.value = `[aria-label="${locator.slice(1)}"]`
471
+ result.type = 'css'
472
+ result.output = `aria-label=${locator.slice(1)}`
469
473
  }
470
474
  }
471
- });
475
+ })
472
476
  }
473
477
 
474
478
  _validateConfig(config) {
@@ -488,41 +492,41 @@ class WebDriver extends Helper {
488
492
  keepBrowserState: false,
489
493
  deprecationWarnings: false,
490
494
  highlightElement: false,
491
- };
495
+ }
492
496
 
493
497
  // override defaults with config
494
- config = Object.assign(defaults, config);
498
+ config = Object.assign(defaults, config)
495
499
 
496
500
  if (config.host) {
497
501
  // webdriverio spec
498
- config.hostname = config.host;
499
- config.path = config.path ? config.path : '/wd/hub';
502
+ config.hostname = config.host
503
+ config.path = config.path ? config.path : '/wd/hub'
500
504
  }
501
505
 
502
- config.baseUrl = config.url || config.baseUrl;
506
+ config.baseUrl = config.url || config.baseUrl
503
507
  if (config.desiredCapabilities && Object.keys(config.desiredCapabilities).length) {
504
- config.capabilities = config.desiredCapabilities;
508
+ config.capabilities = config.desiredCapabilities
505
509
  }
506
- config.capabilities.browserName = config.browser || config.capabilities.browserName;
507
- config.capabilities.browserVersion = config.browserVersion || config.capabilities.browserVersion;
510
+ config.capabilities.browserName = config.browser || config.capabilities.browserName
511
+ config.capabilities.browserVersion = config.browserVersion || config.capabilities.browserVersion
508
512
  if (config.capabilities.chromeOptions) {
509
- config.capabilities['goog:chromeOptions'] = config.capabilities.chromeOptions;
510
- delete config.capabilities.chromeOptions;
513
+ config.capabilities['goog:chromeOptions'] = config.capabilities.chromeOptions
514
+ delete config.capabilities.chromeOptions
511
515
  }
512
516
  if (config.capabilities.firefoxOptions) {
513
- config.capabilities['moz:firefoxOptions'] = config.capabilities.firefoxOptions;
514
- delete config.capabilities.firefoxOptions;
517
+ config.capabilities['moz:firefoxOptions'] = config.capabilities.firefoxOptions
518
+ delete config.capabilities.firefoxOptions
515
519
  }
516
520
  if (config.capabilities.ieOptions) {
517
- config.capabilities['se:ieOptions'] = config.capabilities.ieOptions;
518
- delete config.capabilities.ieOptions;
521
+ config.capabilities['se:ieOptions'] = config.capabilities.ieOptions
522
+ delete config.capabilities.ieOptions
519
523
  }
520
524
  if (config.capabilities.selenoidOptions) {
521
- config.capabilities['selenoid:options'] = config.capabilities.selenoidOptions;
522
- delete config.capabilities.selenoidOptions;
525
+ config.capabilities['selenoid:options'] = config.capabilities.selenoidOptions
526
+ delete config.capabilities.selenoidOptions
523
527
  }
524
528
 
525
- config.waitForTimeoutInSeconds = config.waitForTimeout / 1000; // convert to seconds
529
+ config.waitForTimeoutInSeconds = config.waitForTimeout / 1000 // convert to seconds
526
530
 
527
531
  if (!config.capabilities.platformName && (!config.url || !config.browser)) {
528
532
  throw new Error(`
@@ -536,197 +540,201 @@ class WebDriver extends Helper {
536
540
  }
537
541
  }
538
542
  }
539
- `);
543
+ `)
540
544
  }
541
545
 
542
- return config;
546
+ return config
543
547
  }
544
548
 
545
549
  static _checkRequirements() {
546
550
  try {
547
- require('webdriverio');
551
+ require('webdriverio')
548
552
  } catch (e) {
549
- return ['webdriverio@^6.12.1'];
553
+ return ['webdriverio@^6.12.1']
550
554
  }
551
555
  }
552
556
 
553
557
  static _config() {
554
- return [{
555
- name: 'url',
556
- message: 'Base url of site to be tested',
557
- default: 'http://localhost',
558
- }, {
559
- name: 'browser',
560
- message: 'Browser in which testing will be performed',
561
- default: 'chrome',
562
- }];
558
+ return [
559
+ {
560
+ name: 'url',
561
+ message: 'Base url of site to be tested',
562
+ default: 'http://localhost',
563
+ },
564
+ {
565
+ name: 'browser',
566
+ message: 'Browser in which testing will be performed',
567
+ default: 'chrome',
568
+ },
569
+ ]
563
570
  }
564
571
 
565
572
  _beforeSuite() {
566
573
  if (!this.options.restart && !this.options.manualStart && !this.isRunning) {
567
- this.debugSection('Session', 'Starting singleton browser session');
568
- return this._startBrowser();
574
+ this.debugSection('Session', 'Starting singleton browser session')
575
+ return this._startBrowser()
569
576
  }
570
577
  }
571
578
 
572
579
  _lookupCustomLocator(customStrategy) {
573
- if (typeof (this.customLocatorStrategies) !== 'object') {
574
- return null;
580
+ if (typeof this.customLocatorStrategies !== 'object') {
581
+ return null
575
582
  }
576
- const strategy = this.customLocatorStrategies[customStrategy];
577
- return typeof (strategy) === 'function' ? strategy : null;
583
+ const strategy = this.customLocatorStrategies[customStrategy]
584
+ return typeof strategy === 'function' ? strategy : null
578
585
  }
579
586
 
580
587
  _isCustomLocator(locator) {
581
- const locatorObj = new Locator(locator);
588
+ const locatorObj = new Locator(locator)
582
589
  if (locatorObj.isCustom()) {
583
- const customLocator = this._lookupCustomLocator(locatorObj.type);
590
+ const customLocator = this._lookupCustomLocator(locatorObj.type)
584
591
  if (customLocator) {
585
- return true;
592
+ return true
586
593
  }
587
- throw new Error('Please define "customLocatorStrategies" as an Object and the Locator Strategy as a "function".');
594
+ throw new Error('Please define "customLocatorStrategies" as an Object and the Locator Strategy as a "function".')
588
595
  }
589
- return false;
596
+ return false
590
597
  }
591
598
 
592
599
  async _res(locator) {
593
- const res = (this._isShadowLocator(locator) || this._isCustomLocator(locator))
594
- ? await this._locate(locator)
595
- : await this.$$(withStrictLocator(locator));
596
- return res;
600
+ const res =
601
+ this._isShadowLocator(locator) || this._isCustomLocator(locator)
602
+ ? await this._locate(locator)
603
+ : await this.$$(withStrictLocator(locator))
604
+ return res
597
605
  }
598
606
 
599
607
  async _startBrowser() {
600
608
  try {
601
609
  if (this.options.multiremote) {
602
- this.browser = await webdriverio.multiremote(this.options.multiremote);
610
+ this.browser = await webdriverio.multiremote(this.options.multiremote)
603
611
  } else {
604
612
  // remove non w3c capabilities
605
- delete this.options.capabilities.protocol;
606
- delete this.options.capabilities.hostname;
607
- delete this.options.capabilities.port;
608
- delete this.options.capabilities.path;
613
+ delete this.options.capabilities.protocol
614
+ delete this.options.capabilities.hostname
615
+ delete this.options.capabilities.port
616
+ delete this.options.capabilities.path
609
617
  if (this.options.devtoolsProtocol) {
610
- if (!['chrome', 'chromium'].includes(this.options.browser.toLowerCase())) throw Error('The devtools protocol is only working with Chrome or Chromium');
611
- this.options.automationProtocol = 'devtools';
618
+ if (!['chrome', 'chromium'].includes(this.options.browser.toLowerCase()))
619
+ throw Error('The devtools protocol is only working with Chrome or Chromium')
620
+ this.options.automationProtocol = 'devtools'
612
621
  }
613
- this.browser = await webdriverio.remote(this.options);
622
+ this.browser = await webdriverio.remote(this.options)
614
623
  }
615
624
  } catch (err) {
616
625
  if (err.toString().indexOf('ECONNREFUSED')) {
617
- throw new ConnectionRefused(err);
626
+ throw new ConnectionRefused(err)
618
627
  }
619
- throw err;
628
+ throw err
620
629
  }
621
630
 
622
- this.isRunning = true;
631
+ this.isRunning = true
623
632
  if (this.options.timeouts && this.isWeb) {
624
- await this.defineTimeout(this.options.timeouts);
633
+ await this.defineTimeout(this.options.timeouts)
625
634
  }
626
635
 
627
- await this._resizeWindowIfNeeded(this.browser, this.options.windowSize);
636
+ await this._resizeWindowIfNeeded(this.browser, this.options.windowSize)
628
637
 
629
- this.$$ = this.browser.$$.bind(this.browser);
638
+ this.$$ = this.browser.$$.bind(this.browser)
630
639
 
631
640
  if (this._isCustomLocatorStrategyDefined()) {
632
641
  Object.keys(this.customLocatorStrategies).forEach(async (customLocator) => {
633
- this.debugSection('Weddriver', `adding custom locator strategy: ${customLocator}`);
634
- const locatorFunction = this._lookupCustomLocator(customLocator);
635
- this.browser.addLocatorStrategy(customLocator, locatorFunction);
636
- });
642
+ this.debugSection('Weddriver', `adding custom locator strategy: ${customLocator}`)
643
+ const locatorFunction = this._lookupCustomLocator(customLocator)
644
+ this.browser.addLocatorStrategy(customLocator, locatorFunction)
645
+ })
637
646
  }
638
647
 
639
648
  if (this.browser.capabilities && this.browser.capabilities.platformName) {
640
- this.browser.capabilities.platformName = this.browser.capabilities.platformName.toLowerCase();
649
+ this.browser.capabilities.platformName = this.browser.capabilities.platformName.toLowerCase()
641
650
  }
642
651
 
643
652
  if (this.options.automationProtocol) {
644
- this.puppeteerBrowser = await this.browser.getPuppeteer();
645
- this.page = (await this.puppeteerBrowser.pages())[0];
653
+ this.puppeteerBrowser = await this.browser.getPuppeteer()
654
+ this.page = (await this.puppeteerBrowser.pages())[0]
646
655
  }
647
656
 
648
- return this.browser;
657
+ return this.browser
649
658
  }
650
659
 
651
660
  _isCustomLocatorStrategyDefined() {
652
- return this.customLocatorStrategies && Object.keys(this.customLocatorStrategies).length;
661
+ return this.customLocatorStrategies && Object.keys(this.customLocatorStrategies).length
653
662
  }
654
663
 
655
664
  async _stopBrowser() {
656
- if (this.browser && this.isRunning) await this.browser.deleteSession();
665
+ if (this.browser && this.isRunning) await this.browser.deleteSession()
657
666
  }
658
667
 
659
668
  async _before() {
660
- this.context = this.root;
661
- if (this.options.restart && !this.options.manualStart) return this._startBrowser();
662
- if (!this.isRunning && !this.options.manualStart) return this._startBrowser();
663
- if (this.browser) this.$$ = this.browser.$$.bind(this.browser);
664
- return this.browser;
669
+ this.context = this.root
670
+ if (this.options.restart && !this.options.manualStart) return this._startBrowser()
671
+ if (!this.isRunning && !this.options.manualStart) return this._startBrowser()
672
+ if (this.browser) this.$$ = this.browser.$$.bind(this.browser)
673
+ return this.browser
665
674
  }
666
675
 
667
676
  async _after() {
668
- if (!this.isRunning) return;
677
+ if (!this.isRunning) return
669
678
  if (this.options.restart) {
670
- this.isRunning = false;
671
- return this.browser.deleteSession();
679
+ this.isRunning = false
680
+ return this.browser.deleteSession()
672
681
  }
673
- if (this.browser.isInsideFrame) await this.browser.switchToFrame(null);
682
+ if (this.browser.isInsideFrame) await this.browser.switchToFrame(null)
674
683
 
675
- if (this.options.keepBrowserState) return;
684
+ if (this.options.keepBrowserState) return
676
685
 
677
686
  if (!this.options.keepCookies && this.options.capabilities.browserName) {
678
- this.debugSection('Session', 'cleaning cookies and localStorage');
679
- await this.browser.deleteCookies();
687
+ this.debugSection('Session', 'cleaning cookies and localStorage')
688
+ await this.browser.deleteCookies()
680
689
  }
681
690
  await this.browser.execute('localStorage.clear();').catch((err) => {
682
- if (!(err.message.indexOf("Storage is disabled inside 'data:' URLs.") > -1)) throw err;
683
- });
684
- await this.closeOtherTabs();
685
- return this.browser;
691
+ if (!(err.message.indexOf("Storage is disabled inside 'data:' URLs.") > -1)) throw err
692
+ })
693
+ await this.closeOtherTabs()
694
+ return this.browser
686
695
  }
687
696
 
688
- _afterSuite() {
689
- }
697
+ _afterSuite() {}
690
698
 
691
699
  _finishTest() {
692
- if (!this.options.restart && this.isRunning) return this._stopBrowser();
700
+ if (!this.options.restart && this.isRunning) return this._stopBrowser()
693
701
  }
694
702
 
695
703
  _session() {
696
- const defaultSession = this.browser;
704
+ const defaultSession = this.browser
697
705
  return {
698
706
  start: async (sessionName, opts) => {
699
707
  // opts.disableScreenshots = true; // screenshots cant be saved as session will be already closed
700
- opts = this._validateConfig(Object.assign(this.options, opts));
701
- this.debugSection('New Browser', JSON.stringify(opts));
702
- const browser = await webdriverio.remote(opts);
703
- this.activeSessionName = sessionName;
708
+ opts = this._validateConfig(Object.assign(this.options, opts))
709
+ this.debugSection('New Browser', JSON.stringify(opts))
710
+ const browser = await webdriverio.remote(opts)
711
+ this.activeSessionName = sessionName
704
712
  if (opts.timeouts && this.isWeb) {
705
- await this._defineBrowserTimeout(browser, opts.timeouts);
713
+ await this._defineBrowserTimeout(browser, opts.timeouts)
706
714
  }
707
715
 
708
- await this._resizeWindowIfNeeded(browser, opts.windowSize);
716
+ await this._resizeWindowIfNeeded(browser, opts.windowSize)
709
717
 
710
- return browser;
718
+ return browser
711
719
  },
712
720
  stop: async (browser) => {
713
- if (!browser) return;
714
- return browser.deleteSession();
721
+ if (!browser) return
722
+ return browser.deleteSession()
715
723
  },
716
724
  loadVars: async (browser) => {
717
- if (this.context !== this.root) throw new Error('Can\'t start session inside within block');
718
- this.browser = browser;
719
- this.$$ = this.browser.$$.bind(this.browser);
720
- this.sessionWindows[this.activeSessionName] = browser;
725
+ if (this.context !== this.root) throw new Error("Can't start session inside within block")
726
+ this.browser = browser
727
+ this.$$ = this.browser.$$.bind(this.browser)
728
+ this.sessionWindows[this.activeSessionName] = browser
721
729
  },
722
730
  restoreVars: async (session) => {
723
731
  if (!session) {
724
- this.activeSessionName = '';
732
+ this.activeSessionName = ''
725
733
  }
726
- this.browser = defaultSession;
727
- this.$$ = this.browser.$$.bind(this.browser);
734
+ this.browser = defaultSession
735
+ this.$$ = this.browser.$$.bind(this.browser)
728
736
  },
729
- };
737
+ }
730
738
  }
731
739
 
732
740
  /**
@@ -748,41 +756,41 @@ class WebDriver extends Helper {
748
756
  * @param {function} fn async functuion that executed with WebDriver helper as argument
749
757
  */
750
758
  useWebDriverTo(description, fn) {
751
- return this._useTo(...arguments);
759
+ return this._useTo(...arguments)
752
760
  }
753
761
 
754
762
  async _failed() {
755
- if (this.context !== this.root) await this._withinEnd();
763
+ if (this.context !== this.root) await this._withinEnd()
756
764
  }
757
765
 
758
766
  async _withinBegin(locator) {
759
- const frame = isFrameLocator(locator);
767
+ const frame = isFrameLocator(locator)
760
768
  if (frame) {
761
- this.browser.isInsideFrame = true;
769
+ this.browser.isInsideFrame = true
762
770
  if (Array.isArray(frame)) {
763
771
  // this.switchTo(null);
764
- await forEachAsync(frame, async f => this.switchTo(f));
765
- return;
772
+ await forEachAsync(frame, async (f) => this.switchTo(f))
773
+ return
766
774
  }
767
- await this.switchTo(frame);
768
- return;
775
+ await this.switchTo(frame)
776
+ return
769
777
  }
770
- this.context = locator;
778
+ this.context = locator
771
779
 
772
- let res = await this.browser.$$(withStrictLocator(locator));
773
- assertElementExists(res, locator);
774
- res = usingFirstElement(res);
775
- this.context = res.selector;
776
- this.$$ = res.$$.bind(res);
780
+ let res = await this.browser.$$(withStrictLocator(locator))
781
+ assertElementExists(res, locator)
782
+ res = usingFirstElement(res)
783
+ this.context = res.selector
784
+ this.$$ = res.$$.bind(res)
777
785
  }
778
786
 
779
787
  async _withinEnd() {
780
788
  if (this.browser.isInsideFrame) {
781
- this.browser.isInsideFrame = false;
782
- return this.switchTo(null);
789
+ this.browser.isInsideFrame = false
790
+ return this.switchTo(null)
783
791
  }
784
- this.context = this.root;
785
- this.$$ = this.browser.$$.bind(this.browser);
792
+ this.context = this.root
793
+ this.$$ = this.browser.$$.bind(this.browser)
786
794
  }
787
795
 
788
796
  /**
@@ -791,7 +799,7 @@ class WebDriver extends Helper {
791
799
  * @param {object} locator
792
800
  */
793
801
  _isShadowLocator(locator) {
794
- return locator.type === SHADOW || locator[SHADOW];
802
+ return locator.type === SHADOW || locator[SHADOW]
795
803
  }
796
804
 
797
805
  /**
@@ -800,35 +808,37 @@ class WebDriver extends Helper {
800
808
  * @param {object} locator
801
809
  */
802
810
  async _locateShadow(locator) {
803
- const shadow = locator.value ? locator.value : locator[SHADOW];
804
- const shadowSequence = [];
805
- let elements;
811
+ const shadow = locator.value ? locator.value : locator[SHADOW]
812
+ const shadowSequence = []
813
+ let elements
806
814
 
807
815
  if (!Array.isArray(shadow)) {
808
- throw new Error(`Shadow '${shadow}' should be defined as an Array of elements.`);
816
+ throw new Error(`Shadow '${shadow}' should be defined as an Array of elements.`)
809
817
  }
810
818
 
811
819
  // traverse through the Shadow locators in sequence
812
820
  for (let index = 0; index < shadow.length; index++) {
813
- const shadowElement = shadow[index];
814
- shadowSequence.push(shadowElement);
821
+ const shadowElement = shadow[index]
822
+ shadowSequence.push(shadowElement)
815
823
 
816
824
  if (!elements) {
817
- elements = await (this.browser.$$(shadowElement));
825
+ elements = await this.browser.$$(shadowElement)
818
826
  } else if (Array.isArray(elements)) {
819
- elements = await elements[0].shadow$$(shadowElement);
827
+ elements = await elements[0].shadow$$(shadowElement)
820
828
  } else if (elements) {
821
- elements = await elements.shadow$$(shadowElement);
829
+ elements = await elements.shadow$$(shadowElement)
822
830
  }
823
831
 
824
832
  if (!elements || !elements[0]) {
825
- throw new Error(`Shadow Element '${shadowElement}' is not found. It is possible the element is incorrect or elements sequence is incorrect. Please verify the sequence '${shadowSequence.join('>')}' is correctly chained.`);
833
+ throw new Error(
834
+ `Shadow Element '${shadowElement}' is not found. It is possible the element is incorrect or elements sequence is incorrect. Please verify the sequence '${shadowSequence.join('>')}' is correctly chained.`,
835
+ )
826
836
  }
827
837
  }
828
838
 
829
- this.debugSection('Elements', `Found ${elements.length} '${SHADOW}' elements`);
839
+ this.debugSection('Elements', `Found ${elements.length} '${SHADOW}' elements`)
830
840
 
831
- return elements;
841
+ return elements
832
842
  }
833
843
 
834
844
  /**
@@ -837,8 +847,11 @@ class WebDriver extends Helper {
837
847
  * @param {object} locator
838
848
  */
839
849
  async _smartWait(locator) {
840
- this.debugSection(`SmartWait (${this.options.smartWait}ms)`, `Locating ${JSON.stringify(locator)} in ${this.options.smartWait}`);
841
- await this.defineTimeout({ implicit: this.options.smartWait });
850
+ this.debugSection(
851
+ `SmartWait (${this.options.smartWait}ms)`,
852
+ `Locating ${JSON.stringify(locator)} in ${this.options.smartWait}`,
853
+ )
854
+ await this.defineTimeout({ implicit: this.options.smartWait })
842
855
  }
843
856
 
844
857
  /**
@@ -853,53 +866,53 @@ class WebDriver extends Helper {
853
866
  * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
854
867
  */
855
868
  async _locate(locator, smartWait = false) {
856
- if (require('../store').debugMode) smartWait = false;
869
+ if (require('../store').debugMode) smartWait = false
857
870
 
858
871
  // special locator type for Shadow DOM
859
872
  if (this._isShadowLocator(locator)) {
860
873
  if (!this.options.smartWait || !smartWait) {
861
- const els = await this._locateShadow(locator);
862
- return els;
874
+ const els = await this._locateShadow(locator)
875
+ return els
863
876
  }
864
877
 
865
- const els = await this._locateShadow(locator);
866
- return els;
878
+ const els = await this._locateShadow(locator)
879
+ return els
867
880
  }
868
881
 
869
882
  // special locator type for React
870
883
  if (locator.react) {
871
- const els = await this.browser.react$$(locator.react, locator.props || undefined, locator.state || undefined);
872
- this.debugSection('Elements', `Found ${els.length} react components`);
873
- return els;
884
+ const els = await this.browser.react$$(locator.react, locator.props || undefined, locator.state || undefined)
885
+ this.debugSection('Elements', `Found ${els.length} react components`)
886
+ return els
874
887
  }
875
888
 
876
889
  if (!this.options.smartWait || !smartWait) {
877
890
  if (this._isCustomLocator(locator)) {
878
- const locatorObj = new Locator(locator);
879
- return this.browser.custom$$(locatorObj.type, locatorObj.value);
891
+ const locatorObj = new Locator(locator)
892
+ return this.browser.custom$$(locatorObj.type, locatorObj.value)
880
893
  }
881
894
 
882
- const els = await this.$$(withStrictLocator(locator));
883
- return els;
895
+ const els = await this.$$(withStrictLocator(locator))
896
+ return els
884
897
  }
885
898
 
886
- await this._smartWait(locator);
899
+ await this._smartWait(locator)
887
900
 
888
901
  if (this._isCustomLocator(locator)) {
889
- const locatorObj = new Locator(locator);
890
- return this.browser.custom$$(locatorObj.type, locatorObj.value);
902
+ const locatorObj = new Locator(locator)
903
+ return this.browser.custom$$(locatorObj.type, locatorObj.value)
891
904
  }
892
905
 
893
- const els = await this.$$(withStrictLocator(locator));
894
- await this.defineTimeout({ implicit: 0 });
895
- return els;
906
+ const els = await this.$$(withStrictLocator(locator))
907
+ await this.defineTimeout({ implicit: 0 })
908
+ return els
896
909
  }
897
910
 
898
911
  _grabCustomLocator(locator) {
899
912
  if (typeof locator === 'string') {
900
- locator = new Locator(locator);
913
+ locator = new Locator(locator)
901
914
  }
902
- return locator.value ? locator.value : locator.custom;
915
+ return locator.value ? locator.value : locator.custom
903
916
  }
904
917
 
905
918
  /**
@@ -912,7 +925,7 @@ class WebDriver extends Helper {
912
925
  * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
913
926
  */
914
927
  async _locateCheckable(locator) {
915
- return findCheckable.call(this, locator, this.$$.bind(this)).then(res => res);
928
+ return findCheckable.call(this, locator, this.$$.bind(this)).then((res) => res)
916
929
  }
917
930
 
918
931
  /**
@@ -926,8 +939,8 @@ class WebDriver extends Helper {
926
939
  * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
927
940
  */
928
941
  async _locateClickable(locator, context) {
929
- const locateFn = prepareLocateFn.call(this, context);
930
- return findClickable.call(this, locator, locateFn);
942
+ const locateFn = prepareLocateFn.call(this, context)
943
+ return findClickable.call(this, locator, locateFn)
931
944
  }
932
945
 
933
946
  /**
@@ -940,7 +953,7 @@ class WebDriver extends Helper {
940
953
  * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
941
954
  */
942
955
  async _locateFields(locator) {
943
- return findFields.call(this, locator).then(res => res);
956
+ return findFields.call(this, locator).then((res) => res)
944
957
  }
945
958
 
946
959
  /**
@@ -948,7 +961,7 @@ class WebDriver extends Helper {
948
961
  *
949
962
  */
950
963
  async grabWebElements(locator) {
951
- return this._locate(locator);
964
+ return this._locate(locator)
952
965
  }
953
966
 
954
967
  /**
@@ -964,11 +977,11 @@ class WebDriver extends Helper {
964
977
  * @param {*} timeouts WebDriver timeouts object.
965
978
  */
966
979
  defineTimeout(timeouts) {
967
- return this._defineBrowserTimeout(this.browser, timeouts);
980
+ return this._defineBrowserTimeout(this.browser, timeouts)
968
981
  }
969
982
 
970
983
  _defineBrowserTimeout(browser, timeouts) {
971
- return browser.setTimeout(timeouts);
984
+ return browser.setTimeout(timeouts)
972
985
  }
973
986
 
974
987
  /**
@@ -976,15 +989,15 @@ class WebDriver extends Helper {
976
989
  *
977
990
  */
978
991
  amOnPage(url) {
979
- let split_url;
992
+ let split_url
980
993
  if (this.options.basicAuth) {
981
994
  if (url.startsWith('/')) {
982
- url = this.options.url + url;
995
+ url = this.options.url + url
983
996
  }
984
- split_url = url.split('//');
985
- url = `${split_url[0]}//${this.options.basicAuth.username}:${this.options.basicAuth.password}@${split_url[1]}`;
997
+ split_url = url.split('//')
998
+ url = `${split_url[0]}//${this.options.basicAuth.username}:${this.options.basicAuth.password}@${split_url[1]}`
986
999
  }
987
- return this.browser.url(url);
1000
+ return this.browser.url(url)
988
1001
  }
989
1002
 
990
1003
  /**
@@ -993,18 +1006,18 @@ class WebDriver extends Helper {
993
1006
  * {{ react }}
994
1007
  */
995
1008
  async click(locator, context = null) {
996
- const clickMethod = this.browser.isMobile && !this.browser.isW3C ? 'touchClick' : 'elementClick';
997
- const locateFn = prepareLocateFn.call(this, context);
1009
+ const clickMethod = this.browser.isMobile && !this.browser.isW3C ? 'touchClick' : 'elementClick'
1010
+ const locateFn = prepareLocateFn.call(this, context)
998
1011
 
999
- const res = await findClickable.call(this, locator, locateFn);
1012
+ const res = await findClickable.call(this, locator, locateFn)
1000
1013
  if (context) {
1001
- assertElementExists(res, locator, 'Clickable element', `was not found inside element ${new Locator(context)}`);
1014
+ assertElementExists(res, locator, 'Clickable element', `was not found inside element ${new Locator(context)}`)
1002
1015
  } else {
1003
- assertElementExists(res, locator, 'Clickable element');
1016
+ assertElementExists(res, locator, 'Clickable element')
1004
1017
  }
1005
- const elem = usingFirstElement(res);
1006
- highlightActiveElement.call(this, elem);
1007
- return this.browser[clickMethod](getElementId(elem));
1018
+ const elem = usingFirstElement(res)
1019
+ highlightActiveElement.call(this, elem)
1020
+ return this.browser[clickMethod](getElementId(elem))
1008
1021
  }
1009
1022
 
1010
1023
  /**
@@ -1013,25 +1026,25 @@ class WebDriver extends Helper {
1013
1026
  * {{ react }}
1014
1027
  */
1015
1028
  async forceClick(locator, context = null) {
1016
- const locateFn = prepareLocateFn.call(this, context);
1029
+ const locateFn = prepareLocateFn.call(this, context)
1017
1030
 
1018
- const res = await findClickable.call(this, locator, locateFn);
1031
+ const res = await findClickable.call(this, locator, locateFn)
1019
1032
  if (context) {
1020
- assertElementExists(res, locator, 'Clickable element', `was not found inside element ${new Locator(context)}`);
1033
+ assertElementExists(res, locator, 'Clickable element', `was not found inside element ${new Locator(context)}`)
1021
1034
  } else {
1022
- assertElementExists(res, locator, 'Clickable element');
1035
+ assertElementExists(res, locator, 'Clickable element')
1023
1036
  }
1024
- const elem = usingFirstElement(res);
1025
- highlightActiveElement.call(this, elem);
1037
+ const elem = usingFirstElement(res)
1038
+ highlightActiveElement.call(this, elem)
1026
1039
 
1027
1040
  return this.executeScript((el) => {
1028
1041
  if (document.activeElement instanceof HTMLElement) {
1029
- document.activeElement.blur();
1042
+ document.activeElement.blur()
1030
1043
  }
1031
- const event = document.createEvent('MouseEvent');
1032
- event.initEvent('click', true, true);
1033
- return el.dispatchEvent(event);
1034
- }, elem);
1044
+ const event = document.createEvent('MouseEvent')
1045
+ event.initEvent('click', true, true)
1046
+ return el.dispatchEvent(event)
1047
+ }, elem)
1035
1048
  }
1036
1049
 
1037
1050
  /**
@@ -1040,18 +1053,18 @@ class WebDriver extends Helper {
1040
1053
  * {{ react }}
1041
1054
  */
1042
1055
  async doubleClick(locator, context = null) {
1043
- const locateFn = prepareLocateFn.call(this, context);
1056
+ const locateFn = prepareLocateFn.call(this, context)
1044
1057
 
1045
- const res = await findClickable.call(this, locator, locateFn);
1058
+ const res = await findClickable.call(this, locator, locateFn)
1046
1059
  if (context) {
1047
- assertElementExists(res, locator, 'Clickable element', `was not found inside element ${new Locator(context)}`);
1060
+ assertElementExists(res, locator, 'Clickable element', `was not found inside element ${new Locator(context)}`)
1048
1061
  } else {
1049
- assertElementExists(res, locator, 'Clickable element');
1062
+ assertElementExists(res, locator, 'Clickable element')
1050
1063
  }
1051
1064
 
1052
- const elem = usingFirstElement(res);
1053
- highlightActiveElement.call(this, elem);
1054
- return elem.doubleClick();
1065
+ const elem = usingFirstElement(res)
1066
+ highlightActiveElement.call(this, elem)
1067
+ return elem.doubleClick()
1055
1068
  }
1056
1069
 
1057
1070
  /**
@@ -1060,24 +1073,24 @@ class WebDriver extends Helper {
1060
1073
  * {{ react }}
1061
1074
  */
1062
1075
  async rightClick(locator, context) {
1063
- const locateFn = prepareLocateFn.call(this, context);
1076
+ const locateFn = prepareLocateFn.call(this, context)
1064
1077
 
1065
- const res = await findClickable.call(this, locator, locateFn);
1078
+ const res = await findClickable.call(this, locator, locateFn)
1066
1079
  if (context) {
1067
- assertElementExists(res, locator, 'Clickable element', `was not found inside element ${new Locator(context)}`);
1080
+ assertElementExists(res, locator, 'Clickable element', `was not found inside element ${new Locator(context)}`)
1068
1081
  } else {
1069
- assertElementExists(res, locator, 'Clickable element');
1082
+ assertElementExists(res, locator, 'Clickable element')
1070
1083
  }
1071
1084
 
1072
- const el = usingFirstElement(res);
1085
+ const el = usingFirstElement(res)
1073
1086
 
1074
- await el.moveTo();
1087
+ await el.moveTo()
1075
1088
 
1076
1089
  if (this.browser.isW3C) {
1077
- return el.click({ button: 'right' });
1090
+ return el.click({ button: 'right' })
1078
1091
  }
1079
1092
  // JSON Wire version
1080
- await this.browser.buttonDown(2);
1093
+ await this.browser.buttonDown(2)
1081
1094
  }
1082
1095
 
1083
1096
  /**
@@ -1086,24 +1099,24 @@ class WebDriver extends Helper {
1086
1099
  * {{ react }}
1087
1100
  */
1088
1101
  async forceRightClick(locator, context = null) {
1089
- const locateFn = prepareLocateFn.call(this, context);
1102
+ const locateFn = prepareLocateFn.call(this, context)
1090
1103
 
1091
- const res = await findClickable.call(this, locator, locateFn);
1104
+ const res = await findClickable.call(this, locator, locateFn)
1092
1105
  if (context) {
1093
- assertElementExists(res, locator, 'Clickable element', `was not found inside element ${new Locator(context)}`);
1106
+ assertElementExists(res, locator, 'Clickable element', `was not found inside element ${new Locator(context)}`)
1094
1107
  } else {
1095
- assertElementExists(res, locator, 'Clickable element');
1108
+ assertElementExists(res, locator, 'Clickable element')
1096
1109
  }
1097
- const elem = usingFirstElement(res);
1110
+ const elem = usingFirstElement(res)
1098
1111
 
1099
1112
  return this.executeScript((el) => {
1100
1113
  if (document.activeElement instanceof HTMLElement) {
1101
- document.activeElement.blur();
1114
+ document.activeElement.blur()
1102
1115
  }
1103
- const event = document.createEvent('MouseEvent');
1104
- event.initEvent('contextmenu', true, true);
1105
- return el.dispatchEvent(event);
1106
- }, elem);
1116
+ const event = document.createEvent('MouseEvent')
1117
+ event.initEvent('contextmenu', true, true)
1118
+ return el.dispatchEvent(event)
1119
+ }, elem)
1107
1120
  }
1108
1121
 
1109
1122
  /**
@@ -1113,12 +1126,12 @@ class WebDriver extends Helper {
1113
1126
  *
1114
1127
  */
1115
1128
  async fillField(field, value) {
1116
- const res = await findFields.call(this, field);
1117
- assertElementExists(res, field, 'Field');
1118
- const elem = usingFirstElement(res);
1119
- highlightActiveElement.call(this, elem);
1120
- await elem.clearValue();
1121
- await elem.setValue(value.toString());
1129
+ const res = await findFields.call(this, field)
1130
+ assertElementExists(res, field, 'Field')
1131
+ const elem = usingFirstElement(res)
1132
+ highlightActiveElement.call(this, elem)
1133
+ await elem.clearValue()
1134
+ await elem.setValue(value.toString())
1122
1135
  }
1123
1136
 
1124
1137
  /**
@@ -1126,15 +1139,15 @@ class WebDriver extends Helper {
1126
1139
  * {{ react }}
1127
1140
  */
1128
1141
  async appendField(field, value) {
1129
- const res = await findFields.call(this, field);
1130
- assertElementExists(res, field, 'Field');
1131
- const elem = usingFirstElement(res);
1132
- highlightActiveElement.call(this, elem);
1142
+ const res = await findFields.call(this, field)
1143
+ assertElementExists(res, field, 'Field')
1144
+ const elem = usingFirstElement(res)
1145
+ highlightActiveElement.call(this, elem)
1133
1146
  if (this.options.automationProtocol) {
1134
- const curentValue = await elem.getValue();
1135
- return elem.setValue(curentValue + value.toString());
1147
+ const curentValue = await elem.getValue()
1148
+ return elem.setValue(curentValue + value.toString())
1136
1149
  }
1137
- return elem.addValue(value.toString());
1150
+ return elem.addValue(value.toString())
1138
1151
  }
1139
1152
 
1140
1153
  /**
@@ -1142,47 +1155,63 @@ class WebDriver extends Helper {
1142
1155
  *
1143
1156
  */
1144
1157
  async clearField(field) {
1145
- const res = await findFields.call(this, field);
1146
- assertElementExists(res, field, 'Field');
1147
- const elem = usingFirstElement(res);
1148
- highlightActiveElement.call(this, elem);
1158
+ const res = await findFields.call(this, field)
1159
+ assertElementExists(res, field, 'Field')
1160
+ const elem = usingFirstElement(res)
1161
+ highlightActiveElement.call(this, elem)
1149
1162
  if (this.options.automationProtocol) {
1150
- return elem.setValue('');
1163
+ return elem.setValue('')
1151
1164
  }
1152
- return elem.clearValue(getElementId(elem));
1165
+ return elem.clearValue(getElementId(elem))
1153
1166
  }
1154
1167
 
1155
1168
  /**
1156
1169
  * {{> selectOption }}
1157
1170
  */
1158
1171
  async selectOption(select, option) {
1159
- const res = await findFields.call(this, select);
1160
- assertElementExists(res, select, 'Selectable field');
1161
- const elem = usingFirstElement(res);
1162
- highlightActiveElement.call(this, elem);
1172
+ const res = await findFields.call(this, select)
1173
+ assertElementExists(res, select, 'Selectable field')
1174
+ const elem = usingFirstElement(res)
1175
+ highlightActiveElement.call(this, elem)
1163
1176
 
1164
1177
  if (!Array.isArray(option)) {
1165
- option = [option];
1178
+ option = [option]
1166
1179
  }
1167
1180
 
1168
1181
  // select options by visible text
1169
- let els = await forEachAsync(option, async opt => this.browser.findElementsFromElement(getElementId(elem), 'xpath', Locator.select.byVisibleText(xpathLocator.literal(opt))));
1182
+ let els = await forEachAsync(option, async (opt) =>
1183
+ this.browser.findElementsFromElement(
1184
+ getElementId(elem),
1185
+ 'xpath',
1186
+ Locator.select.byVisibleText(xpathLocator.literal(opt)),
1187
+ ),
1188
+ )
1170
1189
 
1171
1190
  const clickOptionFn = async (el) => {
1172
- if (el[0]) el = el[0];
1173
- const elementId = getElementId(el);
1174
- if (elementId) return this.browser.elementClick(elementId);
1175
- };
1191
+ if (el[0]) el = el[0]
1192
+ const elementId = getElementId(el)
1193
+ if (elementId) return this.browser.elementClick(elementId)
1194
+ }
1176
1195
 
1177
1196
  if (Array.isArray(els) && els.length) {
1178
- return forEachAsync(els, clickOptionFn);
1197
+ return forEachAsync(els, clickOptionFn)
1179
1198
  }
1180
1199
  // select options by value
1181
- els = await forEachAsync(option, async opt => this.browser.findElementsFromElement(getElementId(elem), 'xpath', Locator.select.byValue(xpathLocator.literal(opt))));
1200
+ els = await forEachAsync(option, async (opt) =>
1201
+ this.browser.findElementsFromElement(
1202
+ getElementId(elem),
1203
+ 'xpath',
1204
+ Locator.select.byValue(xpathLocator.literal(opt)),
1205
+ ),
1206
+ )
1182
1207
  if (els.length === 0) {
1183
- throw new ElementNotFound(select, `Option "${option}" in`, 'was not found neither by a visible text nor by a value');
1208
+ throw new ElementNotFound(
1209
+ select,
1210
+ `Option "${option}" in`,
1211
+ 'was not found neither by a visible text nor by a value',
1212
+ )
1184
1213
  }
1185
- return forEachAsync(els, clickOptionFn);
1214
+ return forEachAsync(els, clickOptionFn)
1186
1215
  }
1187
1216
 
1188
1217
  /**
@@ -1191,27 +1220,29 @@ class WebDriver extends Helper {
1191
1220
  * {{> attachFile }}
1192
1221
  */
1193
1222
  async attachFile(locator, pathToFile) {
1194
- let file = path.join(global.codecept_dir, pathToFile);
1223
+ let file = path.join(global.codecept_dir, pathToFile)
1195
1224
  if (!fileExists(file)) {
1196
- throw new Error(`File at ${file} can not be found on local system`);
1225
+ throw new Error(`File at ${file} can not be found on local system`)
1197
1226
  }
1198
1227
 
1199
- const res = await findFields.call(this, locator);
1200
- this.debug(`Uploading ${file}`);
1201
- assertElementExists(res, locator, 'File field');
1202
- const el = usingFirstElement(res);
1228
+ const res = await findFields.call(this, locator)
1229
+ this.debug(`Uploading ${file}`)
1230
+ assertElementExists(res, locator, 'File field')
1231
+ const el = usingFirstElement(res)
1203
1232
 
1204
1233
  // Remote Upload (when running Selenium Server)
1205
1234
  if (this.options.remoteFileUpload && !this.options.automationProtocol) {
1206
1235
  try {
1207
- this.debugSection('File', 'Uploading file to remote server');
1208
- file = await this.browser.uploadFile(file);
1236
+ this.debugSection('File', 'Uploading file to remote server')
1237
+ file = await this.browser.uploadFile(file)
1209
1238
  } catch (err) {
1210
- throw new Error(`File can't be transferred to remote server. Set \`remoteFileUpload: false\` in config to upload file locally.\n${err.message}`);
1239
+ throw new Error(
1240
+ `File can't be transferred to remote server. Set \`remoteFileUpload: false\` in config to upload file locally.\n${err.message}`,
1241
+ )
1211
1242
  }
1212
1243
  }
1213
1244
 
1214
- return el.addValue(file);
1245
+ return el.addValue(file)
1215
1246
  }
1216
1247
 
1217
1248
  /**
@@ -1219,19 +1250,19 @@ class WebDriver extends Helper {
1219
1250
  * {{> checkOption }}
1220
1251
  */
1221
1252
  async checkOption(field, context = null) {
1222
- const clickMethod = this.browser.isMobile && !this.browser.isW3C ? 'touchClick' : 'elementClick';
1223
- const locateFn = prepareLocateFn.call(this, context);
1253
+ const clickMethod = this.browser.isMobile && !this.browser.isW3C ? 'touchClick' : 'elementClick'
1254
+ const locateFn = prepareLocateFn.call(this, context)
1224
1255
 
1225
- const res = await findCheckable.call(this, field, locateFn);
1256
+ const res = await findCheckable.call(this, field, locateFn)
1226
1257
 
1227
- assertElementExists(res, field, 'Checkable');
1228
- const elem = usingFirstElement(res);
1229
- const elementId = getElementId(elem);
1230
- highlightActiveElement.call(this, elem);
1258
+ assertElementExists(res, field, 'Checkable')
1259
+ const elem = usingFirstElement(res)
1260
+ const elementId = getElementId(elem)
1261
+ highlightActiveElement.call(this, elem)
1231
1262
 
1232
- const isSelected = await this.browser.isElementSelected(elementId);
1233
- if (isSelected) return Promise.resolve(true);
1234
- return this.browser[clickMethod](elementId);
1263
+ const isSelected = await this.browser.isElementSelected(elementId)
1264
+ if (isSelected) return Promise.resolve(true)
1265
+ return this.browser[clickMethod](elementId)
1235
1266
  }
1236
1267
 
1237
1268
  /**
@@ -1239,19 +1270,19 @@ class WebDriver extends Helper {
1239
1270
  * {{> uncheckOption }}
1240
1271
  */
1241
1272
  async uncheckOption(field, context = null) {
1242
- const clickMethod = this.browser.isMobile && !this.browser.isW3C ? 'touchClick' : 'elementClick';
1243
- const locateFn = prepareLocateFn.call(this, context);
1273
+ const clickMethod = this.browser.isMobile && !this.browser.isW3C ? 'touchClick' : 'elementClick'
1274
+ const locateFn = prepareLocateFn.call(this, context)
1244
1275
 
1245
- const res = await findCheckable.call(this, field, locateFn);
1276
+ const res = await findCheckable.call(this, field, locateFn)
1246
1277
 
1247
- assertElementExists(res, field, 'Checkable');
1248
- const elem = usingFirstElement(res);
1249
- const elementId = getElementId(elem);
1250
- highlightActiveElement.call(this, elem);
1278
+ assertElementExists(res, field, 'Checkable')
1279
+ const elem = usingFirstElement(res)
1280
+ const elementId = getElementId(elem)
1281
+ highlightActiveElement.call(this, elem)
1251
1282
 
1252
- const isSelected = await this.browser.isElementSelected(elementId);
1253
- if (!isSelected) return Promise.resolve(true);
1254
- return this.browser[clickMethod](elementId);
1283
+ const isSelected = await this.browser.isElementSelected(elementId)
1284
+ if (!isSelected) return Promise.resolve(true)
1285
+ return this.browser[clickMethod](elementId)
1255
1286
  }
1256
1287
 
1257
1288
  /**
@@ -1259,10 +1290,10 @@ class WebDriver extends Helper {
1259
1290
  *
1260
1291
  */
1261
1292
  async grabTextFromAll(locator) {
1262
- const res = await this._locate(locator, true);
1263
- const val = await forEachAsync(res, el => this.browser.getElementText(getElementId(el)));
1264
- this.debugSection('GrabText', String(val));
1265
- return val;
1293
+ const res = await this._locate(locator, true)
1294
+ const val = await forEachAsync(res, (el) => this.browser.getElementText(getElementId(el)))
1295
+ this.debugSection('GrabText', String(val))
1296
+ return val
1266
1297
  }
1267
1298
 
1268
1299
  /**
@@ -1270,13 +1301,13 @@ class WebDriver extends Helper {
1270
1301
  *
1271
1302
  */
1272
1303
  async grabTextFrom(locator) {
1273
- const texts = await this.grabTextFromAll(locator);
1274
- assertElementExists(texts, locator);
1304
+ const texts = await this.grabTextFromAll(locator)
1305
+ assertElementExists(texts, locator)
1275
1306
  if (texts.length > 1) {
1276
- this.debugSection('GrabText', `Using first element out of ${texts.length}`);
1307
+ this.debugSection('GrabText', `Using first element out of ${texts.length}`)
1277
1308
  }
1278
1309
 
1279
- return texts[0];
1310
+ return texts[0]
1280
1311
  }
1281
1312
 
1282
1313
  /**
@@ -1284,10 +1315,10 @@ class WebDriver extends Helper {
1284
1315
  *
1285
1316
  */
1286
1317
  async grabHTMLFromAll(locator) {
1287
- const elems = await this._locate(locator, true);
1288
- const html = await forEachAsync(elems, elem => elem.getHTML(false));
1289
- this.debugSection('GrabHTML', String(html));
1290
- return html;
1318
+ const elems = await this._locate(locator, true)
1319
+ const html = await forEachAsync(elems, (elem) => elem.getHTML(false))
1320
+ this.debugSection('GrabHTML', String(html))
1321
+ return html
1291
1322
  }
1292
1323
 
1293
1324
  /**
@@ -1295,13 +1326,13 @@ class WebDriver extends Helper {
1295
1326
  *
1296
1327
  */
1297
1328
  async grabHTMLFrom(locator) {
1298
- const html = await this.grabHTMLFromAll(locator);
1299
- assertElementExists(html, locator);
1329
+ const html = await this.grabHTMLFromAll(locator)
1330
+ assertElementExists(html, locator)
1300
1331
  if (html.length > 1) {
1301
- this.debugSection('GrabHTML', `Using first element out of ${html.length}`);
1332
+ this.debugSection('GrabHTML', `Using first element out of ${html.length}`)
1302
1333
  }
1303
1334
 
1304
- return html[0];
1335
+ return html[0]
1305
1336
  }
1306
1337
 
1307
1338
  /**
@@ -1309,11 +1340,11 @@ class WebDriver extends Helper {
1309
1340
  *
1310
1341
  */
1311
1342
  async grabValueFromAll(locator) {
1312
- const res = await this._locate(locator, true);
1313
- const val = await forEachAsync(res, el => el.getValue());
1314
- this.debugSection('GrabValue', String(val));
1343
+ const res = await this._locate(locator, true)
1344
+ const val = await forEachAsync(res, (el) => el.getValue())
1345
+ this.debugSection('GrabValue', String(val))
1315
1346
 
1316
- return val;
1347
+ return val
1317
1348
  }
1318
1349
 
1319
1350
  /**
@@ -1321,92 +1352,92 @@ class WebDriver extends Helper {
1321
1352
  *
1322
1353
  */
1323
1354
  async grabValueFrom(locator) {
1324
- const values = await this.grabValueFromAll(locator);
1325
- assertElementExists(values, locator);
1355
+ const values = await this.grabValueFromAll(locator)
1356
+ assertElementExists(values, locator)
1326
1357
  if (values.length > 1) {
1327
- this.debugSection('GrabValue', `Using first element out of ${values.length}`);
1358
+ this.debugSection('GrabValue', `Using first element out of ${values.length}`)
1328
1359
  }
1329
1360
 
1330
- return values[0];
1361
+ return values[0]
1331
1362
  }
1332
1363
 
1333
1364
  /**
1334
1365
  * {{> grabCssPropertyFromAll }}
1335
1366
  */
1336
1367
  async grabCssPropertyFromAll(locator, cssProperty) {
1337
- const res = await this._locate(locator, true);
1338
- const val = await forEachAsync(res, async el => this.browser.getElementCSSValue(getElementId(el), cssProperty));
1339
- this.debugSection('Grab', String(val));
1340
- return val;
1368
+ const res = await this._locate(locator, true)
1369
+ const val = await forEachAsync(res, async (el) => this.browser.getElementCSSValue(getElementId(el), cssProperty))
1370
+ this.debugSection('Grab', String(val))
1371
+ return val
1341
1372
  }
1342
1373
 
1343
1374
  /**
1344
1375
  * {{> grabCssPropertyFrom }}
1345
1376
  */
1346
1377
  async grabCssPropertyFrom(locator, cssProperty) {
1347
- const cssValues = await this.grabCssPropertyFromAll(locator, cssProperty);
1348
- assertElementExists(cssValues, locator);
1378
+ const cssValues = await this.grabCssPropertyFromAll(locator, cssProperty)
1379
+ assertElementExists(cssValues, locator)
1349
1380
 
1350
1381
  if (cssValues.length > 1) {
1351
- this.debugSection('GrabCSS', `Using first element out of ${cssValues.length}`);
1382
+ this.debugSection('GrabCSS', `Using first element out of ${cssValues.length}`)
1352
1383
  }
1353
1384
 
1354
- return cssValues[0];
1385
+ return cssValues[0]
1355
1386
  }
1356
1387
 
1357
1388
  /**
1358
1389
  * {{> grabAttributeFromAll }}
1359
1390
  */
1360
1391
  async grabAttributeFromAll(locator, attr) {
1361
- const res = await this._locate(locator, true);
1362
- const val = await forEachAsync(res, async el => el.getAttribute(attr));
1363
- this.debugSection('GrabAttribute', String(val));
1364
- return val;
1392
+ const res = await this._locate(locator, true)
1393
+ const val = await forEachAsync(res, async (el) => el.getAttribute(attr))
1394
+ this.debugSection('GrabAttribute', String(val))
1395
+ return val
1365
1396
  }
1366
1397
 
1367
1398
  /**
1368
1399
  * {{> grabAttributeFrom }}
1369
1400
  */
1370
1401
  async grabAttributeFrom(locator, attr) {
1371
- const attrs = await this.grabAttributeFromAll(locator, attr);
1372
- assertElementExists(attrs, locator);
1402
+ const attrs = await this.grabAttributeFromAll(locator, attr)
1403
+ assertElementExists(attrs, locator)
1373
1404
  if (attrs.length > 1) {
1374
- this.debugSection('GrabAttribute', `Using first element out of ${attrs.length}`);
1405
+ this.debugSection('GrabAttribute', `Using first element out of ${attrs.length}`)
1375
1406
  }
1376
- return attrs[0];
1407
+ return attrs[0]
1377
1408
  }
1378
1409
 
1379
1410
  /**
1380
1411
  * {{> seeInTitle }}
1381
1412
  */
1382
1413
  async seeInTitle(text) {
1383
- const title = await this.browser.getTitle();
1384
- return stringIncludes('web page title').assert(text, title);
1414
+ const title = await this.browser.getTitle()
1415
+ return stringIncludes('web page title').assert(text, title)
1385
1416
  }
1386
1417
 
1387
1418
  /**
1388
1419
  * {{> seeTitleEquals }}
1389
1420
  */
1390
1421
  async seeTitleEquals(text) {
1391
- const title = await this.browser.getTitle();
1392
- return assert.equal(title, text, `expected web page title to be ${text}, but found ${title}`);
1422
+ const title = await this.browser.getTitle()
1423
+ return assert.equal(title, text, `expected web page title to be ${text}, but found ${title}`)
1393
1424
  }
1394
1425
 
1395
1426
  /**
1396
1427
  * {{> dontSeeInTitle }}
1397
1428
  */
1398
1429
  async dontSeeInTitle(text) {
1399
- const title = await this.browser.getTitle();
1400
- return stringIncludes('web page title').negate(text, title);
1430
+ const title = await this.browser.getTitle()
1431
+ return stringIncludes('web page title').negate(text, title)
1401
1432
  }
1402
1433
 
1403
1434
  /**
1404
1435
  * {{> grabTitle }}
1405
1436
  */
1406
1437
  async grabTitle() {
1407
- const title = await this.browser.getTitle();
1408
- this.debugSection('Title', title);
1409
- return title;
1438
+ const title = await this.browser.getTitle()
1439
+ this.debugSection('Title', title)
1440
+ return title
1410
1441
  }
1411
1442
 
1412
1443
  /**
@@ -1415,14 +1446,14 @@ class WebDriver extends Helper {
1415
1446
  * {{ react }}
1416
1447
  */
1417
1448
  async see(text, context = null) {
1418
- return proceedSee.call(this, 'assert', text, context);
1449
+ return proceedSee.call(this, 'assert', text, context)
1419
1450
  }
1420
1451
 
1421
1452
  /**
1422
1453
  * {{> seeTextEquals }}
1423
1454
  */
1424
1455
  async seeTextEquals(text, context = null) {
1425
- return proceedSee.call(this, 'assert', text, context, true);
1456
+ return proceedSee.call(this, 'assert', text, context, true)
1426
1457
  }
1427
1458
 
1428
1459
  /**
@@ -1431,7 +1462,7 @@ class WebDriver extends Helper {
1431
1462
  * {{ react }}
1432
1463
  */
1433
1464
  async dontSee(text, context = null) {
1434
- return proceedSee.call(this, 'negate', text, context);
1465
+ return proceedSee.call(this, 'negate', text, context)
1435
1466
  }
1436
1467
 
1437
1468
  /**
@@ -1439,8 +1470,8 @@ class WebDriver extends Helper {
1439
1470
  *
1440
1471
  */
1441
1472
  async seeInField(field, value) {
1442
- const _value = (typeof value === 'boolean') ? value : value.toString();
1443
- return proceedSeeField.call(this, 'assert', field, _value);
1473
+ const _value = typeof value === 'boolean' ? value : value.toString()
1474
+ return proceedSeeField.call(this, 'assert', field, _value)
1444
1475
  }
1445
1476
 
1446
1477
  /**
@@ -1448,8 +1479,8 @@ class WebDriver extends Helper {
1448
1479
  *
1449
1480
  */
1450
1481
  async dontSeeInField(field, value) {
1451
- const _value = (typeof value === 'boolean') ? value : value.toString();
1452
- return proceedSeeField.call(this, 'negate', field, _value);
1482
+ const _value = typeof value === 'boolean' ? value : value.toString()
1483
+ return proceedSeeField.call(this, 'negate', field, _value)
1453
1484
  }
1454
1485
 
1455
1486
  /**
@@ -1457,7 +1488,7 @@ class WebDriver extends Helper {
1457
1488
  * {{> seeCheckboxIsChecked }}
1458
1489
  */
1459
1490
  async seeCheckboxIsChecked(field) {
1460
- return proceedSeeCheckbox.call(this, 'assert', field);
1491
+ return proceedSeeCheckbox.call(this, 'assert', field)
1461
1492
  }
1462
1493
 
1463
1494
  /**
@@ -1465,7 +1496,7 @@ class WebDriver extends Helper {
1465
1496
  * {{> dontSeeCheckboxIsChecked }}
1466
1497
  */
1467
1498
  async dontSeeCheckboxIsChecked(field) {
1468
- return proceedSeeCheckbox.call(this, 'negate', field);
1499
+ return proceedSeeCheckbox.call(this, 'negate', field)
1469
1500
  }
1470
1501
 
1471
1502
  /**
@@ -1474,13 +1505,13 @@ class WebDriver extends Helper {
1474
1505
  *
1475
1506
  */
1476
1507
  async seeElement(locator) {
1477
- const res = await this._locate(locator, true);
1478
- assertElementExists(res, locator);
1479
- const selected = await forEachAsync(res, async el => el.isDisplayed());
1508
+ const res = await this._locate(locator, true)
1509
+ assertElementExists(res, locator)
1510
+ const selected = await forEachAsync(res, async (el) => el.isDisplayed())
1480
1511
  try {
1481
- return truth(`elements of ${(new Locator(locator))}`, 'to be seen').assert(selected);
1512
+ return truth(`elements of ${new Locator(locator)}`, 'to be seen').assert(selected)
1482
1513
  } catch (e) {
1483
- dontSeeElementError(locator);
1514
+ dontSeeElementError(locator)
1484
1515
  }
1485
1516
  }
1486
1517
 
@@ -1489,15 +1520,15 @@ class WebDriver extends Helper {
1489
1520
  * {{ react }}
1490
1521
  */
1491
1522
  async dontSeeElement(locator) {
1492
- const res = await this._locate(locator, false);
1523
+ const res = await this._locate(locator, false)
1493
1524
  if (!res || res.length === 0) {
1494
- return truth(`elements of ${(new Locator(locator))}`, 'to be seen').negate(false);
1525
+ return truth(`elements of ${new Locator(locator)}`, 'to be seen').negate(false)
1495
1526
  }
1496
- const selected = await forEachAsync(res, async el => el.isDisplayed());
1527
+ const selected = await forEachAsync(res, async (el) => el.isDisplayed())
1497
1528
  try {
1498
- return truth(`elements of ${(new Locator(locator))}`, 'to be seen').negate(selected);
1529
+ return truth(`elements of ${new Locator(locator)}`, 'to be seen').negate(selected)
1499
1530
  } catch (e) {
1500
- seeElementError(locator);
1531
+ seeElementError(locator)
1501
1532
  }
1502
1533
  }
1503
1534
 
@@ -1506,11 +1537,11 @@ class WebDriver extends Helper {
1506
1537
  *
1507
1538
  */
1508
1539
  async seeElementInDOM(locator) {
1509
- const res = await this._res(locator);
1540
+ const res = await this._res(locator)
1510
1541
  try {
1511
- return empty('elements').negate(res);
1542
+ return empty('elements').negate(res)
1512
1543
  } catch (e) {
1513
- dontSeeElementInDOMError(locator);
1544
+ dontSeeElementInDOMError(locator)
1514
1545
  }
1515
1546
  }
1516
1547
 
@@ -1519,11 +1550,11 @@ class WebDriver extends Helper {
1519
1550
  *
1520
1551
  */
1521
1552
  async dontSeeElementInDOM(locator) {
1522
- const res = await this._res(locator);
1553
+ const res = await this._res(locator)
1523
1554
  try {
1524
- return empty('elements').assert(res);
1555
+ return empty('elements').assert(res)
1525
1556
  } catch (e) {
1526
- seeElementInDOMError(locator);
1557
+ seeElementInDOMError(locator)
1527
1558
  }
1528
1559
  }
1529
1560
 
@@ -1532,8 +1563,8 @@ class WebDriver extends Helper {
1532
1563
  *
1533
1564
  */
1534
1565
  async seeInSource(text) {
1535
- const source = await this.browser.getPageSource();
1536
- return stringIncludes('HTML source of a page').assert(text, source);
1566
+ const source = await this.browser.getPageSource()
1567
+ return stringIncludes('HTML source of a page').assert(text, source)
1537
1568
  }
1538
1569
 
1539
1570
  /**
@@ -1541,7 +1572,7 @@ class WebDriver extends Helper {
1541
1572
  *
1542
1573
  */
1543
1574
  async grabSource() {
1544
- return this.browser.getPageSource();
1575
+ return this.browser.getPageSource()
1545
1576
  }
1546
1577
 
1547
1578
  /**
@@ -1549,27 +1580,27 @@ class WebDriver extends Helper {
1549
1580
  */
1550
1581
  async grabBrowserLogs() {
1551
1582
  if (this.browser.isW3C) {
1552
- this.debug('Logs not available in W3C specification');
1553
- return;
1583
+ this.debug('Logs not available in W3C specification')
1584
+ return
1554
1585
  }
1555
- return this.browser.getLogs('browser');
1586
+ return this.browser.getLogs('browser')
1556
1587
  }
1557
1588
 
1558
1589
  /**
1559
1590
  * {{> grabCurrentUrl }}
1560
1591
  */
1561
1592
  async grabCurrentUrl() {
1562
- const res = await this.browser.getUrl();
1563
- this.debugSection('Url', res);
1564
- return res;
1593
+ const res = await this.browser.getUrl()
1594
+ this.debugSection('Url', res)
1595
+ return res
1565
1596
  }
1566
1597
 
1567
1598
  /**
1568
1599
  * {{> dontSeeInSource }}
1569
1600
  */
1570
1601
  async dontSeeInSource(text) {
1571
- const source = await this.browser.getPageSource();
1572
- return stringIncludes('HTML source of a page').negate(text, source);
1602
+ const source = await this.browser.getPageSource()
1603
+ return stringIncludes('HTML source of a page').negate(text, source)
1573
1604
  }
1574
1605
 
1575
1606
  /**
@@ -1577,8 +1608,12 @@ class WebDriver extends Helper {
1577
1608
  * {{ react }}
1578
1609
  */
1579
1610
  async seeNumberOfElements(locator, num) {
1580
- const res = await this._locate(locator);
1581
- return assert.equal(res.length, num, `expected number of elements (${(new Locator(locator))}) is ${num}, but found ${res.length}`);
1611
+ const res = await this._locate(locator)
1612
+ return assert.equal(
1613
+ res.length,
1614
+ num,
1615
+ `expected number of elements (${new Locator(locator)}) is ${num}, but found ${res.length}`,
1616
+ )
1582
1617
  }
1583
1618
 
1584
1619
  /**
@@ -1586,86 +1621,93 @@ class WebDriver extends Helper {
1586
1621
  * {{ react }}
1587
1622
  */
1588
1623
  async seeNumberOfVisibleElements(locator, num) {
1589
- const res = await this.grabNumberOfVisibleElements(locator);
1590
- return assert.equal(res, num, `expected number of visible elements (${(new Locator(locator))}) is ${num}, but found ${res}`);
1624
+ const res = await this.grabNumberOfVisibleElements(locator)
1625
+ return assert.equal(
1626
+ res,
1627
+ num,
1628
+ `expected number of visible elements (${new Locator(locator)}) is ${num}, but found ${res}`,
1629
+ )
1591
1630
  }
1592
1631
 
1593
1632
  /**
1594
1633
  * {{> seeCssPropertiesOnElements }}
1595
1634
  */
1596
1635
  async seeCssPropertiesOnElements(locator, cssProperties) {
1597
- const res = await this._locate(locator);
1598
- assertElementExists(res, locator);
1636
+ const res = await this._locate(locator)
1637
+ assertElementExists(res, locator)
1599
1638
 
1600
- const cssPropertiesCamelCase = convertCssPropertiesToCamelCase(cssProperties);
1601
- const elemAmount = res.length;
1602
- let props = [];
1639
+ const cssPropertiesCamelCase = convertCssPropertiesToCamelCase(cssProperties)
1640
+ const elemAmount = res.length
1641
+ let props = []
1603
1642
 
1604
1643
  for (const element of res) {
1605
1644
  for (const prop of Object.keys(cssProperties)) {
1606
- const cssProp = await this.grabCssPropertyFrom(locator, prop);
1645
+ const cssProp = await this.grabCssPropertyFrom(locator, prop)
1607
1646
  if (isColorProperty(prop)) {
1608
- props.push(convertColorToRGBA(cssProp));
1647
+ props.push(convertColorToRGBA(cssProp))
1609
1648
  } else {
1610
- props.push(cssProp);
1649
+ props.push(cssProp)
1611
1650
  }
1612
1651
  }
1613
1652
  }
1614
1653
 
1615
- const values = Object.keys(cssPropertiesCamelCase).map(key => cssPropertiesCamelCase[key]);
1616
- if (!Array.isArray(props)) props = [props];
1617
- let chunked = chunkArray(props, values.length);
1654
+ const values = Object.keys(cssPropertiesCamelCase).map((key) => cssPropertiesCamelCase[key])
1655
+ if (!Array.isArray(props)) props = [props]
1656
+ let chunked = chunkArray(props, values.length)
1618
1657
  chunked = chunked.filter((val) => {
1619
1658
  for (let i = 0; i < val.length; ++i) {
1620
1659
  // eslint-disable-next-line eqeqeq
1621
- if (val[i] != values[i]) return false;
1660
+ if (val[i] != values[i]) return false
1622
1661
  }
1623
- return true;
1624
- });
1625
- return equals(`all elements (${(new Locator(locator))}) to have CSS property ${JSON.stringify(cssProperties)}`).assert(chunked.length, elemAmount);
1662
+ return true
1663
+ })
1664
+ return equals(
1665
+ `all elements (${new Locator(locator)}) to have CSS property ${JSON.stringify(cssProperties)}`,
1666
+ ).assert(chunked.length, elemAmount)
1626
1667
  }
1627
1668
 
1628
1669
  /**
1629
1670
  * {{> seeAttributesOnElements }}
1630
1671
  */
1631
1672
  async seeAttributesOnElements(locator, attributes) {
1632
- const res = await this._locate(locator);
1633
- assertElementExists(res, locator);
1634
- const elemAmount = res.length;
1673
+ const res = await this._locate(locator)
1674
+ assertElementExists(res, locator)
1675
+ const elemAmount = res.length
1635
1676
 
1636
1677
  let attrs = await forEachAsync(res, async (el) => {
1637
- return forEachAsync(Object.keys(attributes), async attr => el.getAttribute(attr));
1638
- });
1678
+ return forEachAsync(Object.keys(attributes), async (attr) => el.getAttribute(attr))
1679
+ })
1639
1680
 
1640
- const values = Object.keys(attributes).map(key => attributes[key]);
1641
- if (!Array.isArray(attrs)) attrs = [attrs];
1642
- let chunked = chunkArray(attrs, values.length);
1681
+ const values = Object.keys(attributes).map((key) => attributes[key])
1682
+ if (!Array.isArray(attrs)) attrs = [attrs]
1683
+ let chunked = chunkArray(attrs, values.length)
1643
1684
  chunked = chunked.filter((val) => {
1644
1685
  for (let i = 0; i < val.length; ++i) {
1645
- const _actual = Number.isNaN(val[i]) || (typeof values[i]) === 'string' ? val[i] : Number.parseInt(val[i], 10);
1646
- const _expected = Number.isNaN(values[i]) || (typeof values[i]) === 'string' ? values[i] : Number.parseInt(values[i], 10);
1686
+ const _actual = Number.isNaN(val[i]) || typeof values[i] === 'string' ? val[i] : Number.parseInt(val[i], 10)
1687
+ const _expected =
1688
+ Number.isNaN(values[i]) || typeof values[i] === 'string' ? values[i] : Number.parseInt(values[i], 10)
1647
1689
  // the attribute could be a boolean
1648
- if (typeof _actual === 'boolean') return _actual === _expected;
1649
- if (_actual !== _expected) return false;
1690
+ if (typeof _actual === 'boolean') return _actual === _expected
1691
+ if (_actual !== _expected) return false
1650
1692
  }
1651
- return true;
1652
- });
1693
+ return true
1694
+ })
1653
1695
  return assert.ok(
1654
1696
  chunked.length === elemAmount,
1655
- `expected all elements (${(new Locator(locator))}) to have attributes ${JSON.stringify(attributes)}`,
1656
- );
1697
+ `expected all elements (${new Locator(locator)}) to have attributes ${JSON.stringify(attributes)}`,
1698
+ )
1657
1699
  }
1658
1700
 
1659
1701
  /**
1660
1702
  * {{> grabNumberOfVisibleElements }}
1661
1703
  */
1662
1704
  async grabNumberOfVisibleElements(locator) {
1663
- const res = await this._locate(locator);
1705
+ const res = await this._locate(locator)
1664
1706
 
1665
- let selected = await forEachAsync(res, async el => el.isDisplayed());
1666
- if (!Array.isArray(selected)) selected = [selected];
1667
- selected = selected.filter(val => val === true);
1668
- return selected.length;
1707
+ let selected = await forEachAsync(res, async (el) => el.isDisplayed())
1708
+ if (!Array.isArray(selected)) selected = [selected]
1709
+ selected = selected.filter((val) => val === true)
1710
+ return selected.length
1669
1711
  }
1670
1712
 
1671
1713
  /**
@@ -1673,8 +1715,8 @@ class WebDriver extends Helper {
1673
1715
  *
1674
1716
  */
1675
1717
  async seeInCurrentUrl(url) {
1676
- const res = await this.browser.getUrl();
1677
- return stringIncludes('url').assert(url, decodeUrl(res));
1718
+ const res = await this.browser.getUrl()
1719
+ return stringIncludes('url').assert(url, decodeUrl(res))
1678
1720
  }
1679
1721
 
1680
1722
  /**
@@ -1682,8 +1724,8 @@ class WebDriver extends Helper {
1682
1724
  *
1683
1725
  */
1684
1726
  async dontSeeInCurrentUrl(url) {
1685
- const res = await this.browser.getUrl();
1686
- return stringIncludes('url').negate(url, decodeUrl(res));
1727
+ const res = await this.browser.getUrl()
1728
+ return stringIncludes('url').negate(url, decodeUrl(res))
1687
1729
  }
1688
1730
 
1689
1731
  /**
@@ -1691,8 +1733,8 @@ class WebDriver extends Helper {
1691
1733
  *
1692
1734
  */
1693
1735
  async seeCurrentUrlEquals(url) {
1694
- const res = await this.browser.getUrl();
1695
- return urlEquals(this.options.url).assert(url, decodeUrl(res));
1736
+ const res = await this.browser.getUrl()
1737
+ return urlEquals(this.options.url).assert(url, decodeUrl(res))
1696
1738
  }
1697
1739
 
1698
1740
  /**
@@ -1700,8 +1742,8 @@ class WebDriver extends Helper {
1700
1742
  *
1701
1743
  */
1702
1744
  async dontSeeCurrentUrlEquals(url) {
1703
- const res = await this.browser.getUrl();
1704
- return urlEquals(this.options.url).negate(url, decodeUrl(res));
1745
+ const res = await this.browser.getUrl()
1746
+ return urlEquals(this.options.url).negate(url, decodeUrl(res))
1705
1747
  }
1706
1748
 
1707
1749
  /**
@@ -1710,7 +1752,7 @@ class WebDriver extends Helper {
1710
1752
  * {{> executeScript }}
1711
1753
  */
1712
1754
  executeScript(...args) {
1713
- return this.browser.execute.apply(this.browser, args);
1755
+ return this.browser.execute.apply(this.browser, args)
1714
1756
  }
1715
1757
 
1716
1758
  /**
@@ -1718,7 +1760,7 @@ class WebDriver extends Helper {
1718
1760
  *
1719
1761
  */
1720
1762
  executeAsyncScript(...args) {
1721
- return this.browser.executeAsync.apply(this.browser, args);
1763
+ return this.browser.executeAsync.apply(this.browser, args)
1722
1764
  }
1723
1765
 
1724
1766
  /**
@@ -1726,10 +1768,10 @@ class WebDriver extends Helper {
1726
1768
  *
1727
1769
  */
1728
1770
  async scrollIntoView(locator, scrollIntoViewOptions) {
1729
- const res = await this._locate(withStrictLocator(locator), true);
1730
- assertElementExists(res, locator);
1731
- const elem = usingFirstElement(res);
1732
- return elem.scrollIntoView(scrollIntoViewOptions);
1771
+ const res = await this._locate(withStrictLocator(locator), true)
1772
+ assertElementExists(res, locator)
1773
+ const elem = usingFirstElement(res)
1774
+ return elem.scrollIntoView(scrollIntoViewOptions)
1733
1775
  }
1734
1776
 
1735
1777
  /**
@@ -1738,28 +1780,40 @@ class WebDriver extends Helper {
1738
1780
  */
1739
1781
  async scrollTo(locator, offsetX = 0, offsetY = 0) {
1740
1782
  if (typeof locator === 'number' && typeof offsetX === 'number') {
1741
- offsetY = offsetX;
1742
- offsetX = locator;
1743
- locator = null;
1783
+ offsetY = offsetX
1784
+ offsetX = locator
1785
+ locator = null
1744
1786
  }
1745
1787
 
1746
1788
  if (locator) {
1747
- const res = await this._locate(withStrictLocator(locator), true);
1748
- assertElementExists(res, locator);
1749
- const elem = usingFirstElement(res);
1750
- const elementId = getElementId(elem);
1751
- if (this.browser.isMobile && !this.browser.isW3C) return this.browser.touchScroll(offsetX, offsetY, elementId);
1752
- const location = await elem.getLocation();
1753
- assertElementExists(location, locator, 'Failed to receive', 'location');
1789
+ const res = await this._locate(withStrictLocator(locator), true)
1790
+ assertElementExists(res, locator)
1791
+ const elem = usingFirstElement(res)
1792
+ const elementId = getElementId(elem)
1793
+ if (this.browser.isMobile && !this.browser.isW3C) return this.browser.touchScroll(offsetX, offsetY, elementId)
1794
+ const location = await elem.getLocation()
1795
+ assertElementExists(location, locator, 'Failed to receive', 'location')
1754
1796
  /* eslint-disable prefer-arrow-callback */
1755
- return this.browser.execute(function (x, y) { return window.scrollTo(x, y); }, location.x + offsetX, location.y + offsetY);
1797
+ return this.browser.execute(
1798
+ function (x, y) {
1799
+ return window.scrollTo(x, y)
1800
+ },
1801
+ location.x + offsetX,
1802
+ location.y + offsetY,
1803
+ )
1756
1804
  /* eslint-enable */
1757
1805
  }
1758
1806
 
1759
- if (this.browser.isMobile && !this.browser.isW3C) return this.browser.touchScroll(locator, offsetX, offsetY);
1807
+ if (this.browser.isMobile && !this.browser.isW3C) return this.browser.touchScroll(locator, offsetX, offsetY)
1760
1808
 
1761
1809
  /* eslint-disable prefer-arrow-callback, comma-dangle */
1762
- return this.browser.execute(function (x, y) { return window.scrollTo(x, y); }, offsetX, offsetY);
1810
+ return this.browser.execute(
1811
+ function (x, y) {
1812
+ return window.scrollTo(x, y)
1813
+ },
1814
+ offsetX,
1815
+ offsetY,
1816
+ )
1763
1817
  /* eslint-enable */
1764
1818
  }
1765
1819
 
@@ -1767,13 +1821,13 @@ class WebDriver extends Helper {
1767
1821
  * {{> moveCursorTo }}
1768
1822
  */
1769
1823
  async moveCursorTo(locator, xOffset, yOffset) {
1770
- const res = await this._locate(withStrictLocator(locator), true);
1771
- assertElementExists(res, locator);
1772
- const elem = usingFirstElement(res);
1824
+ const res = await this._locate(withStrictLocator(locator), true)
1825
+ assertElementExists(res, locator)
1826
+ const elem = usingFirstElement(res)
1773
1827
  try {
1774
- await elem.moveTo({ xOffset, yOffset });
1828
+ await elem.moveTo({ xOffset, yOffset })
1775
1829
  } catch (e) {
1776
- debug(e.message);
1830
+ debug(e.message)
1777
1831
  }
1778
1832
  }
1779
1833
 
@@ -1782,61 +1836,63 @@ class WebDriver extends Helper {
1782
1836
  *
1783
1837
  */
1784
1838
  async saveElementScreenshot(locator, fileName) {
1785
- const outputFile = screenshotOutputFolder(fileName);
1839
+ const outputFile = screenshotOutputFolder(fileName)
1786
1840
 
1787
- const res = await this._locate(withStrictLocator(locator), true);
1788
- assertElementExists(res, locator);
1789
- const elem = usingFirstElement(res);
1841
+ const res = await this._locate(withStrictLocator(locator), true)
1842
+ assertElementExists(res, locator)
1843
+ const elem = usingFirstElement(res)
1790
1844
 
1791
- this.debug(`Screenshot of ${(new Locator(locator))} element has been saved to ${outputFile}`);
1792
- return elem.saveScreenshot(outputFile);
1845
+ this.debug(`Screenshot of ${new Locator(locator)} element has been saved to ${outputFile}`)
1846
+ return elem.saveScreenshot(outputFile)
1793
1847
  }
1794
1848
 
1795
1849
  /**
1796
1850
  * {{> saveScreenshot }}
1797
1851
  */
1798
1852
  async saveScreenshot(fileName, fullPage = false) {
1799
- let outputFile = screenshotOutputFolder(fileName);
1853
+ let outputFile = screenshotOutputFolder(fileName)
1800
1854
 
1801
1855
  if (this.activeSessionName) {
1802
- const browser = this.sessionWindows[this.activeSessionName];
1856
+ const browser = this.sessionWindows[this.activeSessionName]
1803
1857
 
1804
1858
  for (const sessionName in this.sessionWindows) {
1805
- const activeSessionPage = this.sessionWindows[sessionName];
1806
- outputFile = screenshotOutputFolder(`${sessionName}_${fileName}`);
1859
+ const activeSessionPage = this.sessionWindows[sessionName]
1860
+ outputFile = screenshotOutputFolder(`${sessionName}_${fileName}`)
1807
1861
 
1808
- this.debug(`${sessionName} - Screenshot is saving to ${outputFile}`);
1862
+ this.debug(`${sessionName} - Screenshot is saving to ${outputFile}`)
1809
1863
 
1810
1864
  if (browser) {
1811
- this.debug(`Screenshot of ${sessionName} session has been saved to ${outputFile}`);
1812
- return browser.saveScreenshot(outputFile);
1865
+ this.debug(`Screenshot of ${sessionName} session has been saved to ${outputFile}`)
1866
+ return browser.saveScreenshot(outputFile)
1813
1867
  }
1814
1868
  }
1815
1869
  }
1816
1870
 
1817
1871
  if (!fullPage) {
1818
- this.debug(`Screenshot has been saved to ${outputFile}`);
1819
- return this.browser.saveScreenshot(outputFile);
1872
+ this.debug(`Screenshot has been saved to ${outputFile}`)
1873
+ return this.browser.saveScreenshot(outputFile)
1820
1874
  }
1821
1875
 
1822
1876
  /* eslint-disable prefer-arrow-callback, comma-dangle, prefer-const */
1823
- const originalWindowSize = await this.browser.getWindowSize();
1877
+ const originalWindowSize = await this.browser.getWindowSize()
1824
1878
 
1825
- let { width, height } = await this.browser.execute(function () {
1826
- return {
1827
- height: document.body.scrollHeight,
1828
- width: document.body.scrollWidth
1829
- };
1830
- }).then(res => res);
1879
+ let { width, height } = await this.browser
1880
+ .execute(function () {
1881
+ return {
1882
+ height: document.body.scrollHeight,
1883
+ width: document.body.scrollWidth,
1884
+ }
1885
+ })
1886
+ .then((res) => res)
1831
1887
 
1832
- if (height < 100) height = 500; // errors for very small height
1888
+ if (height < 100) height = 500 // errors for very small height
1833
1889
  /* eslint-enable */
1834
1890
 
1835
- await this.browser.setWindowSize(width, height);
1836
- this.debug(`Screenshot has been saved to ${outputFile}, size: ${width}x${height}`);
1837
- const buffer = await this.browser.saveScreenshot(outputFile);
1838
- await this.browser.setWindowSize(originalWindowSize.width, originalWindowSize.height);
1839
- return buffer;
1891
+ await this.browser.setWindowSize(width, height)
1892
+ this.debug(`Screenshot has been saved to ${outputFile}, size: ${width}x${height}`)
1893
+ const buffer = await this.browser.saveScreenshot(outputFile)
1894
+ await this.browser.setWindowSize(originalWindowSize.width, originalWindowSize.height)
1895
+ return buffer
1840
1896
  }
1841
1897
 
1842
1898
  /**
@@ -1844,40 +1900,40 @@ class WebDriver extends Helper {
1844
1900
  * {{> setCookie }}
1845
1901
  */
1846
1902
  async setCookie(cookie) {
1847
- return this.browser.setCookies(cookie);
1903
+ return this.browser.setCookies(cookie)
1848
1904
  }
1849
1905
 
1850
1906
  /**
1851
1907
  * {{> clearCookie }}
1852
1908
  */
1853
1909
  async clearCookie(cookie) {
1854
- return this.browser.deleteCookies(cookie);
1910
+ return this.browser.deleteCookies(cookie)
1855
1911
  }
1856
1912
 
1857
1913
  /**
1858
1914
  * {{> seeCookie }}
1859
1915
  */
1860
1916
  async seeCookie(name) {
1861
- const cookie = await this.browser.getCookies([name]);
1862
- return truth(`cookie ${name}`, 'to be set').assert(cookie);
1917
+ const cookie = await this.browser.getCookies([name])
1918
+ return truth(`cookie ${name}`, 'to be set').assert(cookie)
1863
1919
  }
1864
1920
 
1865
1921
  /**
1866
1922
  * {{> dontSeeCookie }}
1867
1923
  */
1868
1924
  async dontSeeCookie(name) {
1869
- const cookie = await this.browser.getCookies([name]);
1870
- return truth(`cookie ${name}`, 'to be set').negate(cookie);
1925
+ const cookie = await this.browser.getCookies([name])
1926
+ return truth(`cookie ${name}`, 'to be set').negate(cookie)
1871
1927
  }
1872
1928
 
1873
1929
  /**
1874
1930
  * {{> grabCookie }}
1875
1931
  */
1876
1932
  async grabCookie(name) {
1877
- if (!name) return this.browser.getCookies();
1878
- const cookie = await this.browser.getCookies([name]);
1879
- this.debugSection('Cookie', JSON.stringify(cookie));
1880
- return cookie[0];
1933
+ if (!name) return this.browser.getCookies()
1934
+ const cookie = await this.browser.getCookies([name])
1935
+ this.debugSection('Cookie', JSON.stringify(cookie))
1936
+ return cookie[0]
1881
1937
  }
1882
1938
 
1883
1939
  /**
@@ -1885,30 +1941,33 @@ class WebDriver extends Helper {
1885
1941
  */
1886
1942
  async waitForCookie(name, sec) {
1887
1943
  // by default, we will retry 3 times
1888
- let retries = 3;
1889
- const waitTimeout = sec || this.options.waitForTimeoutInSeconds;
1944
+ let retries = 3
1945
+ const waitTimeout = sec || this.options.waitForTimeoutInSeconds
1890
1946
 
1891
1947
  if (sec) {
1892
- retries = sec;
1948
+ retries = sec
1893
1949
  } else {
1894
- retries = waitTimeout - 1;
1950
+ retries = waitTimeout - 1
1895
1951
  }
1896
1952
 
1897
- return promiseRetry(async (retry, number) => {
1898
- const _grabCookie = async (name) => {
1899
- const cookie = await this.browser.getCookies([name]);
1900
- if (cookie.length === 0) throw Error(`Cookie ${name} is not found after ${retries}s`);
1901
- };
1953
+ return promiseRetry(
1954
+ async (retry, number) => {
1955
+ const _grabCookie = async (name) => {
1956
+ const cookie = await this.browser.getCookies([name])
1957
+ if (cookie.length === 0) throw Error(`Cookie ${name} is not found after ${retries}s`)
1958
+ }
1902
1959
 
1903
- this.debugSection('Wait for cookie: ', name);
1904
- if (number > 1) this.debugSection('Retrying... Attempt #', number);
1960
+ this.debugSection('Wait for cookie: ', name)
1961
+ if (number > 1) this.debugSection('Retrying... Attempt #', number)
1905
1962
 
1906
- try {
1907
- await _grabCookie(name);
1908
- } catch (e) {
1909
- retry(e);
1910
- }
1911
- }, { retries, maxTimeout: 1000 });
1963
+ try {
1964
+ await _grabCookie(name)
1965
+ } catch (e) {
1966
+ retry(e)
1967
+ }
1968
+ },
1969
+ { retries, maxTimeout: 1000 },
1970
+ )
1912
1971
  }
1913
1972
 
1914
1973
  /**
@@ -1919,9 +1978,9 @@ class WebDriver extends Helper {
1919
1978
  async acceptPopup() {
1920
1979
  return this.browser.getAlertText().then((res) => {
1921
1980
  if (res !== null) {
1922
- return this.browser.acceptAlert();
1981
+ return this.browser.acceptAlert()
1923
1982
  }
1924
- });
1983
+ })
1925
1984
  }
1926
1985
 
1927
1986
  /**
@@ -1931,9 +1990,9 @@ class WebDriver extends Helper {
1931
1990
  async cancelPopup() {
1932
1991
  return this.browser.getAlertText().then((res) => {
1933
1992
  if (res !== null) {
1934
- return this.browser.dismissAlert();
1993
+ return this.browser.dismissAlert()
1935
1994
  }
1936
- });
1995
+ })
1937
1996
  }
1938
1997
 
1939
1998
  /**
@@ -1945,10 +2004,10 @@ class WebDriver extends Helper {
1945
2004
  async seeInPopup(text) {
1946
2005
  return this.browser.getAlertText().then((res) => {
1947
2006
  if (res === null) {
1948
- throw new Error('Popup is not opened');
2007
+ throw new Error('Popup is not opened')
1949
2008
  }
1950
- stringIncludes('text in popup').assert(text, res);
1951
- });
2009
+ stringIncludes('text in popup').assert(text, res)
2010
+ })
1952
2011
  }
1953
2012
 
1954
2013
  /**
@@ -1956,9 +2015,9 @@ class WebDriver extends Helper {
1956
2015
  */
1957
2016
  async grabPopupText() {
1958
2017
  try {
1959
- return await this.browser.getAlertText();
2018
+ return await this.browser.getAlertText()
1960
2019
  } catch (err) {
1961
- this.debugSection('Popup', 'Error getting text from popup');
2020
+ this.debugSection('Popup', 'Error getting text from popup')
1962
2021
  }
1963
2022
  }
1964
2023
 
@@ -1966,36 +2025,44 @@ class WebDriver extends Helper {
1966
2025
  * {{> pressKeyDown }}
1967
2026
  */
1968
2027
  async pressKeyDown(key) {
1969
- key = getNormalizedKey.call(this, key);
2028
+ key = getNormalizedKey.call(this, key)
1970
2029
  if (!this.browser.isW3C) {
1971
- return this.browser.sendKeys([key]);
2030
+ return this.browser.sendKeys([key])
1972
2031
  }
1973
- return this.browser.performActions([{
1974
- type: 'key',
1975
- id: 'keyboard',
1976
- actions: [{
1977
- type: 'keyDown',
1978
- value: key,
1979
- }],
1980
- }]);
2032
+ return this.browser.performActions([
2033
+ {
2034
+ type: 'key',
2035
+ id: 'keyboard',
2036
+ actions: [
2037
+ {
2038
+ type: 'keyDown',
2039
+ value: key,
2040
+ },
2041
+ ],
2042
+ },
2043
+ ])
1981
2044
  }
1982
2045
 
1983
2046
  /**
1984
2047
  * {{> pressKeyUp }}
1985
2048
  */
1986
2049
  async pressKeyUp(key) {
1987
- key = getNormalizedKey.call(this, key);
2050
+ key = getNormalizedKey.call(this, key)
1988
2051
  if (!this.browser.isW3C) {
1989
- return this.browser.sendKeys([key]);
2052
+ return this.browser.sendKeys([key])
1990
2053
  }
1991
- return this.browser.performActions([{
1992
- type: 'key',
1993
- id: 'keyboard',
1994
- actions: [{
1995
- type: 'keyUp',
1996
- value: key,
1997
- }],
1998
- }]);
2054
+ return this.browser.performActions([
2055
+ {
2056
+ type: 'key',
2057
+ id: 'keyboard',
2058
+ actions: [
2059
+ {
2060
+ type: 'keyUp',
2061
+ value: key,
2062
+ },
2063
+ ],
2064
+ },
2065
+ ])
1999
2066
  }
2000
2067
 
2001
2068
  /**
@@ -2004,40 +2071,45 @@ class WebDriver extends Helper {
2004
2071
  * {{> pressKeyWithKeyNormalization }}
2005
2072
  */
2006
2073
  async pressKey(key) {
2007
- const modifiers = [];
2074
+ const modifiers = []
2008
2075
  if (Array.isArray(key)) {
2009
2076
  for (let k of key) {
2010
- k = getNormalizedKey.call(this, k);
2077
+ k = getNormalizedKey.call(this, k)
2011
2078
  if (isModifierKey(k)) {
2012
- modifiers.push(k);
2079
+ modifiers.push(k)
2013
2080
  } else {
2014
- key = k;
2015
- break;
2081
+ key = k
2082
+ break
2016
2083
  }
2017
2084
  }
2018
2085
  } else {
2019
- key = getNormalizedKey.call(this, key);
2086
+ key = getNormalizedKey.call(this, key)
2020
2087
  }
2021
2088
  for (const modifier of modifiers) {
2022
- await this.pressKeyDown(modifier);
2089
+ await this.pressKeyDown(modifier)
2023
2090
  }
2024
2091
  if (!this.browser.isW3C) {
2025
- await this.browser.sendKeys([key]);
2092
+ await this.browser.sendKeys([key])
2026
2093
  } else {
2027
- await this.browser.performActions([{
2028
- type: 'key',
2029
- id: 'keyboard',
2030
- actions: [{
2031
- type: 'keyDown',
2032
- value: key,
2033
- }, {
2034
- type: 'keyUp',
2035
- value: key,
2036
- }],
2037
- }]);
2094
+ await this.browser.performActions([
2095
+ {
2096
+ type: 'key',
2097
+ id: 'keyboard',
2098
+ actions: [
2099
+ {
2100
+ type: 'keyDown',
2101
+ value: key,
2102
+ },
2103
+ {
2104
+ type: 'keyUp',
2105
+ value: key,
2106
+ },
2107
+ ],
2108
+ },
2109
+ ])
2038
2110
  }
2039
2111
  for (const modifier of modifiers) {
2040
- await this.pressKeyUp(modifier);
2112
+ await this.pressKeyUp(modifier)
2041
2113
  }
2042
2114
  }
2043
2115
 
@@ -2046,17 +2118,17 @@ class WebDriver extends Helper {
2046
2118
  */
2047
2119
  async type(keys, delay = null) {
2048
2120
  if (!Array.isArray(keys)) {
2049
- keys = keys.toString();
2050
- keys = keys.split('');
2121
+ keys = keys.toString()
2122
+ keys = keys.split('')
2051
2123
  }
2052
2124
  if (delay) {
2053
2125
  for (const key of keys) {
2054
- await this.browser.keys(key);
2055
- await this.wait(delay / 1000);
2126
+ await this.browser.keys(key)
2127
+ await this.wait(delay / 1000)
2056
2128
  }
2057
- return;
2129
+ return
2058
2130
  }
2059
- await this.browser.keys(keys);
2131
+ await this.browser.keys(keys)
2060
2132
  }
2061
2133
 
2062
2134
  /**
@@ -2065,27 +2137,27 @@ class WebDriver extends Helper {
2065
2137
  * {{> resizeWindow }}
2066
2138
  */
2067
2139
  async resizeWindow(width, height) {
2068
- return this.browser.setWindowSize(width, height);
2140
+ return this.browser.setWindowSize(width, height)
2069
2141
  }
2070
2142
 
2071
2143
  async _resizeBrowserWindow(browser, width, height) {
2072
2144
  if (width === 'maximize') {
2073
- const size = await browser.maximizeWindow();
2074
- this.debugSection('Window Size', size);
2075
- return;
2145
+ const size = await browser.maximizeWindow()
2146
+ this.debugSection('Window Size', size)
2147
+ return
2076
2148
  }
2077
2149
  if (browser.isW3C) {
2078
- return browser.setWindowRect(null, null, parseInt(width, 10), parseInt(height, 10));
2150
+ return browser.setWindowRect(null, null, parseInt(width, 10), parseInt(height, 10))
2079
2151
  }
2080
- return browser.setWindowSize(parseInt(width, 10), parseInt(height, 10));
2152
+ return browser.setWindowSize(parseInt(width, 10), parseInt(height, 10))
2081
2153
  }
2082
2154
 
2083
2155
  async _resizeWindowIfNeeded(browser, windowSize) {
2084
2156
  if (this.isWeb && windowSize === 'maximize') {
2085
- await this._resizeBrowserWindow(browser, 'maximize');
2157
+ await this._resizeBrowserWindow(browser, 'maximize')
2086
2158
  } else if (this.isWeb && windowSize && windowSize.indexOf('x') > 0) {
2087
- const dimensions = windowSize.split('x');
2088
- await this._resizeBrowserWindow(browser, dimensions[0], dimensions[1]);
2159
+ const dimensions = windowSize.split('x')
2160
+ await this._resizeBrowserWindow(browser, dimensions[0], dimensions[1])
2089
2161
  }
2090
2162
  }
2091
2163
 
@@ -2094,11 +2166,11 @@ class WebDriver extends Helper {
2094
2166
  *
2095
2167
  */
2096
2168
  async focus(locator) {
2097
- const els = await this._locate(locator);
2098
- assertElementExists(els, locator, 'Element to focus');
2099
- const el = usingFirstElement(els);
2169
+ const els = await this._locate(locator)
2170
+ assertElementExists(els, locator, 'Element to focus')
2171
+ const el = usingFirstElement(els)
2100
2172
 
2101
- await focusElement(el, this.browser);
2173
+ await focusElement(el, this.browser)
2102
2174
  }
2103
2175
 
2104
2176
  /**
@@ -2106,11 +2178,11 @@ class WebDriver extends Helper {
2106
2178
  *
2107
2179
  */
2108
2180
  async blur(locator) {
2109
- const els = await this._locate(locator);
2110
- assertElementExists(els, locator, 'Element to blur');
2111
- const el = usingFirstElement(els);
2181
+ const els = await this._locate(locator)
2182
+ assertElementExists(els, locator, 'Element to blur')
2183
+ const el = usingFirstElement(els)
2112
2184
 
2113
- await blurElement(el, this.browser);
2185
+ await blurElement(el, this.browser)
2114
2186
  }
2115
2187
 
2116
2188
  /**
@@ -2118,64 +2190,73 @@ class WebDriver extends Helper {
2118
2190
  * {{> dragAndDrop }}
2119
2191
  */
2120
2192
  async dragAndDrop(srcElement, destElement) {
2121
- let sourceEl = await this._locate(srcElement);
2122
- assertElementExists(sourceEl, srcElement);
2123
- sourceEl = usingFirstElement(sourceEl);
2193
+ let sourceEl = await this._locate(srcElement)
2194
+ assertElementExists(sourceEl, srcElement)
2195
+ sourceEl = usingFirstElement(sourceEl)
2124
2196
 
2125
- let destEl = await this._locate(destElement);
2126
- assertElementExists(destEl, destElement);
2127
- destEl = usingFirstElement(destEl);
2197
+ let destEl = await this._locate(destElement)
2198
+ assertElementExists(destEl, destElement)
2199
+ destEl = usingFirstElement(destEl)
2128
2200
 
2129
- return sourceEl.dragAndDrop(destEl);
2201
+ return sourceEl.dragAndDrop(destEl)
2130
2202
  }
2131
2203
 
2132
2204
  /**
2133
2205
  * {{> dragSlider }}
2134
2206
  */
2135
2207
  async dragSlider(locator, offsetX = 0) {
2136
- const browser = this.browser;
2137
- await this.moveCursorTo(locator);
2208
+ const browser = this.browser
2209
+ await this.moveCursorTo(locator)
2138
2210
 
2139
2211
  // for chrome
2140
2212
  if (browser.isW3C) {
2141
- const xOffset = await this.grabElementBoundingRect(locator, 'x');
2142
- const yOffset = await this.grabElementBoundingRect(locator, 'y');
2143
-
2144
- return browser.performActions([{
2145
- type: 'pointer',
2146
- id: 'pointer1',
2147
- parameters: { pointerType: 'mouse' },
2148
- actions: [
2149
- {
2150
- type: 'pointerMove', origin: 'pointer', duration: 1000, x: xOffset, y: yOffset,
2151
- },
2152
- { type: 'pointerDown', button: 0 },
2153
- {
2154
- type: 'pointerMove', origin: 'pointer', duration: 1000, x: offsetX, y: 0,
2155
- },
2156
- { type: 'pointerUp', button: 0 },
2157
- ],
2158
- },
2159
- ]);
2160
- }
2161
-
2162
- await browser.buttonDown(0);
2163
- await browser.moveToElement(null, offsetX, 0);
2164
- await browser.buttonUp(0);
2213
+ const xOffset = await this.grabElementBoundingRect(locator, 'x')
2214
+ const yOffset = await this.grabElementBoundingRect(locator, 'y')
2215
+
2216
+ return browser.performActions([
2217
+ {
2218
+ type: 'pointer',
2219
+ id: 'pointer1',
2220
+ parameters: { pointerType: 'mouse' },
2221
+ actions: [
2222
+ {
2223
+ type: 'pointerMove',
2224
+ origin: 'pointer',
2225
+ duration: 1000,
2226
+ x: xOffset,
2227
+ y: yOffset,
2228
+ },
2229
+ { type: 'pointerDown', button: 0 },
2230
+ {
2231
+ type: 'pointerMove',
2232
+ origin: 'pointer',
2233
+ duration: 1000,
2234
+ x: offsetX,
2235
+ y: 0,
2236
+ },
2237
+ { type: 'pointerUp', button: 0 },
2238
+ ],
2239
+ },
2240
+ ])
2241
+ }
2242
+
2243
+ await browser.buttonDown(0)
2244
+ await browser.moveToElement(null, offsetX, 0)
2245
+ await browser.buttonUp(0)
2165
2246
  }
2166
2247
 
2167
2248
  /**
2168
2249
  * {{> grabAllWindowHandles }}
2169
2250
  */
2170
2251
  async grabAllWindowHandles() {
2171
- return this.browser.getWindowHandles();
2252
+ return this.browser.getWindowHandles()
2172
2253
  }
2173
2254
 
2174
2255
  /**
2175
2256
  * {{> grabCurrentWindowHandle }}
2176
2257
  */
2177
2258
  async grabCurrentWindowHandle() {
2178
- return this.browser.getWindowHandle();
2259
+ return this.browser.getWindowHandle()
2179
2260
  }
2180
2261
 
2181
2262
  /**
@@ -2193,125 +2274,140 @@ class WebDriver extends Helper {
2193
2274
  * @param {string} window name of window handle.
2194
2275
  */
2195
2276
  async switchToWindow(window) {
2196
- await this.browser.switchToWindow(window);
2277
+ await this.browser.switchToWindow(window)
2197
2278
  }
2198
2279
 
2199
2280
  /**
2200
2281
  * {{> closeOtherTabs }}
2201
2282
  */
2202
2283
  async closeOtherTabs() {
2203
- const handles = await this.browser.getWindowHandles();
2204
- const currentHandle = await this.browser.getWindowHandle();
2205
- const otherHandles = handles.filter(handle => handle !== currentHandle);
2284
+ const handles = await this.browser.getWindowHandles()
2285
+ const currentHandle = await this.browser.getWindowHandle()
2286
+ const otherHandles = handles.filter((handle) => handle !== currentHandle)
2206
2287
 
2207
2288
  await forEachAsync(otherHandles, async (handle) => {
2208
- await this.browser.switchToWindow(handle);
2209
- await this.browser.closeWindow();
2210
- });
2211
- await this.browser.switchToWindow(currentHandle);
2289
+ await this.browser.switchToWindow(handle)
2290
+ await this.browser.closeWindow()
2291
+ })
2292
+ await this.browser.switchToWindow(currentHandle)
2212
2293
  }
2213
2294
 
2214
2295
  /**
2215
2296
  * {{> wait }}
2216
2297
  */
2217
2298
  async wait(sec) {
2218
- return new Promise(resolve => {
2219
- setTimeout(resolve, sec * 1000);
2220
- });
2299
+ return new Promise((resolve) => {
2300
+ setTimeout(resolve, sec * 1000)
2301
+ })
2221
2302
  }
2222
2303
 
2223
2304
  /**
2224
2305
  * {{> waitForEnabled }}
2225
2306
  */
2226
2307
  async waitForEnabled(locator, sec = null) {
2227
- const aSec = sec || this.options.waitForTimeoutInSeconds;
2308
+ const aSec = sec || this.options.waitForTimeoutInSeconds
2228
2309
 
2229
- return this.browser.waitUntil(async () => {
2230
- const res = await this._res(locator);
2231
- if (!res || res.length === 0) {
2232
- return false;
2233
- }
2234
- const selected = await forEachAsync(res, async el => this.browser.isElementEnabled(getElementId(el)));
2235
- if (Array.isArray(selected)) {
2236
- return selected.filter(val => val === true).length > 0;
2237
- }
2238
- return selected;
2239
- }, {
2240
- timeout: aSec * 1000,
2241
- timeoutMsg: `element (${new Locator(locator)}) still not enabled after ${aSec} sec`,
2242
- });
2310
+ return this.browser.waitUntil(
2311
+ async () => {
2312
+ const res = await this._res(locator)
2313
+ if (!res || res.length === 0) {
2314
+ return false
2315
+ }
2316
+ const selected = await forEachAsync(res, async (el) => this.browser.isElementEnabled(getElementId(el)))
2317
+ if (Array.isArray(selected)) {
2318
+ return selected.filter((val) => val === true).length > 0
2319
+ }
2320
+ return selected
2321
+ },
2322
+ {
2323
+ timeout: aSec * 1000,
2324
+ timeoutMsg: `element (${new Locator(locator)}) still not enabled after ${aSec} sec`,
2325
+ },
2326
+ )
2243
2327
  }
2244
2328
 
2245
2329
  /**
2246
2330
  * {{> waitForElement }}
2247
2331
  */
2248
2332
  async waitForElement(locator, sec = null) {
2249
- const aSec = sec || this.options.waitForTimeoutInSeconds;
2333
+ const aSec = sec || this.options.waitForTimeoutInSeconds
2250
2334
 
2251
- return this.browser.waitUntil(async () => {
2252
- const res = await this._res(locator);
2253
- return res && res.length;
2254
- }, { timeout: aSec * 1000, timeoutMsg: `element (${(new Locator(locator))}) still not present on page after ${aSec} sec` });
2335
+ return this.browser.waitUntil(
2336
+ async () => {
2337
+ const res = await this._res(locator)
2338
+ return res && res.length
2339
+ },
2340
+ {
2341
+ timeout: aSec * 1000,
2342
+ timeoutMsg: `element (${new Locator(locator)}) still not present on page after ${aSec} sec`,
2343
+ },
2344
+ )
2255
2345
  }
2256
2346
 
2257
2347
  /**
2258
2348
  * {{> waitForClickable }}
2259
2349
  */
2260
2350
  async waitForClickable(locator, waitTimeout) {
2261
- waitTimeout = waitTimeout || this.options.waitForTimeoutInSeconds;
2262
- let res = await this._locate(locator);
2263
- res = usingFirstElement(res);
2264
- assertElementExists(res, locator);
2351
+ waitTimeout = waitTimeout || this.options.waitForTimeoutInSeconds
2352
+ let res = await this._locate(locator)
2353
+ res = usingFirstElement(res)
2354
+ assertElementExists(res, locator)
2265
2355
 
2266
2356
  return res.waitForClickable({
2267
2357
  timeout: waitTimeout * 1000,
2268
2358
  timeoutMsg: `element ${res.selector} still not clickable after ${waitTimeout} sec`,
2269
- });
2359
+ })
2270
2360
  }
2271
2361
 
2272
2362
  /**
2273
2363
  * {{> waitInUrl }}
2274
2364
  */
2275
2365
  async waitInUrl(urlPart, sec = null) {
2276
- const client = this.browser;
2277
- const aSec = sec || this.options.waitForTimeoutInSeconds;
2278
- let currUrl = '';
2366
+ const client = this.browser
2367
+ const aSec = sec || this.options.waitForTimeoutInSeconds
2368
+ let currUrl = ''
2279
2369
 
2280
2370
  return client
2281
- .waitUntil(function () {
2282
- return this.getUrl().then((res) => {
2283
- currUrl = decodeUrl(res);
2284
- return currUrl.indexOf(urlPart) > -1;
2285
- });
2286
- }, { timeout: aSec * 1000 }).catch((e) => {
2371
+ .waitUntil(
2372
+ function () {
2373
+ return this.getUrl().then((res) => {
2374
+ currUrl = decodeUrl(res)
2375
+ return currUrl.indexOf(urlPart) > -1
2376
+ })
2377
+ },
2378
+ { timeout: aSec * 1000 },
2379
+ )
2380
+ .catch((e) => {
2287
2381
  if (e.message.indexOf('timeout')) {
2288
- throw new Error(`expected url to include ${urlPart}, but found ${currUrl}`);
2382
+ throw new Error(`expected url to include ${urlPart}, but found ${currUrl}`)
2289
2383
  }
2290
- throw e;
2291
- });
2384
+ throw e
2385
+ })
2292
2386
  }
2293
2387
 
2294
2388
  /**
2295
2389
  * {{> waitUrlEquals }}
2296
2390
  */
2297
2391
  async waitUrlEquals(urlPart, sec = null) {
2298
- const aSec = sec || this.options.waitForTimeoutInSeconds;
2299
- const baseUrl = this.options.url;
2392
+ const aSec = sec || this.options.waitForTimeoutInSeconds
2393
+ const baseUrl = this.options.url
2300
2394
  if (urlPart.indexOf('http') < 0) {
2301
- urlPart = baseUrl + urlPart;
2302
- }
2303
- let currUrl = '';
2304
- return this.browser.waitUntil(function () {
2305
- return this.getUrl().then((res) => {
2306
- currUrl = decodeUrl(res);
2307
- return currUrl === urlPart;
2308
- });
2309
- }, aSec * 1000).catch((e) => {
2310
- if (e.message.indexOf('timeout')) {
2311
- throw new Error(`expected url to be ${urlPart}, but found ${currUrl}`);
2312
- }
2313
- throw e;
2314
- });
2395
+ urlPart = baseUrl + urlPart
2396
+ }
2397
+ let currUrl = ''
2398
+ return this.browser
2399
+ .waitUntil(function () {
2400
+ return this.getUrl().then((res) => {
2401
+ currUrl = decodeUrl(res)
2402
+ return currUrl === urlPart
2403
+ })
2404
+ }, aSec * 1000)
2405
+ .catch((e) => {
2406
+ if (e.message.indexOf('timeout')) {
2407
+ throw new Error(`expected url to be ${urlPart}, but found ${currUrl}`)
2408
+ }
2409
+ throw e
2410
+ })
2315
2411
  }
2316
2412
 
2317
2413
  /**
@@ -2319,42 +2415,48 @@ class WebDriver extends Helper {
2319
2415
  *
2320
2416
  */
2321
2417
  async waitForText(text, sec = null, context = null) {
2322
- const aSec = sec || this.options.waitForTimeoutInSeconds;
2323
- const _context = context || this.root;
2324
-
2325
- return this.browser.waitUntil(async () => {
2326
- const res = await this.$$(withStrictLocator.call(this, _context));
2327
- if (!res || res.length === 0) return false;
2328
- const selected = await forEachAsync(res, async el => this.browser.getElementText(getElementId(el)));
2329
- if (Array.isArray(selected)) {
2330
- return selected.filter(part => part.indexOf(text) >= 0).length > 0;
2331
- }
2332
- return selected.indexOf(text) >= 0;
2333
- }, {
2334
- timeout: aSec * 1000,
2335
- timeoutMsg: `element (${_context}) is not in DOM or there is no element(${_context}) with text "${text}" after ${aSec} sec`,
2336
- });
2418
+ const aSec = sec || this.options.waitForTimeoutInSeconds
2419
+ const _context = context || this.root
2420
+
2421
+ return this.browser.waitUntil(
2422
+ async () => {
2423
+ const res = await this.$$(withStrictLocator.call(this, _context))
2424
+ if (!res || res.length === 0) return false
2425
+ const selected = await forEachAsync(res, async (el) => this.browser.getElementText(getElementId(el)))
2426
+ if (Array.isArray(selected)) {
2427
+ return selected.filter((part) => part.indexOf(text) >= 0).length > 0
2428
+ }
2429
+ return selected.indexOf(text) >= 0
2430
+ },
2431
+ {
2432
+ timeout: aSec * 1000,
2433
+ timeoutMsg: `element (${_context}) is not in DOM or there is no element(${_context}) with text "${text}" after ${aSec} sec`,
2434
+ },
2435
+ )
2337
2436
  }
2338
2437
 
2339
2438
  /**
2340
2439
  * {{> waitForValue }}
2341
2440
  */
2342
2441
  async waitForValue(field, value, sec = null) {
2343
- const client = this.browser;
2344
- const aSec = sec || this.options.waitForTimeoutInSeconds;
2345
-
2346
- return client.waitUntil(async () => {
2347
- const res = await findFields.call(this, field);
2348
- if (!res || res.length === 0) return false;
2349
- const selected = await forEachAsync(res, async el => el.getValue());
2350
- if (Array.isArray(selected)) {
2351
- return selected.filter(part => part.indexOf(value) >= 0).length > 0;
2352
- }
2353
- return selected.indexOf(value) >= 0;
2354
- }, {
2355
- timeout: aSec * 1000,
2356
- timeoutMsg: `element (${field}) is not in DOM or there is no element(${field}) with value "${value}" after ${aSec} sec`,
2357
- });
2442
+ const client = this.browser
2443
+ const aSec = sec || this.options.waitForTimeoutInSeconds
2444
+
2445
+ return client.waitUntil(
2446
+ async () => {
2447
+ const res = await findFields.call(this, field)
2448
+ if (!res || res.length === 0) return false
2449
+ const selected = await forEachAsync(res, async (el) => el.getValue())
2450
+ if (Array.isArray(selected)) {
2451
+ return selected.filter((part) => part.indexOf(value) >= 0).length > 0
2452
+ }
2453
+ return selected.indexOf(value) >= 0
2454
+ },
2455
+ {
2456
+ timeout: aSec * 1000,
2457
+ timeoutMsg: `element (${field}) is not in DOM or there is no element(${field}) with value "${value}" after ${aSec} sec`,
2458
+ },
2459
+ )
2358
2460
  }
2359
2461
 
2360
2462
  /**
@@ -2362,214 +2464,241 @@ class WebDriver extends Helper {
2362
2464
  *
2363
2465
  */
2364
2466
  async waitForVisible(locator, sec = null) {
2365
- const aSec = sec || this.options.waitForTimeoutInSeconds;
2366
-
2367
- return this.browser.waitUntil(async () => {
2368
- const res = await this._res(locator);
2369
- if (!res || res.length === 0) return false;
2370
- const selected = await forEachAsync(res, async el => el.isDisplayed());
2371
- if (Array.isArray(selected)) {
2372
- return selected.filter(val => val === true).length > 0;
2373
- }
2374
- return selected;
2375
- }, { timeout: aSec * 1000, timeoutMsg: `element (${new Locator(locator)}) still not visible after ${aSec} sec` });
2467
+ const aSec = sec || this.options.waitForTimeoutInSeconds
2468
+
2469
+ return this.browser.waitUntil(
2470
+ async () => {
2471
+ const res = await this._res(locator)
2472
+ if (!res || res.length === 0) return false
2473
+ const selected = await forEachAsync(res, async (el) => el.isDisplayed())
2474
+ if (Array.isArray(selected)) {
2475
+ return selected.filter((val) => val === true).length > 0
2476
+ }
2477
+ return selected
2478
+ },
2479
+ {
2480
+ timeout: aSec * 1000,
2481
+ timeoutMsg: `element (${new Locator(locator)}) still not visible after ${aSec} sec`,
2482
+ },
2483
+ )
2376
2484
  }
2377
2485
 
2378
2486
  /**
2379
2487
  * {{> waitNumberOfVisibleElements }}
2380
2488
  */
2381
2489
  async waitNumberOfVisibleElements(locator, num, sec = null) {
2382
- const aSec = sec || this.options.waitForTimeoutInSeconds;
2490
+ const aSec = sec || this.options.waitForTimeoutInSeconds
2383
2491
 
2384
- return this.browser.waitUntil(async () => {
2385
- const res = await this._res(locator);
2386
- if (!res || res.length === 0) return false;
2387
- let selected = await forEachAsync(res, async el => el.isDisplayed());
2492
+ return this.browser.waitUntil(
2493
+ async () => {
2494
+ const res = await this._res(locator)
2495
+ if (!res || res.length === 0) return false
2496
+ let selected = await forEachAsync(res, async (el) => el.isDisplayed())
2388
2497
 
2389
- if (!Array.isArray(selected)) selected = [selected];
2390
- selected = selected.filter(val => val === true);
2391
- return selected.length === num;
2392
- }, { timeout: aSec * 1000, timeoutMsg: `The number of elements (${new Locator(locator)}) is not ${num} after ${aSec} sec` });
2498
+ if (!Array.isArray(selected)) selected = [selected]
2499
+ selected = selected.filter((val) => val === true)
2500
+ return selected.length === num
2501
+ },
2502
+ {
2503
+ timeout: aSec * 1000,
2504
+ timeoutMsg: `The number of elements (${new Locator(locator)}) is not ${num} after ${aSec} sec`,
2505
+ },
2506
+ )
2393
2507
  }
2394
2508
 
2395
2509
  /**
2396
2510
  * {{> waitForInvisible }}
2397
2511
  */
2398
2512
  async waitForInvisible(locator, sec = null) {
2399
- const aSec = sec || this.options.waitForTimeoutInSeconds;
2400
-
2401
- return this.browser.waitUntil(async () => {
2402
- const res = await this._res(locator);
2403
- if (!res || res.length === 0) return true;
2404
- const selected = await forEachAsync(res, async el => el.isDisplayed());
2405
- return !selected.length;
2406
- }, { timeout: aSec * 1000, timeoutMsg: `element (${new Locator(locator)}) still visible after ${aSec} sec` });
2513
+ const aSec = sec || this.options.waitForTimeoutInSeconds
2514
+
2515
+ return this.browser.waitUntil(
2516
+ async () => {
2517
+ const res = await this._res(locator)
2518
+ if (!res || res.length === 0) return true
2519
+ const selected = await forEachAsync(res, async (el) => el.isDisplayed())
2520
+ return !selected.length
2521
+ },
2522
+ { timeout: aSec * 1000, timeoutMsg: `element (${new Locator(locator)}) still visible after ${aSec} sec` },
2523
+ )
2407
2524
  }
2408
2525
 
2409
2526
  /**
2410
2527
  * {{> waitToHide }}
2411
2528
  */
2412
2529
  async waitToHide(locator, sec = null) {
2413
- return this.waitForInvisible(locator, sec);
2530
+ return this.waitForInvisible(locator, sec)
2414
2531
  }
2415
2532
 
2416
2533
  /**
2417
2534
  * {{> waitForDetached }}
2418
2535
  */
2419
2536
  async waitForDetached(locator, sec = null) {
2420
- const aSec = sec || this.options.waitForTimeoutInSeconds;
2537
+ const aSec = sec || this.options.waitForTimeoutInSeconds
2421
2538
 
2422
- return this.browser.waitUntil(async () => {
2423
- const res = await this._res(locator);
2424
- if (!res || res.length === 0) {
2425
- return true;
2426
- }
2427
- return false;
2428
- }, { timeout: aSec * 1000, timeoutMsg: `element (${new Locator(locator)}) still on page after ${aSec} sec` });
2539
+ return this.browser.waitUntil(
2540
+ async () => {
2541
+ const res = await this._res(locator)
2542
+ if (!res || res.length === 0) {
2543
+ return true
2544
+ }
2545
+ return false
2546
+ },
2547
+ { timeout: aSec * 1000, timeoutMsg: `element (${new Locator(locator)}) still on page after ${aSec} sec` },
2548
+ )
2429
2549
  }
2430
2550
 
2431
2551
  /**
2432
2552
  * {{> waitForFunction }}
2433
2553
  */
2434
2554
  async waitForFunction(fn, argsOrSec = null, sec = null) {
2435
- let args = [];
2555
+ let args = []
2436
2556
  if (argsOrSec) {
2437
2557
  if (Array.isArray(argsOrSec)) {
2438
- args = argsOrSec;
2558
+ args = argsOrSec
2439
2559
  } else if (typeof argsOrSec === 'number') {
2440
- sec = argsOrSec;
2560
+ sec = argsOrSec
2441
2561
  }
2442
2562
  }
2443
2563
 
2444
- const aSec = sec || this.options.waitForTimeoutInSeconds;
2564
+ const aSec = sec || this.options.waitForTimeoutInSeconds
2445
2565
 
2446
- return this.browser.waitUntil(async () => this.browser.execute(fn, ...args), { timeout: aSec * 1000, timeoutMsg: '' });
2566
+ return this.browser.waitUntil(async () => this.browser.execute(fn, ...args), {
2567
+ timeout: aSec * 1000,
2568
+ timeoutMsg: '',
2569
+ })
2447
2570
  }
2448
2571
 
2449
2572
  /**
2450
2573
  * {{> waitForNumberOfTabs }}
2451
2574
  */
2452
2575
  async waitForNumberOfTabs(expectedTabs, sec) {
2453
- const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeoutInSeconds;
2454
- let currentTabs;
2455
- let count = 0;
2576
+ const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeoutInSeconds
2577
+ let currentTabs
2578
+ let count = 0
2456
2579
 
2457
2580
  do {
2458
- currentTabs = await this.grabNumberOfOpenTabs();
2459
- await this.wait(1);
2460
- count += 1000;
2461
- if (currentTabs >= expectedTabs) return;
2462
- } while (count <= waitTimeout);
2581
+ currentTabs = await this.grabNumberOfOpenTabs()
2582
+ await this.wait(1)
2583
+ count += 1000
2584
+ if (currentTabs >= expectedTabs) return
2585
+ } while (count <= waitTimeout)
2463
2586
 
2464
- throw new Error(`Expected ${expectedTabs} tabs are not met after ${waitTimeout / 1000} sec.`);
2587
+ throw new Error(`Expected ${expectedTabs} tabs are not met after ${waitTimeout / 1000} sec.`)
2465
2588
  }
2466
2589
 
2467
2590
  /**
2468
2591
  * {{> switchTo }}
2469
2592
  */
2470
2593
  async switchTo(locator) {
2471
- this.browser.isInsideFrame = true;
2594
+ this.browser.isInsideFrame = true
2472
2595
  if (Number.isInteger(locator)) {
2473
2596
  if (this.options.automationProtocol) {
2474
- return this.browser.switchToFrame(locator + 1);
2597
+ return this.browser.switchToFrame(locator + 1)
2475
2598
  }
2476
- return this.browser.switchToFrame(locator);
2599
+ return this.browser.switchToFrame(locator)
2477
2600
  }
2478
2601
  if (!locator) {
2479
- return this.browser.switchToFrame(null);
2602
+ return this.browser.switchToFrame(null)
2480
2603
  }
2481
2604
 
2482
- let res = await this._locate(locator, true);
2483
- assertElementExists(res, locator);
2484
- res = usingFirstElement(res);
2485
- return this.browser.switchToFrame(res);
2605
+ let res = await this._locate(locator, true)
2606
+ assertElementExists(res, locator)
2607
+ res = usingFirstElement(res)
2608
+ return this.browser.switchToFrame(res)
2486
2609
  }
2487
2610
 
2488
2611
  /**
2489
2612
  * {{> switchToNextTab }}
2490
2613
  */
2491
2614
  async switchToNextTab(num = 1, sec = null) {
2492
- const aSec = sec || this.options.waitForTimeoutInSeconds;
2493
- let target;
2494
- const current = await this.browser.getWindowHandle();
2495
-
2496
- await this.browser.waitUntil(async () => {
2497
- await this.browser.getWindowHandles().then((handles) => {
2498
- if (handles.indexOf(current) + num + 1 <= handles.length) {
2499
- target = handles[handles.indexOf(current) + num];
2500
- }
2501
- });
2502
- return target;
2503
- }, { timeout: aSec * 1000, timeoutMsg: `There is no ability to switch to next tab with offset ${num}` });
2504
- return this.browser.switchToWindow(target);
2615
+ const aSec = sec || this.options.waitForTimeoutInSeconds
2616
+ let target
2617
+ const current = await this.browser.getWindowHandle()
2618
+
2619
+ await this.browser.waitUntil(
2620
+ async () => {
2621
+ await this.browser.getWindowHandles().then((handles) => {
2622
+ if (handles.indexOf(current) + num + 1 <= handles.length) {
2623
+ target = handles[handles.indexOf(current) + num]
2624
+ }
2625
+ })
2626
+ return target
2627
+ },
2628
+ { timeout: aSec * 1000, timeoutMsg: `There is no ability to switch to next tab with offset ${num}` },
2629
+ )
2630
+ return this.browser.switchToWindow(target)
2505
2631
  }
2506
2632
 
2507
2633
  /**
2508
2634
  * {{> switchToPreviousTab }}
2509
2635
  */
2510
2636
  async switchToPreviousTab(num = 1, sec = null) {
2511
- const aSec = sec || this.options.waitForTimeoutInSeconds;
2512
- const current = await this.browser.getWindowHandle();
2513
- let target;
2514
-
2515
- await this.browser.waitUntil(async () => {
2516
- await this.browser.getWindowHandles().then((handles) => {
2517
- if (handles.indexOf(current) - num > -1) {
2518
- target = handles[handles.indexOf(current) - num];
2519
- }
2520
- });
2521
- return target;
2522
- }, { timeout: aSec * 1000, timeoutMsg: `There is no ability to switch to previous tab with offset ${num}` });
2523
- return this.browser.switchToWindow(target);
2637
+ const aSec = sec || this.options.waitForTimeoutInSeconds
2638
+ const current = await this.browser.getWindowHandle()
2639
+ let target
2640
+
2641
+ await this.browser.waitUntil(
2642
+ async () => {
2643
+ await this.browser.getWindowHandles().then((handles) => {
2644
+ if (handles.indexOf(current) - num > -1) {
2645
+ target = handles[handles.indexOf(current) - num]
2646
+ }
2647
+ })
2648
+ return target
2649
+ },
2650
+ { timeout: aSec * 1000, timeoutMsg: `There is no ability to switch to previous tab with offset ${num}` },
2651
+ )
2652
+ return this.browser.switchToWindow(target)
2524
2653
  }
2525
2654
 
2526
2655
  /**
2527
2656
  * {{> closeCurrentTab }}
2528
2657
  */
2529
2658
  async closeCurrentTab() {
2530
- await this.browser.closeWindow();
2531
- const handles = await this.browser.getWindowHandles();
2532
- if (handles[0]) await this.browser.switchToWindow(handles[0]);
2659
+ await this.browser.closeWindow()
2660
+ const handles = await this.browser.getWindowHandles()
2661
+ if (handles[0]) await this.browser.switchToWindow(handles[0])
2533
2662
  }
2534
2663
 
2535
2664
  /**
2536
2665
  * {{> openNewTab }}
2537
2666
  */
2538
2667
  async openNewTab(url = 'about:blank', windowName = null) {
2539
- const client = this.browser;
2540
- const crypto = require('crypto');
2668
+ const client = this.browser
2669
+ const crypto = require('crypto')
2541
2670
  if (windowName == null) {
2542
- windowName = crypto.randomBytes(32).toString('hex');
2671
+ windowName = crypto.randomBytes(32).toString('hex')
2543
2672
  }
2544
- return client.newWindow(url, windowName);
2673
+ return client.newWindow(url, windowName)
2545
2674
  }
2546
2675
 
2547
2676
  /**
2548
2677
  * {{> grabNumberOfOpenTabs }}
2549
2678
  */
2550
2679
  async grabNumberOfOpenTabs() {
2551
- const pages = await this.browser.getWindowHandles();
2552
- this.debugSection('Tabs', `Total ${pages.length}`);
2553
- return pages.length;
2680
+ const pages = await this.browser.getWindowHandles()
2681
+ this.debugSection('Tabs', `Total ${pages.length}`)
2682
+ return pages.length
2554
2683
  }
2555
2684
 
2556
2685
  /**
2557
2686
  * {{> refreshPage }}
2558
2687
  */
2559
2688
  async refreshPage() {
2560
- const client = this.browser;
2561
- return client.refresh();
2689
+ const client = this.browser
2690
+ return client.refresh()
2562
2691
  }
2563
2692
 
2564
2693
  /**
2565
2694
  * {{> scrollPageToTop }}
2566
2695
  */
2567
2696
  scrollPageToTop() {
2568
- const client = this.browser;
2697
+ const client = this.browser
2569
2698
  /* eslint-disable prefer-arrow-callback */
2570
2699
  return client.execute(function () {
2571
- window.scrollTo(0, 0);
2572
- });
2700
+ window.scrollTo(0, 0)
2701
+ })
2573
2702
  /* eslint-enable */
2574
2703
  }
2575
2704
 
@@ -2577,19 +2706,16 @@ class WebDriver extends Helper {
2577
2706
  * {{> scrollPageToBottom }}
2578
2707
  */
2579
2708
  scrollPageToBottom() {
2580
- const client = this.browser;
2709
+ const client = this.browser
2581
2710
  /* eslint-disable prefer-arrow-callback, comma-dangle */
2582
2711
  return client.execute(function () {
2583
- const body = document.body;
2584
- const html = document.documentElement;
2585
- window.scrollTo(0, Math.max(
2586
- body.scrollHeight,
2587
- body.offsetHeight,
2588
- html.clientHeight,
2589
- html.scrollHeight,
2590
- html.offsetHeight
2591
- ));
2592
- });
2712
+ const body = document.body
2713
+ const html = document.documentElement
2714
+ window.scrollTo(
2715
+ 0,
2716
+ Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight),
2717
+ )
2718
+ })
2593
2719
  /* eslint-enable */
2594
2720
  }
2595
2721
 
@@ -2601,11 +2727,11 @@ class WebDriver extends Helper {
2601
2727
  function getScrollPosition() {
2602
2728
  return {
2603
2729
  x: window.pageXOffset,
2604
- y: window.pageYOffset
2605
- };
2730
+ y: window.pageYOffset,
2731
+ }
2606
2732
  }
2607
2733
  /* eslint-enable comma-dangle */
2608
- return this.executeScript(getScrollPosition);
2734
+ return this.executeScript(getScrollPosition)
2609
2735
  }
2610
2736
 
2611
2737
  /**
@@ -2618,15 +2744,15 @@ class WebDriver extends Helper {
2618
2744
  if (!this.options.automationProtocol) {
2619
2745
  console.log(`setGeoLocation deprecated:
2620
2746
  * This command is deprecated due to using deprecated JSON Wire Protocol command. More info: https://webdriver.io/docs/api/jsonwp/#setgeolocation
2621
- * Switch to devtools protocol to use this command by setting devtoolsProtocol: true in the configuration`);
2622
- return;
2747
+ * Switch to devtools protocol to use this command by setting devtoolsProtocol: true in the configuration`)
2748
+ return
2623
2749
  }
2624
- this.geoLocation = { latitude, longitude };
2750
+ this.geoLocation = { latitude, longitude }
2625
2751
 
2626
2752
  await this.browser.call(async () => {
2627
- const pages = await this.puppeteerBrowser.pages();
2628
- await pages[0].setGeolocation({ latitude, longitude });
2629
- });
2753
+ const pages = await this.puppeteerBrowser.pages()
2754
+ await pages[0].setGeolocation({ latitude, longitude })
2755
+ })
2630
2756
  }
2631
2757
 
2632
2758
  /**
@@ -2639,27 +2765,27 @@ class WebDriver extends Helper {
2639
2765
  if (!this.options.automationProtocol) {
2640
2766
  console.log(`grabGeoLocation deprecated:
2641
2767
  * This command is deprecated due to using deprecated JSON Wire Protocol command. More info: https://webdriver.io/docs/api/jsonwp/#getgeolocation
2642
- * Switch to devtools protocol to use this command by setting devtoolsProtocol: true in the configuration`);
2643
- return;
2768
+ * Switch to devtools protocol to use this command by setting devtoolsProtocol: true in the configuration`)
2769
+ return
2644
2770
  }
2645
- if (!this.geoLocation) return 'No GeoLocation is set!';
2646
- return this.geoLocation;
2771
+ if (!this.geoLocation) return 'No GeoLocation is set!'
2772
+ return this.geoLocation
2647
2773
  }
2648
2774
 
2649
2775
  /**
2650
2776
  * {{> grabElementBoundingRect }}
2651
2777
  */
2652
2778
  async grabElementBoundingRect(locator, prop) {
2653
- const res = await this._locate(locator, true);
2654
- assertElementExists(res, locator);
2655
- const el = usingFirstElement(res);
2779
+ const res = await this._locate(locator, true)
2780
+ assertElementExists(res, locator)
2781
+ const el = usingFirstElement(res)
2656
2782
 
2657
2783
  const rect = {
2658
- ...await el.getLocation(),
2659
- ...await el.getSize(),
2660
- };
2661
- if (prop) return rect[prop];
2662
- return rect;
2784
+ ...(await el.getLocation()),
2785
+ ...(await el.getSize()),
2786
+ }
2787
+ if (prop) return rect[prop]
2788
+ return rect
2663
2789
  }
2664
2790
 
2665
2791
  /**
@@ -2668,23 +2794,21 @@ class WebDriver extends Helper {
2668
2794
  * @param {*} fn
2669
2795
  */
2670
2796
  /* eslint-disable */
2671
- runOnIOS(caps, fn) {
2672
- }
2797
+ runOnIOS(caps, fn) {}
2673
2798
 
2674
2799
  /**
2675
2800
  * Placeholder for ~ locator only test case write once run on both Appium and WebDriver.
2676
2801
  * @param {*} caps
2677
2802
  * @param {*} fn
2678
2803
  */
2679
- runOnAndroid(caps, fn) {
2680
- }
2804
+ runOnAndroid(caps, fn) {}
2681
2805
  /* eslint-enable */
2682
2806
 
2683
2807
  /**
2684
2808
  * Placeholder for ~ locator only test case write once run on both Appium and WebDriver.
2685
2809
  */
2686
2810
  runInWeb(fn) {
2687
- return fn();
2811
+ return fn()
2688
2812
  }
2689
2813
 
2690
2814
  /**
@@ -2695,10 +2819,12 @@ class WebDriver extends Helper {
2695
2819
  */
2696
2820
  flushNetworkTraffics() {
2697
2821
  if (!this.options.automationProtocol) {
2698
- console.log('* Switch to devtools protocol to use this command by setting devtoolsProtocol: true in the configuration');
2699
- return;
2822
+ console.log(
2823
+ '* Switch to devtools protocol to use this command by setting devtoolsProtocol: true in the configuration',
2824
+ )
2825
+ return
2700
2826
  }
2701
- this.requests = [];
2827
+ this.requests = []
2702
2828
  }
2703
2829
 
2704
2830
  /**
@@ -2709,11 +2835,13 @@ class WebDriver extends Helper {
2709
2835
  */
2710
2836
  stopRecordingTraffic() {
2711
2837
  if (!this.options.automationProtocol) {
2712
- console.log('* Switch to devtools protocol to use this command by setting devtoolsProtocol: true in the configuration');
2713
- return;
2838
+ console.log(
2839
+ '* Switch to devtools protocol to use this command by setting devtoolsProtocol: true in the configuration',
2840
+ )
2841
+ return
2714
2842
  }
2715
- this.page.removeAllListeners('request');
2716
- this.recording = false;
2843
+ this.page.removeAllListeners('request')
2844
+ this.recording = false
2717
2845
  }
2718
2846
 
2719
2847
  /**
@@ -2725,14 +2853,16 @@ class WebDriver extends Helper {
2725
2853
  */
2726
2854
  async startRecordingTraffic() {
2727
2855
  if (!this.options.automationProtocol) {
2728
- console.log('* Switch to devtools protocol to use this command by setting devtoolsProtocol: true in the configuration');
2729
- return;
2856
+ console.log(
2857
+ '* Switch to devtools protocol to use this command by setting devtoolsProtocol: true in the configuration',
2858
+ )
2859
+ return
2730
2860
  }
2731
- this.flushNetworkTraffics();
2732
- this.recording = true;
2733
- this.recordedAtLeastOnce = true;
2861
+ this.flushNetworkTraffics()
2862
+ this.recording = true
2863
+ this.recordedAtLeastOnce = true
2734
2864
 
2735
- await this.page.setRequestInterception(true);
2865
+ await this.page.setRequestInterception(true)
2736
2866
 
2737
2867
  this.page.on('request', (request) => {
2738
2868
  const information = {
@@ -2741,16 +2871,16 @@ class WebDriver extends Helper {
2741
2871
  requestHeaders: request.headers(),
2742
2872
  requestPostData: request.postData(),
2743
2873
  response: request.response(),
2744
- };
2874
+ }
2745
2875
 
2746
- this.debugSection('REQUEST: ', JSON.stringify(information));
2876
+ this.debugSection('REQUEST: ', JSON.stringify(information))
2747
2877
 
2748
2878
  if (typeof information.requestPostData === 'object') {
2749
- information.requestPostData = JSON.parse(information.requestPostData);
2879
+ information.requestPostData = JSON.parse(information.requestPostData)
2750
2880
  }
2751
- request.continue();
2752
- this.requests.push(information);
2753
- });
2881
+ request.continue()
2882
+ this.requests.push(information)
2883
+ })
2754
2884
  }
2755
2885
 
2756
2886
  /**
@@ -2761,10 +2891,12 @@ class WebDriver extends Helper {
2761
2891
  */
2762
2892
  async grabRecordedNetworkTraffics() {
2763
2893
  if (!this.options.automationProtocol) {
2764
- console.log('* Switch to devtools protocol to use this command by setting devtoolsProtocol: true in the configuration');
2765
- return;
2894
+ console.log(
2895
+ '* Switch to devtools protocol to use this command by setting devtoolsProtocol: true in the configuration',
2896
+ )
2897
+ return
2766
2898
  }
2767
- return grabRecordedNetworkTraffics.call(this);
2899
+ return grabRecordedNetworkTraffics.call(this)
2768
2900
  }
2769
2901
 
2770
2902
  /**
@@ -2773,14 +2905,14 @@ class WebDriver extends Helper {
2773
2905
  *
2774
2906
  * {{> seeTraffic }}
2775
2907
  */
2776
- async seeTraffic({
2777
- name, url, parameters, requestPostData, timeout = 10,
2778
- }) {
2908
+ async seeTraffic({ name, url, parameters, requestPostData, timeout = 10 }) {
2779
2909
  if (!this.options.automationProtocol) {
2780
- console.log('* Switch to devtools protocol to use this command by setting devtoolsProtocol: true in the configuration');
2781
- return;
2910
+ console.log(
2911
+ '* Switch to devtools protocol to use this command by setting devtoolsProtocol: true in the configuration',
2912
+ )
2913
+ return
2782
2914
  }
2783
- await seeTraffic.call(this, ...arguments);
2915
+ await seeTraffic.call(this, ...arguments)
2784
2916
  }
2785
2917
 
2786
2918
  /**
@@ -2792,38 +2924,40 @@ class WebDriver extends Helper {
2792
2924
  */
2793
2925
  dontSeeTraffic({ name, url }) {
2794
2926
  if (!this.options.automationProtocol) {
2795
- console.log('* Switch to devtools protocol to use this command by setting devtoolsProtocol: true in the configuration');
2796
- return;
2927
+ console.log(
2928
+ '* Switch to devtools protocol to use this command by setting devtoolsProtocol: true in the configuration',
2929
+ )
2930
+ return
2797
2931
  }
2798
- dontSeeTraffic.call(this, ...arguments);
2932
+ dontSeeTraffic.call(this, ...arguments)
2799
2933
  }
2800
2934
  }
2801
2935
 
2802
2936
  async function proceedSee(assertType, text, context, strict = false) {
2803
- let description;
2937
+ let description
2804
2938
  if (!context) {
2805
2939
  if (this.context === webRoot) {
2806
- context = this.context;
2807
- description = 'web page';
2940
+ context = this.context
2941
+ description = 'web page'
2808
2942
  } else {
2809
- description = `current context ${this.context}`;
2810
- context = './/*';
2943
+ description = `current context ${this.context}`
2944
+ context = './/*'
2811
2945
  }
2812
2946
  } else {
2813
- description = `element ${context}`;
2947
+ description = `element ${context}`
2814
2948
  }
2815
2949
 
2816
- const smartWaitEnabled = assertType === 'assert';
2817
- const res = await this._locate(withStrictLocator(context), smartWaitEnabled);
2818
- assertElementExists(res, context);
2819
- const selected = await forEachAsync(res, async el => this.browser.getElementText(getElementId(el)));
2950
+ const smartWaitEnabled = assertType === 'assert'
2951
+ const res = await this._locate(withStrictLocator(context), smartWaitEnabled)
2952
+ assertElementExists(res, context)
2953
+ const selected = await forEachAsync(res, async (el) => this.browser.getElementText(getElementId(el)))
2820
2954
  if (strict) {
2821
2955
  if (Array.isArray(selected) && selected.length !== 0) {
2822
- return selected.map(elText => equals(description)[assertType](text, elText));
2956
+ return selected.map((elText) => equals(description)[assertType](text, elText))
2823
2957
  }
2824
- return equals(description)[assertType](text, selected);
2958
+ return equals(description)[assertType](text, selected)
2825
2959
  }
2826
- return stringIncludes(description)[assertType](text, selected);
2960
+ return stringIncludes(description)[assertType](text, selected)
2827
2961
  }
2828
2962
 
2829
2963
  /**
@@ -2840,21 +2974,19 @@ async function proceedSee(assertType, text, context, strict = false) {
2840
2974
  * @return {Promise<Array>} - Array of values.
2841
2975
  */
2842
2976
  async function forEachAsync(array, callback, options = { expandArrayResults: true }) {
2843
- const {
2844
- expandArrayResults = true,
2845
- } = options;
2846
- const inputArray = Array.isArray(array) ? array : [array];
2847
- const values = [];
2977
+ const { expandArrayResults = true } = options
2978
+ const inputArray = Array.isArray(array) ? array : [array]
2979
+ const values = []
2848
2980
  for (let index = 0; index < inputArray.length; index++) {
2849
- const res = await callback(inputArray[index], index, inputArray);
2981
+ const res = await callback(inputArray[index], index, inputArray)
2850
2982
 
2851
2983
  if (Array.isArray(res) && expandArrayResults) {
2852
- res.forEach(val => values.push(val));
2984
+ res.forEach((val) => values.push(val))
2853
2985
  } else if (res) {
2854
- values.push(res);
2986
+ values.push(res)
2855
2987
  }
2856
2988
  }
2857
- return values;
2989
+ return values
2858
2990
  }
2859
2991
 
2860
2992
  /**
@@ -2869,374 +3001,380 @@ async function forEachAsync(array, callback, options = { expandArrayResults: tru
2869
3001
  * @return {Promise<Array>} - Array of values.
2870
3002
  */
2871
3003
  async function filterAsync(array, callback) {
2872
- const inputArray = Array.isArray(array) ? array : [array];
2873
- const values = [];
3004
+ const inputArray = Array.isArray(array) ? array : [array]
3005
+ const values = []
2874
3006
  for (let index = 0; index < inputArray.length; index++) {
2875
- const res = await callback(inputArray[index], index, inputArray);
2876
- const value = Array.isArray(res) ? res[0] : res;
3007
+ const res = await callback(inputArray[index], index, inputArray)
3008
+ const value = Array.isArray(res) ? res[0] : res
2877
3009
 
2878
3010
  if (value) {
2879
- values.push(inputArray[index]);
3011
+ values.push(inputArray[index])
2880
3012
  }
2881
3013
  }
2882
- return values;
3014
+ return values
2883
3015
  }
2884
3016
 
2885
3017
  async function findClickable(locator, locateFn) {
2886
- locator = new Locator(locator);
3018
+ locator = new Locator(locator)
2887
3019
 
2888
3020
  if (this._isCustomLocator(locator)) {
2889
- return locateFn(locator.value);
3021
+ return locateFn(locator.value)
2890
3022
  }
2891
3023
 
2892
- if (locator.isAccessibilityId() && !this.isWeb) return locateFn(locator, true);
2893
- if (!locator.isFuzzy()) return locateFn(locator, true);
3024
+ if (locator.isAccessibilityId() && !this.isWeb) return locateFn(locator, true)
3025
+ if (!locator.isFuzzy()) return locateFn(locator, true)
2894
3026
 
2895
- let els;
2896
- const literal = xpathLocator.literal(locator.value);
3027
+ let els
3028
+ const literal = xpathLocator.literal(locator.value)
2897
3029
 
2898
- els = await locateFn(Locator.clickable.narrow(literal));
2899
- if (els.length) return els;
3030
+ els = await locateFn(Locator.clickable.narrow(literal))
3031
+ if (els.length) return els
2900
3032
 
2901
- els = await locateFn(Locator.clickable.wide(literal));
2902
- if (els.length) return els;
3033
+ els = await locateFn(Locator.clickable.wide(literal))
3034
+ if (els.length) return els
2903
3035
 
2904
- els = await locateFn(Locator.clickable.self(literal));
2905
- if (els.length) return els;
3036
+ els = await locateFn(Locator.clickable.self(literal))
3037
+ if (els.length) return els
2906
3038
 
2907
- return locateFn(locator.value); // by css or xpath
3039
+ return locateFn(locator.value) // by css or xpath
2908
3040
  }
2909
3041
 
2910
3042
  async function findFields(locator) {
2911
- locator = new Locator(locator);
3043
+ locator = new Locator(locator)
2912
3044
 
2913
3045
  if (this._isCustomLocator(locator)) {
2914
- return this._locate(locator);
3046
+ return this._locate(locator)
2915
3047
  }
2916
3048
 
2917
- if (locator.isAccessibilityId() && !this.isWeb) return this._locate(locator, true);
2918
- if (!locator.isFuzzy()) return this._locate(locator, true);
3049
+ if (locator.isAccessibilityId() && !this.isWeb) return this._locate(locator, true)
3050
+ if (!locator.isFuzzy()) return this._locate(locator, true)
2919
3051
 
2920
- const literal = xpathLocator.literal(locator.value);
2921
- let els = await this._locate(Locator.field.labelEquals(literal));
2922
- if (els.length) return els;
3052
+ const literal = xpathLocator.literal(locator.value)
3053
+ let els = await this._locate(Locator.field.labelEquals(literal))
3054
+ if (els.length) return els
2923
3055
 
2924
- els = await this._locate(Locator.field.labelContains(literal));
2925
- if (els.length) return els;
3056
+ els = await this._locate(Locator.field.labelContains(literal))
3057
+ if (els.length) return els
2926
3058
 
2927
- els = await this._locate(Locator.field.byName(literal));
2928
- if (els.length) return els;
2929
- return this._locate(locator.value); // by css or xpath
3059
+ els = await this._locate(Locator.field.byName(literal))
3060
+ if (els.length) return els
3061
+ return this._locate(locator.value) // by css or xpath
2930
3062
  }
2931
3063
 
2932
3064
  async function proceedSeeField(assertType, field, value) {
2933
- const res = await findFields.call(this, field);
2934
- assertElementExists(res, field, 'Field');
2935
- const elem = usingFirstElement(res);
2936
- const elemId = getElementId(elem);
3065
+ const res = await findFields.call(this, field)
3066
+ assertElementExists(res, field, 'Field')
3067
+ const elem = usingFirstElement(res)
3068
+ const elemId = getElementId(elem)
2937
3069
 
2938
3070
  const proceedMultiple = async (fields) => {
2939
- const fieldResults = toArray(await forEachAsync(fields, async (el) => {
2940
- const elementId = getElementId(el);
2941
- return this.browser.isW3C ? el.getValue() : this.browser.getElementAttribute(elementId, 'value');
2942
- }));
3071
+ const fieldResults = toArray(
3072
+ await forEachAsync(fields, async (el) => {
3073
+ const elementId = getElementId(el)
3074
+ return this.browser.isW3C ? el.getValue() : this.browser.getElementAttribute(elementId, 'value')
3075
+ }),
3076
+ )
2943
3077
 
2944
3078
  if (typeof value === 'boolean') {
2945
- equals(`no. of items matching > 0: ${field}`)[assertType](value, !!fieldResults.length);
3079
+ equals(`no. of items matching > 0: ${field}`)[assertType](value, !!fieldResults.length)
2946
3080
  } else {
2947
3081
  // Assert that results were found so the forEach assert does not silently pass
2948
- equals(`no. of items matching > 0: ${field}`)[assertType](true, !!fieldResults.length);
2949
- fieldResults.forEach(val => stringIncludes(`fields by ${field}`)[assertType](value, val));
3082
+ equals(`no. of items matching > 0: ${field}`)[assertType](true, !!fieldResults.length)
3083
+ fieldResults.forEach((val) => stringIncludes(`fields by ${field}`)[assertType](value, val))
2950
3084
  }
2951
- };
3085
+ }
2952
3086
 
2953
- const proceedSingle = el => el.getValue().then((res) => {
2954
- if (res === null) {
2955
- throw new Error(`Element ${el.selector} has no value attribute`);
2956
- }
2957
- stringIncludes(`fields by ${field}`)[assertType](value, res);
2958
- });
3087
+ const proceedSingle = (el) =>
3088
+ el.getValue().then((res) => {
3089
+ if (res === null) {
3090
+ throw new Error(`Element ${el.selector} has no value attribute`)
3091
+ }
3092
+ stringIncludes(`fields by ${field}`)[assertType](value, res)
3093
+ })
2959
3094
 
2960
- const filterBySelected = async elements => filterAsync(elements, async el => this.browser.isElementSelected(getElementId(el)));
3095
+ const filterBySelected = async (elements) =>
3096
+ filterAsync(elements, async (el) => this.browser.isElementSelected(getElementId(el)))
2961
3097
 
2962
3098
  const filterSelectedByValue = async (elements, value) => {
2963
3099
  return filterAsync(elements, async (el) => {
2964
- const elementId = getElementId(el);
2965
- const currentValue = this.browser.isW3C ? await el.getValue() : await this.browser.getElementAttribute(elementId, 'value');
2966
- const isSelected = await this.browser.isElementSelected(elementId);
2967
- return currentValue === value && isSelected;
2968
- });
2969
- };
2970
-
2971
- const tag = await elem.getTagName();
3100
+ const elementId = getElementId(el)
3101
+ const currentValue = this.browser.isW3C
3102
+ ? await el.getValue()
3103
+ : await this.browser.getElementAttribute(elementId, 'value')
3104
+ const isSelected = await this.browser.isElementSelected(elementId)
3105
+ return currentValue === value && isSelected
3106
+ })
3107
+ }
3108
+
3109
+ const tag = await elem.getTagName()
2972
3110
  if (tag === 'select') {
2973
- const subOptions = await this.browser.findElementsFromElement(elemId, 'css', 'option');
3111
+ const subOptions = await this.browser.findElementsFromElement(elemId, 'css', 'option')
2974
3112
 
2975
3113
  if (value === '') {
2976
3114
  // Don't filter by value
2977
- const selectedOptions = await filterBySelected(subOptions);
2978
- return proceedMultiple(selectedOptions);
3115
+ const selectedOptions = await filterBySelected(subOptions)
3116
+ return proceedMultiple(selectedOptions)
2979
3117
  }
2980
3118
 
2981
- const options = await filterSelectedByValue(subOptions, value);
2982
- return proceedMultiple(options);
3119
+ const options = await filterSelectedByValue(subOptions, value)
3120
+ return proceedMultiple(options)
2983
3121
  }
2984
3122
 
2985
3123
  if (tag === 'input') {
2986
- const fieldType = await elem.getAttribute('type');
3124
+ const fieldType = await elem.getAttribute('type')
2987
3125
 
2988
3126
  if (fieldType === 'checkbox' || fieldType === 'radio') {
2989
3127
  if (typeof value === 'boolean') {
2990
3128
  // Support boolean values
2991
- const options = await filterBySelected(res);
2992
- return proceedMultiple(options);
3129
+ const options = await filterBySelected(res)
3130
+ return proceedMultiple(options)
2993
3131
  }
2994
3132
 
2995
- const options = await filterSelectedByValue(res, value);
2996
- return proceedMultiple(options);
3133
+ const options = await filterSelectedByValue(res, value)
3134
+ return proceedMultiple(options)
2997
3135
  }
2998
- return proceedSingle(elem);
3136
+ return proceedSingle(elem)
2999
3137
  }
3000
- return proceedSingle(elem);
3138
+ return proceedSingle(elem)
3001
3139
  }
3002
3140
 
3003
3141
  function toArray(item) {
3004
3142
  if (!Array.isArray(item)) {
3005
- return [item];
3143
+ return [item]
3006
3144
  }
3007
- return item;
3145
+ return item
3008
3146
  }
3009
3147
 
3010
3148
  async function proceedSeeCheckbox(assertType, field) {
3011
- const res = await findFields.call(this, field);
3012
- assertElementExists(res, field, 'Field');
3149
+ const res = await findFields.call(this, field)
3150
+ assertElementExists(res, field, 'Field')
3013
3151
 
3014
- const selected = await forEachAsync(res, async el => this.browser.isElementSelected(getElementId(el)));
3015
- return truth(`checkable field "${field}"`, 'to be checked')[assertType](selected);
3152
+ const selected = await forEachAsync(res, async (el) => this.browser.isElementSelected(getElementId(el)))
3153
+ return truth(`checkable field "${field}"`, 'to be checked')[assertType](selected)
3016
3154
  }
3017
3155
 
3018
3156
  async function findCheckable(locator, locateFn) {
3019
- let els;
3020
- locator = new Locator(locator);
3157
+ let els
3158
+ locator = new Locator(locator)
3021
3159
 
3022
3160
  if (this._isCustomLocator(locator)) {
3023
- return locateFn(locator.value);
3161
+ return locateFn(locator.value)
3024
3162
  }
3025
3163
 
3026
- if (locator.isAccessibilityId() && !this.isWeb) return locateFn(locator, true);
3027
- if (!locator.isFuzzy()) return locateFn(locator, true);
3164
+ if (locator.isAccessibilityId() && !this.isWeb) return locateFn(locator, true)
3165
+ if (!locator.isFuzzy()) return locateFn(locator, true)
3028
3166
 
3029
- const literal = xpathLocator.literal(locator.value);
3030
- els = await locateFn(Locator.checkable.byText(literal));
3031
- if (els.length) return els;
3032
- els = await locateFn(Locator.checkable.byName(literal));
3033
- if (els.length) return els;
3167
+ const literal = xpathLocator.literal(locator.value)
3168
+ els = await locateFn(Locator.checkable.byText(literal))
3169
+ if (els.length) return els
3170
+ els = await locateFn(Locator.checkable.byName(literal))
3171
+ if (els.length) return els
3034
3172
 
3035
- return locateFn(locator.value); // by css or xpath
3173
+ return locateFn(locator.value) // by css or xpath
3036
3174
  }
3037
3175
 
3038
3176
  function withStrictLocator(locator) {
3039
- locator = new Locator(locator);
3040
- return locator.simplify();
3177
+ locator = new Locator(locator)
3178
+ return locator.simplify()
3041
3179
  }
3042
3180
 
3043
3181
  function isFrameLocator(locator) {
3044
- locator = new Locator(locator);
3045
- if (locator.isFrame()) return locator.value;
3046
- return false;
3182
+ locator = new Locator(locator)
3183
+ if (locator.isFrame()) return locator.value
3184
+ return false
3047
3185
  }
3048
3186
 
3049
3187
  function assertElementExists(res, locator, prefix, suffix) {
3050
3188
  if (!res || res.length === 0) {
3051
- throw new ElementNotFound(locator, prefix, suffix);
3189
+ throw new ElementNotFound(locator, prefix, suffix)
3052
3190
  }
3053
3191
  }
3054
3192
 
3055
3193
  function usingFirstElement(els) {
3056
- if (els.length > 1) debug(`[Elements] Using first element out of ${els.length}`);
3057
- return els[0];
3194
+ if (els.length > 1) debug(`[Elements] Using first element out of ${els.length}`)
3195
+ return els[0]
3058
3196
  }
3059
3197
 
3060
3198
  function getElementId(el) {
3061
3199
  // W3C WebDriver web element identifier
3062
3200
  // https://w3c.github.io/webdriver/#dfn-web-element-identifier
3063
3201
  if (el['element-6066-11e4-a52e-4f735466cecf']) {
3064
- return el['element-6066-11e4-a52e-4f735466cecf'];
3202
+ return el['element-6066-11e4-a52e-4f735466cecf']
3065
3203
  }
3066
3204
  // (deprecated) JsonWireProtocol identifier
3067
3205
  // https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#webelement-json-object
3068
3206
  if (el.ELEMENT) {
3069
- return el.ELEMENT;
3207
+ return el.ELEMENT
3070
3208
  }
3071
3209
 
3072
- return null;
3210
+ return null
3073
3211
  }
3074
3212
 
3075
3213
  // List of known key values to unicode code points
3076
3214
  // https://www.w3.org/TR/webdriver/#keyboard-actions
3077
3215
  const keyUnicodeMap = {
3078
3216
  /* eslint-disable quote-props */
3079
- 'Unidentified': '\uE000',
3080
- 'Cancel': '\uE001',
3081
- 'Clear': '\uE005',
3082
- 'Help': '\uE002',
3083
- 'Pause': '\uE00B',
3084
- 'Backspace': '\uE003',
3085
- 'Return': '\uE006',
3086
- 'Enter': '\uE007',
3087
- 'Escape': '\uE00C',
3088
- 'Alt': '\uE00A',
3089
- 'AltLeft': '\uE00A',
3090
- 'AltRight': '\uE052',
3091
- 'Control': '\uE009',
3092
- 'ControlLeft': '\uE009',
3093
- 'ControlRight': '\uE051',
3094
- 'Meta': '\uE03D',
3095
- 'MetaLeft': '\uE03D',
3096
- 'MetaRight': '\uE053',
3097
- 'Shift': '\uE008',
3098
- 'ShiftLeft': '\uE008',
3099
- 'ShiftRight': '\uE050',
3100
- 'Space': '\uE00D',
3217
+ Unidentified: '\uE000',
3218
+ Cancel: '\uE001',
3219
+ Clear: '\uE005',
3220
+ Help: '\uE002',
3221
+ Pause: '\uE00B',
3222
+ Backspace: '\uE003',
3223
+ Return: '\uE006',
3224
+ Enter: '\uE007',
3225
+ Escape: '\uE00C',
3226
+ Alt: '\uE00A',
3227
+ AltLeft: '\uE00A',
3228
+ AltRight: '\uE052',
3229
+ Control: '\uE009',
3230
+ ControlLeft: '\uE009',
3231
+ ControlRight: '\uE051',
3232
+ Meta: '\uE03D',
3233
+ MetaLeft: '\uE03D',
3234
+ MetaRight: '\uE053',
3235
+ Shift: '\uE008',
3236
+ ShiftLeft: '\uE008',
3237
+ ShiftRight: '\uE050',
3238
+ Space: '\uE00D',
3101
3239
  ' ': '\uE00D',
3102
- 'Tab': '\uE004',
3103
- 'Insert': '\uE016',
3104
- 'Delete': '\uE017',
3105
- 'End': '\uE010',
3106
- 'Home': '\uE011',
3107
- 'PageUp': '\uE00E',
3108
- 'PageDown': '\uE00F',
3109
- 'ArrowDown': '\uE015',
3110
- 'ArrowLeft': '\uE012',
3111
- 'ArrowRight': '\uE014',
3112
- 'ArrowUp': '\uE013',
3113
- 'F1': '\uE031',
3114
- 'F2': '\uE032',
3115
- 'F3': '\uE033',
3116
- 'F4': '\uE034',
3117
- 'F5': '\uE035',
3118
- 'F6': '\uE036',
3119
- 'F7': '\uE037',
3120
- 'F8': '\uE038',
3121
- 'F9': '\uE039',
3122
- 'F10': '\uE03A',
3123
- 'F11': '\uE03B',
3124
- 'F12': '\uE03C',
3125
- 'Numpad0': '\uE01A',
3126
- 'Numpad1': '\uE01B',
3127
- 'Numpad2': '\uE01C',
3128
- 'Numpad3': '\uE01D',
3129
- 'Numpad4': '\uE01E',
3130
- 'Numpad5': '\uE01F',
3131
- 'Numpad6': '\uE020',
3132
- 'Numpad7': '\uE021',
3133
- 'Numpad8': '\uE022',
3134
- 'Numpad9': '\uE023',
3135
- 'NumpadMultiply': '\uE024',
3136
- 'NumpadAdd': '\uE025',
3137
- 'NumpadSubtract': '\uE027',
3138
- 'NumpadDecimal': '\uE028',
3139
- 'NumpadDivide': '\uE029',
3140
- 'NumpadEnter': '\uE007',
3141
- 'NumpadInsert': '\uE05C', // 'Numpad0' alternate (when NumLock off)
3142
- 'NumpadDelete': '\uE05D', // 'NumpadDecimal' alternate (when NumLock off)
3143
- 'NumpadEnd': '\uE056', // 'Numpad1' alternate (when NumLock off)
3144
- 'NumpadHome': '\uE057', // 'Numpad7' alternate (when NumLock off)
3145
- 'NumpadPageDown': '\uE055', // 'Numpad3' alternate (when NumLock off)
3146
- 'NumpadPageUp': '\uE054', // 'Numpad9' alternate (when NumLock off)
3147
- 'NumpadArrowDown': '\uE05B', // 'Numpad2' alternate (when NumLock off)
3148
- 'NumpadArrowLeft': '\uE058', // 'Numpad4' alternate (when NumLock off)
3149
- 'NumpadArrowRight': '\uE05A', // 'Numpad6' alternate (when NumLock off)
3150
- 'NumpadArrowUp': '\uE059', // 'Numpad8' alternate (when NumLock off)
3151
- 'Comma': '\uE026', // ',' alias
3152
- 'Digit0': '0', // '0' alias
3153
- 'Digit1': '1', // '1' alias
3154
- 'Digit2': '2', // '2' alias
3155
- 'Digit3': '3', // '3' alias
3156
- 'Digit4': '4', // '4' alias
3157
- 'Digit5': '5', // '5' alias
3158
- 'Digit6': '6', // '6' alias
3159
- 'Digit7': '7', // '7' alias
3160
- 'Digit8': '8', // '8' alias
3161
- 'Digit9': '9', // '9' alias
3162
- 'Equal': '\uE019', // '=' alias
3163
- 'KeyA': 'a', // 'a' alias
3164
- 'KeyB': 'b', // 'b' alias
3165
- 'KeyC': 'c', // 'c' alias
3166
- 'KeyD': 'd', // 'd' alias
3167
- 'KeyE': 'e', // 'e' alias
3168
- 'KeyF': 'f', // 'f' alias
3169
- 'KeyG': 'g', // 'g' alias
3170
- 'KeyH': 'h', // 'h' alias
3171
- 'KeyI': 'i', // 'i' alias
3172
- 'KeyJ': 'j', // 'j' alias
3173
- 'KeyK': 'k', // 'k' alias
3174
- 'KeyL': 'l', // 'l' alias
3175
- 'KeyM': 'm', // 'm' alias
3176
- 'KeyN': 'n', // 'n' alias
3177
- 'KeyO': 'o', // 'o' alias
3178
- 'KeyP': 'p', // 'p' alias
3179
- 'KeyQ': 'q', // 'q' alias
3180
- 'KeyR': 'r', // 'r' alias
3181
- 'KeyS': 's', // 's' alias
3182
- 'KeyT': 't', // 't' alias
3183
- 'KeyU': 'u', // 'u' alias
3184
- 'KeyV': 'v', // 'v' alias
3185
- 'KeyW': 'w', // 'w' alias
3186
- 'KeyX': 'x', // 'x' alias
3187
- 'KeyY': 'y', // 'y' alias
3188
- 'KeyZ': 'z', // 'z' alias
3189
- 'Period': '.', // '.' alias
3190
- 'Semicolon': '\uE018', // ';' alias
3191
- 'Slash': '/', // '/' alias
3192
- 'ZenkakuHankaku': '\uE040',
3240
+ Tab: '\uE004',
3241
+ Insert: '\uE016',
3242
+ Delete: '\uE017',
3243
+ End: '\uE010',
3244
+ Home: '\uE011',
3245
+ PageUp: '\uE00E',
3246
+ PageDown: '\uE00F',
3247
+ ArrowDown: '\uE015',
3248
+ ArrowLeft: '\uE012',
3249
+ ArrowRight: '\uE014',
3250
+ ArrowUp: '\uE013',
3251
+ F1: '\uE031',
3252
+ F2: '\uE032',
3253
+ F3: '\uE033',
3254
+ F4: '\uE034',
3255
+ F5: '\uE035',
3256
+ F6: '\uE036',
3257
+ F7: '\uE037',
3258
+ F8: '\uE038',
3259
+ F9: '\uE039',
3260
+ F10: '\uE03A',
3261
+ F11: '\uE03B',
3262
+ F12: '\uE03C',
3263
+ Numpad0: '\uE01A',
3264
+ Numpad1: '\uE01B',
3265
+ Numpad2: '\uE01C',
3266
+ Numpad3: '\uE01D',
3267
+ Numpad4: '\uE01E',
3268
+ Numpad5: '\uE01F',
3269
+ Numpad6: '\uE020',
3270
+ Numpad7: '\uE021',
3271
+ Numpad8: '\uE022',
3272
+ Numpad9: '\uE023',
3273
+ NumpadMultiply: '\uE024',
3274
+ NumpadAdd: '\uE025',
3275
+ NumpadSubtract: '\uE027',
3276
+ NumpadDecimal: '\uE028',
3277
+ NumpadDivide: '\uE029',
3278
+ NumpadEnter: '\uE007',
3279
+ NumpadInsert: '\uE05C', // 'Numpad0' alternate (when NumLock off)
3280
+ NumpadDelete: '\uE05D', // 'NumpadDecimal' alternate (when NumLock off)
3281
+ NumpadEnd: '\uE056', // 'Numpad1' alternate (when NumLock off)
3282
+ NumpadHome: '\uE057', // 'Numpad7' alternate (when NumLock off)
3283
+ NumpadPageDown: '\uE055', // 'Numpad3' alternate (when NumLock off)
3284
+ NumpadPageUp: '\uE054', // 'Numpad9' alternate (when NumLock off)
3285
+ NumpadArrowDown: '\uE05B', // 'Numpad2' alternate (when NumLock off)
3286
+ NumpadArrowLeft: '\uE058', // 'Numpad4' alternate (when NumLock off)
3287
+ NumpadArrowRight: '\uE05A', // 'Numpad6' alternate (when NumLock off)
3288
+ NumpadArrowUp: '\uE059', // 'Numpad8' alternate (when NumLock off)
3289
+ Comma: '\uE026', // ',' alias
3290
+ Digit0: '0', // '0' alias
3291
+ Digit1: '1', // '1' alias
3292
+ Digit2: '2', // '2' alias
3293
+ Digit3: '3', // '3' alias
3294
+ Digit4: '4', // '4' alias
3295
+ Digit5: '5', // '5' alias
3296
+ Digit6: '6', // '6' alias
3297
+ Digit7: '7', // '7' alias
3298
+ Digit8: '8', // '8' alias
3299
+ Digit9: '9', // '9' alias
3300
+ Equal: '\uE019', // '=' alias
3301
+ KeyA: 'a', // 'a' alias
3302
+ KeyB: 'b', // 'b' alias
3303
+ KeyC: 'c', // 'c' alias
3304
+ KeyD: 'd', // 'd' alias
3305
+ KeyE: 'e', // 'e' alias
3306
+ KeyF: 'f', // 'f' alias
3307
+ KeyG: 'g', // 'g' alias
3308
+ KeyH: 'h', // 'h' alias
3309
+ KeyI: 'i', // 'i' alias
3310
+ KeyJ: 'j', // 'j' alias
3311
+ KeyK: 'k', // 'k' alias
3312
+ KeyL: 'l', // 'l' alias
3313
+ KeyM: 'm', // 'm' alias
3314
+ KeyN: 'n', // 'n' alias
3315
+ KeyO: 'o', // 'o' alias
3316
+ KeyP: 'p', // 'p' alias
3317
+ KeyQ: 'q', // 'q' alias
3318
+ KeyR: 'r', // 'r' alias
3319
+ KeyS: 's', // 's' alias
3320
+ KeyT: 't', // 't' alias
3321
+ KeyU: 'u', // 'u' alias
3322
+ KeyV: 'v', // 'v' alias
3323
+ KeyW: 'w', // 'w' alias
3324
+ KeyX: 'x', // 'x' alias
3325
+ KeyY: 'y', // 'y' alias
3326
+ KeyZ: 'z', // 'z' alias
3327
+ Period: '.', // '.' alias
3328
+ Semicolon: '\uE018', // ';' alias
3329
+ Slash: '/', // '/' alias
3330
+ ZenkakuHankaku: '\uE040',
3193
3331
  /* eslint-enable quote-props */
3194
- };
3332
+ }
3195
3333
 
3196
3334
  function convertKeyToRawKey(key) {
3197
3335
  if (Object.prototype.hasOwnProperty.call(keyUnicodeMap, key)) {
3198
- return keyUnicodeMap[key];
3336
+ return keyUnicodeMap[key]
3199
3337
  }
3200
3338
  // Key is raw key when no representative unicode code point for value
3201
- return key;
3339
+ return key
3202
3340
  }
3203
3341
 
3204
3342
  function getNormalizedKey(key) {
3205
- let normalizedKey = getNormalizedKeyAttributeValue(key);
3343
+ let normalizedKey = getNormalizedKeyAttributeValue(key)
3206
3344
  // Always use "left" modifier keys for non-W3C sessions,
3207
3345
  // as JsonWireProtocol does not support "right" modifier keys
3208
3346
  if (!this.browser.isW3C) {
3209
- normalizedKey = normalizedKey.replace(/^(Alt|Control|Meta|Shift)Right$/, '$1');
3347
+ normalizedKey = normalizedKey.replace(/^(Alt|Control|Meta|Shift)Right$/, '$1')
3210
3348
  }
3211
3349
  if (key !== normalizedKey) {
3212
- this.debugSection('Input', `Mapping key '${key}' to '${normalizedKey}'`);
3350
+ this.debugSection('Input', `Mapping key '${key}' to '${normalizedKey}'`)
3213
3351
  }
3214
- return convertKeyToRawKey(normalizedKey);
3352
+ return convertKeyToRawKey(normalizedKey)
3215
3353
  }
3216
3354
 
3217
- const unicodeModifierKeys = modifierKeys.map(k => convertKeyToRawKey(k));
3355
+ const unicodeModifierKeys = modifierKeys.map((k) => convertKeyToRawKey(k))
3218
3356
  function isModifierKey(key) {
3219
- return unicodeModifierKeys.includes(key);
3357
+ return unicodeModifierKeys.includes(key)
3220
3358
  }
3221
3359
 
3222
3360
  function highlightActiveElement(element) {
3223
3361
  if (this.options.highlightElement && global.debugMode) {
3224
- highlightElement(element, this.browser);
3362
+ highlightElement(element, this.browser)
3225
3363
  }
3226
3364
  }
3227
3365
 
3228
3366
  function prepareLocateFn(context) {
3229
- if (!context) return this._locate.bind(this);
3367
+ if (!context) return this._locate.bind(this)
3230
3368
  return (l) => {
3231
- l = new Locator(l, 'css');
3369
+ l = new Locator(l, 'css')
3232
3370
  return this._locate(context, true).then(async (res) => {
3233
- assertElementExists(res, context, 'Context element');
3371
+ assertElementExists(res, context, 'Context element')
3234
3372
  if (l.react) {
3235
- return res[0].react$$(l.react, l.props || undefined);
3373
+ return res[0].react$$(l.react, l.props || undefined)
3236
3374
  }
3237
- return res[0].$$(l.simplify());
3238
- });
3239
- };
3375
+ return res[0].$$(l.simplify())
3376
+ })
3377
+ }
3240
3378
  }
3241
3379
 
3242
- module.exports = WebDriver;
3380
+ module.exports = WebDriver