codeceptjs 4.0.0-beta.2 → 4.0.0-beta.4

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