codeceptjs 3.6.6 → 4.0.0-beta.1

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