codeceptjs 4.0.0-beta.1 → 4.0.0-beta.3

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