codeceptjs 2.1.3 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/CHANGELOG.md +125 -37
  2. package/README.md +15 -22
  3. package/bin/codecept.js +4 -1
  4. package/docs/acceptance.md +44 -1
  5. package/docs/advanced.md +1 -1
  6. package/docs/angular.md +6 -9
  7. package/docs/basics.md +388 -75
  8. package/docs/bdd.md +4 -3
  9. package/docs/best.md +1 -1
  10. package/docs/books.md +31 -0
  11. package/docs/build/Appium.js +215 -176
  12. package/docs/build/Nightmare.js +618 -489
  13. package/docs/build/Polly.js +189 -0
  14. package/docs/build/Protractor.js +747 -608
  15. package/docs/build/Puppeteer.js +914 -633
  16. package/docs/build/REST.js +1 -1
  17. package/docs/build/TestCafe.js +1835 -0
  18. package/docs/build/WebDriver.js +861 -805
  19. package/docs/build/WebDriverIO.js +616 -617
  20. package/docs/changelog.md +410 -316
  21. package/docs/commands.md +6 -6
  22. package/docs/community-helpers.md +2 -0
  23. package/docs/detox.md +235 -0
  24. package/docs/examples.md +23 -0
  25. package/docs/helpers/ApiDataFactory.md +11 -10
  26. package/docs/helpers/Appium.md +130 -61
  27. package/docs/helpers/Detox.md +579 -0
  28. package/docs/helpers/FileSystem.md +2 -1
  29. package/docs/helpers/Mochawesome.md +1 -0
  30. package/docs/helpers/Nightmare.md +348 -128
  31. package/docs/helpers/Polly.md +85 -0
  32. package/docs/helpers/Protractor.md +451 -184
  33. package/docs/helpers/Puppeteer-firefox.md +55 -0
  34. package/docs/helpers/Puppeteer.md +619 -183
  35. package/docs/helpers/REST.md +17 -16
  36. package/docs/helpers/SeleniumWebdriver.md +9 -8
  37. package/docs/helpers/TestCafe.md +1168 -0
  38. package/docs/helpers/WebDriver.md +600 -291
  39. package/docs/helpers/WebDriverIO.md +393 -278
  40. package/docs/helpers.md +37 -18
  41. package/docs/locators.md +2 -0
  42. package/docs/mobile-react-native-locators.md +64 -0
  43. package/docs/mobile.md +5 -0
  44. package/docs/plugins.md +54 -13
  45. package/docs/puppeteer.md +74 -26
  46. package/docs/quickstart.md +47 -12
  47. package/docs/react.md +67 -0
  48. package/docs/reports.md +1 -1
  49. package/docs/{webapi/_keys.mustache → shared/keys.mustache} +0 -0
  50. package/docs/shared/react.mustache +1 -0
  51. package/docs/testcafe.md +157 -0
  52. package/docs/videos.md +19 -0
  53. package/docs/webapi/amOnPage.mustache +1 -1
  54. package/docs/webapi/appendField.mustache +2 -2
  55. package/docs/webapi/attachFile.mustache +2 -2
  56. package/docs/webapi/checkOption.mustache +2 -2
  57. package/docs/webapi/clearCookie.mustache +1 -1
  58. package/docs/webapi/clearField.mustache +1 -1
  59. package/docs/webapi/click.mustache +2 -2
  60. package/docs/webapi/clickLink.mustache +3 -3
  61. package/docs/webapi/dontSee.mustache +6 -3
  62. package/docs/webapi/dontSeeCheckboxIsChecked.mustache +7 -1
  63. package/docs/webapi/dontSeeCookie.mustache +5 -1
  64. package/docs/webapi/dontSeeCurrentUrlEquals.mustache +6 -1
  65. package/docs/webapi/dontSeeElement.mustache +5 -1
  66. package/docs/webapi/dontSeeElementInDOM.mustache +5 -1
  67. package/docs/webapi/dontSeeInCurrentUrl.mustache +1 -1
  68. package/docs/webapi/dontSeeInField.mustache +7 -2
  69. package/docs/webapi/dontSeeInSource.mustache +5 -1
  70. package/docs/webapi/dontSeeInTitle.mustache +5 -1
  71. package/docs/webapi/doubleClick.mustache +2 -2
  72. package/docs/webapi/downloadFile.mustache +2 -2
  73. package/docs/webapi/dragAndDrop.mustache +2 -2
  74. package/docs/webapi/dragSlider.mustache +2 -2
  75. package/docs/webapi/executeAsyncScript.mustache +1 -1
  76. package/docs/webapi/executeScript.mustache +1 -1
  77. package/docs/webapi/fillField.mustache +2 -2
  78. package/docs/webapi/grabAttributeFrom.mustache +3 -2
  79. package/docs/webapi/grabBrowserLogs.mustache +3 -1
  80. package/docs/webapi/grabCookie.mustache +2 -1
  81. package/docs/webapi/grabCssPropertyFrom.mustache +3 -2
  82. package/docs/webapi/grabCurrentUrl.mustache +3 -1
  83. package/docs/webapi/grabDataFromPerformanceTiming.mustache +19 -0
  84. package/docs/webapi/grabHTMLFrom.mustache +2 -1
  85. package/docs/webapi/grabNumberOfOpenTabs.mustache +4 -2
  86. package/docs/webapi/grabNumberOfVisibleElements.mustache +3 -2
  87. package/docs/webapi/grabPageScrollPosition.mustache +3 -1
  88. package/docs/webapi/grabSource.mustache +3 -1
  89. package/docs/webapi/grabTextFrom.mustache +2 -1
  90. package/docs/webapi/grabTitle.mustache +3 -1
  91. package/docs/webapi/grabValueFrom.mustache +2 -1
  92. package/docs/webapi/moveCursorTo.mustache +3 -3
  93. package/docs/webapi/pressKey.mustache +1 -1
  94. package/docs/webapi/resizeWindow.mustache +2 -2
  95. package/docs/webapi/rightClick.mustache +2 -2
  96. package/docs/webapi/saveScreenshot.mustache +3 -3
  97. package/docs/webapi/say.mustache +2 -2
  98. package/docs/webapi/scrollPageToBottom.mustache +1 -1
  99. package/docs/webapi/scrollPageToTop.mustache +1 -1
  100. package/docs/webapi/scrollTo.mustache +3 -3
  101. package/docs/webapi/see.mustache +2 -2
  102. package/docs/webapi/seeAttributesOnElements.mustache +3 -3
  103. package/docs/webapi/seeCheckboxIsChecked.mustache +2 -1
  104. package/docs/webapi/seeCookie.mustache +1 -1
  105. package/docs/webapi/seeCssPropertiesOnElements.mustache +2 -2
  106. package/docs/webapi/seeCurrentUrlEquals.mustache +1 -1
  107. package/docs/webapi/seeElement.mustache +1 -1
  108. package/docs/webapi/seeElementInDOM.mustache +1 -1
  109. package/docs/webapi/seeInCurrentUrl.mustache +1 -1
  110. package/docs/webapi/seeInField.mustache +2 -2
  111. package/docs/webapi/seeInSource.mustache +1 -1
  112. package/docs/webapi/seeInTitle.mustache +5 -1
  113. package/docs/webapi/seeNumberOfElements.mustache +10 -0
  114. package/docs/webapi/seeNumberOfVisibleElements.mustache +2 -2
  115. package/docs/webapi/selectOption.mustache +2 -2
  116. package/docs/webapi/setCookie.mustache +1 -1
  117. package/docs/webapi/switchTo.mustache +6 -1
  118. package/docs/webapi/uncheckOption.mustache +2 -2
  119. package/docs/webapi/wait.mustache +1 -2
  120. package/docs/webapi/waitForDetached.mustache +3 -3
  121. package/docs/webapi/waitForElement.mustache +2 -2
  122. package/docs/webapi/waitForEnabled.mustache +1 -1
  123. package/docs/webapi/waitForFunction.mustache +3 -3
  124. package/docs/webapi/waitForInvisible.mustache +3 -3
  125. package/docs/webapi/waitForText.mustache +3 -3
  126. package/docs/webapi/waitForValue.mustache +3 -3
  127. package/docs/webapi/waitForVisible.mustache +3 -3
  128. package/docs/webapi/waitInUrl.mustache +2 -2
  129. package/docs/webapi/waitNumberOfVisibleElements.mustache +3 -3
  130. package/docs/webapi/waitToHide.mustache +3 -3
  131. package/docs/webapi/waitUntil.mustache +3 -3
  132. package/docs/webapi/waitUrlEquals.mustache +2 -2
  133. package/docs/webdriver.md +453 -0
  134. package/lib/codecept.js +11 -9
  135. package/lib/command/definitions.js +183 -30
  136. package/lib/command/gherkin/snippets.js +29 -9
  137. package/lib/command/init.js +31 -9
  138. package/lib/command/run-multiple.js +46 -59
  139. package/lib/command/utils.js +1 -1
  140. package/lib/container.js +30 -4
  141. package/lib/data/dataScenarioConfig.js +18 -0
  142. package/lib/helper/Appium.js +24 -24
  143. package/lib/helper/Nightmare.js +81 -84
  144. package/lib/helper/Polly.js +189 -0
  145. package/lib/helper/Protractor.js +96 -86
  146. package/lib/helper/Puppeteer.js +238 -113
  147. package/lib/helper/REST.js +1 -1
  148. package/lib/helper/TestCafe.js +1257 -0
  149. package/lib/helper/WebDriver.js +217 -277
  150. package/lib/helper/WebDriverIO.js +75 -75
  151. package/lib/helper/clientscripts/nightmare.js +8 -0
  152. package/lib/helper/extras/React.js +55 -0
  153. package/lib/helper/testcafe/testControllerHolder.js +42 -0
  154. package/lib/helper/testcafe/testcafe-utils.js +63 -0
  155. package/lib/history.js +39 -0
  156. package/lib/hooks.js +25 -1
  157. package/lib/interfaces/gherkin.js +17 -1
  158. package/lib/interfaces/scenarioConfig.js +2 -2
  159. package/lib/listener/config.js +3 -3
  160. package/lib/locator.js +6 -0
  161. package/lib/pause.js +22 -1
  162. package/lib/plugin/allure.js +63 -0
  163. package/lib/plugin/autoLogin.js +65 -16
  164. package/lib/plugin/puppeteerCoverage.js +6 -1
  165. package/lib/plugin/stepByStepReport.js +4 -3
  166. package/lib/scenario.js +23 -17
  167. package/lib/step.js +5 -2
  168. package/lib/ui.js +1 -1
  169. package/lib/utils.js +70 -20
  170. package/package.json +20 -19
  171. package/translations/de-DE.js +69 -0
  172. package/translations/index.js +1 -0
  173. package/docs/video.md +0 -26
@@ -81,6 +81,9 @@ class Nightmare extends Helper {
81
81
  static _config() {
82
82
  return [
83
83
  { name: 'url', message: 'Base url of site to be tested', default: 'http://localhost' },
84
+ {
85
+ name: 'show', message: 'Show browser window', default: true, type: 'confirm',
86
+ },
84
87
  ];
85
88
  }
86
89
 
@@ -393,21 +396,18 @@ class Nightmare extends Helper {
393
396
 
394
397
  /**
395
398
  * Opens a web page in a browser. Requires relative or absolute url.
396
- If url starts with `/`, opens a web page of a site defined in `url` config parameter.
397
-
398
- ```js
399
- I.amOnPage('/'); // opens main page of website
400
- I.amOnPage('https://github.com'); // opens github
401
- I.amOnPage('/login'); // opens a login page
402
- ```
403
-
404
- @param url url path or global url.
405
- *
406
- * In a second argument a list of request headers can be passed:
407
- *
399
+ * If url starts with `/`, opens a web page of a site defined in `url` config parameter.
400
+ *
408
401
  * ```js
409
- * I.amOnPage('/auth', { 'x-my-custom-header': 'some value' })
402
+ * I.amOnPage('/'); // opens main page of website
403
+ * I.amOnPage('https://github.com'); // opens github
404
+ * I.amOnPage('/login'); // opens a login page
410
405
  * ```
406
+ *
407
+ * @param {string} url url path or global url.
408
+ * {--end--}
409
+ * @param headers {object} list of request headers can be passed
410
+ *
411
411
  */
412
412
  async amOnPage(url, headers = null) {
413
413
  if (!(/^\w+\:\/\//.test(url))) {
@@ -427,8 +427,13 @@ I.amOnPage('/login'); // opens a login page
427
427
 
428
428
  /**
429
429
  * Checks that title contains text.
430
-
431
- @param text text value to check.
430
+ *
431
+ * ```js
432
+ * I.seeInTitle('Home Page');
433
+ * ```
434
+ *
435
+ * @param {string} text text value to check.
436
+ * {--end--}
432
437
  */
433
438
  async seeInTitle(text) {
434
439
  const title = await this.browser.title();
@@ -437,8 +442,13 @@ I.amOnPage('/login'); // opens a login page
437
442
 
438
443
  /**
439
444
  * Checks that title does not contain text.
440
-
441
- @param text text value to check.
445
+ *
446
+ * ```js
447
+ * I.dontSeeInTitle('Error');
448
+ * ```
449
+ *
450
+ * @param {string} text value to check.
451
+ * {--end--}
442
452
  */
443
453
  async dontSeeInTitle(text) {
444
454
  const title = await this.browser.title();
@@ -447,11 +457,14 @@ I.amOnPage('/login'); // opens a login page
447
457
 
448
458
  /**
449
459
  * Retrieves a page title and returns it to test.
450
- Resumes test execution, so **should be used inside async with `await`** operator.
451
-
452
- ```js
453
- let title = await I.grabTitle();
454
- ```
460
+ * Resumes test execution, so **should be used inside async with `await`** operator.
461
+ *
462
+ * ```js
463
+ * let title = await I.grabTitle();
464
+ * ```
465
+ *
466
+ * @returns {Promise<string>} title
467
+ * {--end--}
455
468
  */
456
469
  async grabTitle() {
457
470
  return this.browser.title();
@@ -459,12 +472,15 @@ let title = await I.grabTitle();
459
472
 
460
473
  /**
461
474
  * Get current URL from browser.
462
- Resumes test execution, so should be used inside an async function.
463
-
464
- ```js
465
- let url = await I.grabCurrentUrl();
466
- console.log(`Current URL is [${url}]`);
467
- ```
475
+ * Resumes test execution, so should be used inside an async function.
476
+ *
477
+ * ```js
478
+ * let url = await I.grabCurrentUrl();
479
+ * console.log(`Current URL is [${url}]`);
480
+ * ```
481
+ *
482
+ * @returns {Promise<string>} current URL
483
+ * {--end--}
468
484
  */
469
485
  async grabCurrentUrl() {
470
486
  return this.browser.url();
@@ -472,12 +488,13 @@ console.log(`Current URL is [${url}]`);
472
488
 
473
489
  /**
474
490
  * Checks that current url contains a provided fragment.
475
-
476
- ```js
477
- I.seeInCurrentUrl('/register'); // we are on registration page
478
- ```
479
-
480
- @param url value to check.
491
+ *
492
+ * ```js
493
+ * I.seeInCurrentUrl('/register'); // we are on registration page
494
+ * ```
495
+ *
496
+ * @param {string} url a fragment to check
497
+ * {--end--}
481
498
  */
482
499
  async seeInCurrentUrl(url) {
483
500
  const currentUrl = await this.browser.url();
@@ -486,8 +503,9 @@ I.seeInCurrentUrl('/register'); // we are on registration page
486
503
 
487
504
  /**
488
505
  * Checks that current url does not contain a provided fragment.
489
-
490
- @param url value to check.
506
+ *
507
+ * @param {string} url value to check.
508
+ * {--end--}
491
509
  */
492
510
  async dontSeeInCurrentUrl(url) {
493
511
  const currentUrl = await this.browser.url();
@@ -496,15 +514,16 @@ I.seeInCurrentUrl('/register'); // we are on registration page
496
514
 
497
515
  /**
498
516
  * Checks that current url is equal to provided one.
499
- If a relative url provided, a configured url will be prepended to it.
500
- So both examples will work:
501
-
502
- ```js
503
- I.seeCurrentUrlEquals('/register');
504
- I.seeCurrentUrlEquals('http://my.site.com/register');
505
- ```
506
-
507
- @param url value to check.
517
+ * If a relative url provided, a configured url will be prepended to it.
518
+ * So both examples will work:
519
+ *
520
+ * ```js
521
+ * I.seeCurrentUrlEquals('/register');
522
+ * I.seeCurrentUrlEquals('http://my.site.com/register');
523
+ * ```
524
+ *
525
+ * @param {string} url value to check.
526
+ * {--end--}
508
527
  */
509
528
  async seeCurrentUrlEquals(url) {
510
529
  const currentUrl = await this.browser.url();
@@ -513,9 +532,15 @@ I.seeCurrentUrlEquals('http://my.site.com/register');
513
532
 
514
533
  /**
515
534
  * Checks that current url is not equal to provided one.
516
- If a relative url provided, a configured url will be prepended to it.
517
-
518
- @param url value to check.
535
+ * If a relative url provided, a configured url will be prepended to it.
536
+ *
537
+ * ```js
538
+ * I.dontSeeCurrentUrlEquals('/login'); // relative url are ok
539
+ * I.dontSeeCurrentUrlEquals('http://mysite.com/login'); // absolute urls are also ok
540
+ * ```
541
+ *
542
+ * @param {string} url value to check.
543
+ * {--end--}
519
544
  */
520
545
  async dontSeeCurrentUrlEquals(url) {
521
546
  const currentUrl = await this.browser.url();
@@ -524,15 +549,16 @@ If a relative url provided, a configured url will be prepended to it.
524
549
 
525
550
  /**
526
551
  * Checks that a page contains a visible text.
527
- Use context parameter to narrow down the search.
528
-
529
- ```js
530
- I.see('Welcome'); // text welcome on a page
531
- I.see('Welcome', '.content'); // text inside .content div
532
- I.see('Register', {css: 'form.register'}); // use strict locator
533
- ```
534
- @param text expected on page.
535
- @param context (optional) element located by CSS|Xpath|strict locator in which to search for text.
552
+ * Use context parameter to narrow down the search.
553
+ *
554
+ * ```js
555
+ * I.see('Welcome'); // text welcome on a page
556
+ * I.see('Welcome', '.content'); // text inside .content div
557
+ * I.see('Register', {css: 'form.register'}); // use strict locator
558
+ * ```
559
+ * @param {string} text expected on page.
560
+ * @param {string|object} context (optional, `null` by default) element located by CSS|Xpath|strict locator in which to search for text.
561
+ * {--end--}
536
562
  */
537
563
  async see(text, context = null) {
538
564
  return proceedSee.call(this, 'assert', text, context);
@@ -540,13 +566,17 @@ I.see('Register', {css: 'form.register'}); // use strict locator
540
566
 
541
567
  /**
542
568
  * Opposite to `see`. Checks that a text is not present on a page.
543
- Use context parameter to narrow down the search.
544
-
545
- ```js
546
- I.dontSee('Login'); // assume we are already logged in
547
- ```
548
- @param text is not present.
549
- @param context (optional) element located by CSS|XPath|strict locator in which to perfrom search.
569
+ * Use context parameter to narrow down the search.
570
+ *
571
+ * ```js
572
+ * I.dontSee('Login'); // assume we are already logged in.
573
+ * I.dontSee('Login', '.nav'); // no login inside .nav element
574
+ * ```
575
+ *
576
+ * @param {string} text which is not present.
577
+ * @param {string|object} context (optional) element located by CSS|XPath|strict locator in which to perfrom search.
578
+ *
579
+ * {--end--}
550
580
  */
551
581
  dontSee(text, context = null) {
552
582
  return proceedSee.call(this, 'negate', text, context);
@@ -554,12 +584,13 @@ I.dontSee('Login'); // assume we are already logged in
554
584
 
555
585
  /**
556
586
  * Checks that a given Element is visible
557
- Element is located by CSS or XPath.
558
-
559
- ```js
560
- I.seeElement('#modal');
561
- ```
562
- @param locator located by CSS|XPath|strict locator.
587
+ * Element is located by CSS or XPath.
588
+ *
589
+ * ```js
590
+ * I.seeElement('#modal');
591
+ * ```
592
+ * @param {string|object} locator located by CSS|XPath|strict locator.
593
+ * {--end--}
563
594
  */
564
595
  async seeElement(locator) {
565
596
  locator = new Locator(locator, 'css');
@@ -571,8 +602,13 @@ I.seeElement('#modal');
571
602
 
572
603
  /**
573
604
  * Opposite to `seeElement`. Checks that element is not visible (or in DOM)
574
-
575
- @param locator located by CSS|XPath|Strict locator.
605
+ *
606
+ * ```js
607
+ * I.dontSeeElement('.modal'); // modal is not shown
608
+ * ```
609
+ *
610
+ * @param {string|object} locator located by CSS|XPath|Strict locator.
611
+ * {--end--}
576
612
  */
577
613
  async dontSeeElement(locator) {
578
614
  locator = new Locator(locator, 'css');
@@ -585,12 +621,13 @@ I.seeElement('#modal');
585
621
 
586
622
  /**
587
623
  * Checks that a given Element is present in the DOM
588
- Element is located by CSS or XPath.
589
-
590
- ```js
591
- I.seeElementInDOM('#modal');
592
- ```
593
- @param locator located by CSS|XPath|strict locator.
624
+ * Element is located by CSS or XPath.
625
+ *
626
+ * ```js
627
+ * I.seeElementInDOM('#modal');
628
+ * ```
629
+ * @param {string|object} locator element located by CSS|XPath|strict locator.
630
+ * {--end--}
594
631
  */
595
632
  async seeElementInDOM(locator) {
596
633
  locator = new Locator(locator, 'css');
@@ -600,8 +637,13 @@ I.seeElementInDOM('#modal');
600
637
 
601
638
  /**
602
639
  * Opposite to `seeElementInDOM`. Checks that element is not on page.
603
-
604
- @param locator located by CSS|XPath|Strict locator.
640
+ *
641
+ * ```js
642
+ * I.dontSeeElementInDOM('.nav'); // checks that element is not on page visible or not
643
+ * ```
644
+ *
645
+ * @param {string|object} locator located by CSS|XPath|Strict locator.
646
+ * {--end--}
605
647
  */
606
648
  async dontSeeElementInDOM(locator) {
607
649
  locator = new Locator(locator, 'css');
@@ -611,11 +653,12 @@ I.seeElementInDOM('#modal');
611
653
 
612
654
  /**
613
655
  * Checks that the current page contains the given string in its raw source code.
614
-
615
- ```js
616
- I.seeInSource('<h1>Green eggs &amp; ham</h1>');
617
- ```
618
- @param text value to check.
656
+ *
657
+ * ```js
658
+ * I.seeInSource('<h1>Green eggs &amp; ham</h1>');
659
+ * ```
660
+ * @param {string} text value to check.
661
+ * {--end--}
619
662
  */
620
663
  async seeInSource(text) {
621
664
  const source = await this.browser.evaluate(() => document.documentElement.outerHTML);
@@ -624,9 +667,13 @@ I.seeInSource('<h1>Green eggs &amp; ham</h1>');
624
667
 
625
668
  /**
626
669
  * Checks that the current page does not contains the given string in its raw source code.
627
-
628
- @param text value to check.
629
-
670
+ *
671
+ * ```js
672
+ * I.dontSeeInSource('<!--'); // no comments in source
673
+ * ```
674
+ *
675
+ * @param {string} value to check.
676
+ * {--end--}
630
677
  */
631
678
  async dontSeeInSource(text) {
632
679
  const source = await this.browser.evaluate(() => document.documentElement.outerHTML);
@@ -634,28 +681,34 @@ I.seeInSource('<h1>Green eggs &amp; ham</h1>');
634
681
  }
635
682
 
636
683
  /**
637
- * asserts that an element appears a given number of times in the DOM
684
+ * Asserts that an element appears a given number of times in the DOM.
638
685
  * Element is located by label or name or CSS or XPath.
639
- *
686
+ *
687
+ *
640
688
  * ```js
641
689
  * I.seeNumberOfElements('#submitBtn', 1);
642
690
  * ```
691
+ *
692
+ * @param {string|object} locator element located by CSS|XPath|strict locator.
693
+ * @param {number} num number of elements.
694
+ * {--end--}
643
695
  */
644
- async seeNumberOfElements(selector, num) {
645
- const elements = await this._locate(selector);
646
- return equals(`expected number of elements (${selector}) is ${num}, but found ${elements.length}`).assert(elements.length, num);
696
+ async seeNumberOfElements(locator, num) {
697
+ const elements = await this._locate(locator);
698
+ return equals(`expected number of elements (${locator}) is ${num}, but found ${elements.length}`).assert(elements.length, num);
647
699
  }
648
700
 
649
701
  /**
650
702
  * Asserts that an element is visible a given number of times.
651
- Element is located by CSS or XPath.
652
-
653
- ```js
654
- I.seeNumberOfVisibleElements('.buttons', 3);
655
- ```
656
-
657
- @param locator element located by CSS|XPath|strict locator.
658
- @param num number of elements.
703
+ * Element is located by CSS or XPath.
704
+ *
705
+ * ```js
706
+ * I.seeNumberOfVisibleElements('.buttons', 3);
707
+ * ```
708
+ *
709
+ * @param {string|object} locator element located by CSS|XPath|strict locator.
710
+ * @param {number} num number of elements.
711
+ * {--end--}
659
712
  */
660
713
  async seeNumberOfVisibleElements(locator, num) {
661
714
  const res = await this.grabNumberOfVisibleElements(locator);
@@ -664,12 +717,14 @@ I.seeNumberOfVisibleElements('.buttons', 3);
664
717
 
665
718
  /**
666
719
  * Grab number of visible elements by locator.
667
-
668
- ```js
669
- I.grabNumberOfVisibleElements('p');
670
- ```
671
-
672
- @param locator located by CSS|XPath|strict locator.
720
+ *
721
+ * ```js
722
+ * let numOfElements = await I.grabNumberOfVisibleElements('p');
723
+ * ```
724
+ *
725
+ * @param {string|object} locator located by CSS|XPath|strict locator.
726
+ * @returns {Promise<number>} number of visible elements
727
+ * {--end--}
673
728
  */
674
729
  async grabNumberOfVisibleElements(locator) {
675
730
  locator = new Locator(locator, 'css');
@@ -684,29 +739,30 @@ I.grabNumberOfVisibleElements('p');
684
739
 
685
740
  /**
686
741
  * Perform a click on a link or a button, given by a locator.
687
- If a fuzzy locator is given, the page will be searched for a button, link, or image matching the locator string.
688
- For buttons, the "value" attribute, "name" attribute, and inner text are searched. For links, the link text is searched.
689
- For images, the "alt" attribute and inner text of any parent links are searched.
690
-
691
- The second parameter is a context (CSS or XPath locator) to narrow the search.
692
-
693
- ```js
694
- // simple link
695
- I.click('Logout');
696
- // button of form
697
- I.click('Submit');
698
- // CSS button
699
- I.click('#form input[type=submit]');
700
- // XPath
701
- I.click('//form/*[@type=submit]');
702
- // link in context
703
- I.click('Logout', '#nav');
704
- // using strict locator
705
- I.click({css: 'nav a.login'});
706
- ```
707
-
708
- @param locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
709
- @param context (optional) element to search in CSS|XPath|Strict locator.
742
+ * If a fuzzy locator is given, the page will be searched for a button, link, or image matching the locator string.
743
+ * For buttons, the "value" attribute, "name" attribute, and inner text are searched. For links, the link text is searched.
744
+ * For images, the "alt" attribute and inner text of any parent links are searched.
745
+ *
746
+ * The second parameter is a context (CSS or XPath locator) to narrow the search.
747
+ *
748
+ * ```js
749
+ * // simple link
750
+ * I.click('Logout');
751
+ * // button of form
752
+ * I.click('Submit');
753
+ * // CSS button
754
+ * I.click('#form input[type=submit]');
755
+ * // XPath
756
+ * I.click('//form/*[@type=submit]');
757
+ * // link in context
758
+ * I.click('Logout', '#nav');
759
+ * // using strict locator
760
+ * I.click({css: 'nav a.login'});
761
+ * ```
762
+ *
763
+ * @param {string|object} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
764
+ * @param {string|object} context (optional, `null` by default) element to search in CSS|XPath|Strict locator.
765
+ * {--end--}
710
766
  */
711
767
  async click(locator, context = null) {
712
768
  const el = await findClickable.call(this, locator, context);
@@ -717,17 +773,18 @@ I.click({css: 'nav a.login'});
717
773
 
718
774
  /**
719
775
  * Performs a double-click on an element matched by link|button|label|CSS or XPath.
720
- Context can be specified as second parameter to narrow search.
721
-
722
- ```js
723
- I.doubleClick('Edit');
724
- I.doubleClick('Edit', '.actions');
725
- I.doubleClick({css: 'button.accept'});
726
- I.doubleClick('.btn.edit');
727
- ```
728
-
729
- @param locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
730
- @param context (optional) element to search in CSS|XPath|Strict locator.
776
+ * Context can be specified as second parameter to narrow search.
777
+ *
778
+ * ```js
779
+ * I.doubleClick('Edit');
780
+ * I.doubleClick('Edit', '.actions');
781
+ * I.doubleClick({css: 'button.accept'});
782
+ * I.doubleClick('.btn.edit');
783
+ * ```
784
+ *
785
+ * @param {string|object} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
786
+ * @param {string|object} context (optional, `null` by default) element to search in CSS|XPath|Strict locator.
787
+ * {--end--}
731
788
  */
732
789
  async doubleClick(locator, context = null) {
733
790
  const el = await findClickable.call(this, locator, context);
@@ -739,19 +796,19 @@ I.doubleClick('.btn.edit');
739
796
 
740
797
  /**
741
798
  * Performs right click on a clickable element matched by semantic locator, CSS or XPath.
742
-
743
- ```js
744
- // right click element with id el
745
- I.rightClick('#el');
746
- // right click link or button with text "Click me"
747
- I.rightClick('Click me');
748
- // right click button with text "Click me" inside .context
749
- I.rightClick('Click me', '.context');
750
- ```
751
-
752
- @param locator clickable element located by CSS|XPath|strict locator.
753
- @param context (optional) element located by CSS|XPath|strict locator.
754
-
799
+ *
800
+ * ```js
801
+ * // right click element with id el
802
+ * I.rightClick('#el');
803
+ * // right click link or button with text "Click me"
804
+ * I.rightClick('Click me');
805
+ * // right click button with text "Click me" inside .context
806
+ * I.rightClick('Click me', '.context');
807
+ * ```
808
+ *
809
+ * @param {string|object} locator clickable element located by CSS|XPath|strict locator.
810
+ * @param {string|object} context (optional, `null` by default) element located by CSS|XPath|strict locator.
811
+ * {--end--}
755
812
  */
756
813
  async rightClick(locator, context = null) {
757
814
  const el = await findClickable.call(this, locator, context);
@@ -763,16 +820,17 @@ I.rightClick('Click me', '.context');
763
820
 
764
821
  /**
765
822
  * Moves cursor to element matched by locator.
766
- Extra shift can be set with offsetX and offsetY options.
767
-
768
- ```js
769
- I.moveCursorTo('.tooltip');
770
- I.moveCursorTo('#submit', 5,5);
771
- ```
772
-
773
- @param locator located by CSS|XPath|strict locator.
774
- @param offsetX (optional) X-axis offset.
775
- @param offsetY (optional) Y-axis offset.
823
+ * Extra shift can be set with offsetX and offsetY options.
824
+ *
825
+ * ```js
826
+ * I.moveCursorTo('.tooltip');
827
+ * I.moveCursorTo('#submit', 5,5);
828
+ * ```
829
+ *
830
+ * @param {string|object} locator located by CSS|XPath|strict locator.
831
+ * @param {number} offsetX (optional, `0` by default) X-axis offset.
832
+ * @param {number} offsetY (optional, `0` by default) Y-axis offset.
833
+ * {--end--}
776
834
  */
777
835
  async moveCursorTo(locator, offsetX = 0, offsetY = 0) {
778
836
  locator = new Locator(locator, 'css');
@@ -785,30 +843,31 @@ I.moveCursorTo('#submit', 5,5);
785
843
 
786
844
  /**
787
845
  * Executes sync script on a page.
788
- Pass arguments to function as additional parameters.
789
- Will return execution result to a test.
790
- In this case you should use async function and await to receive results.
791
-
792
- Example with jQuery DatePicker:
793
-
794
- ```js
795
- // change date of jQuery DatePicker
796
- I.executeScript(function() {
797
- // now we are inside browser context
798
- $('date').datetimepicker('setDate', new Date());
799
- });
800
- ```
801
- Can return values. Don't forget to use `await` to get them.
802
-
803
- ```js
804
- let date = await I.executeScript(function(el) {
805
- // only basic types can be returned
806
- return $(el).datetimepicker('getDate').toString();
807
- }, '#date'); // passing jquery selector
808
- ```
809
-
810
- @param fn function to be executed in browser context.
811
- @param ...args args to be passed to function.
846
+ * Pass arguments to function as additional parameters.
847
+ * Will return execution result to a test.
848
+ * In this case you should use async function and await to receive results.
849
+ *
850
+ * Example with jQuery DatePicker:
851
+ *
852
+ * ```js
853
+ * // change date of jQuery DatePicker
854
+ * I.executeScript(function() {
855
+ * // now we are inside browser context
856
+ * $('date').datetimepicker('setDate', new Date());
857
+ * });
858
+ * ```
859
+ * Can return values. Don't forget to use `await` to get them.
860
+ *
861
+ * ```js
862
+ * let date = await I.executeScript(function(el) {
863
+ * // only basic types can be returned
864
+ * return $(el).datetimepicker('getDate').toString();
865
+ * }, '#date'); // passing jquery selector
866
+ * ```
867
+ *
868
+ * @param {string|function} fn function to be executed in browser context.
869
+ * @param ...args args to be passed to function.
870
+ * {--end--}
812
871
  *
813
872
  * Wrapper for synchronous [evaluate](https://github.com/segmentio/nightmare#evaluatefn-arg1-arg2)
814
873
  */
@@ -819,28 +878,29 @@ let date = await I.executeScript(function(el) {
819
878
 
820
879
  /**
821
880
  * Executes async script on page.
822
- Provided function should execute a passed callback (as first argument) to signal it is finished.
823
-
824
- Example: In Vue.js to make components completely rendered we are waiting for [nextTick](https://vuejs.org/v2/api/#Vue-nextTick).
825
-
826
- ```js
827
- I.executeAsyncScript(function(done) {
828
- Vue.nextTick(done); // waiting for next tick
829
- });
830
- ```
831
-
832
- By passing value to `done()` function you can return values.
833
- Additional arguments can be passed as well, while `done` function is always last parameter in arguments list.
834
-
835
- ```js
836
- let val = await I.executeAsyncScript(function(url, done) {
837
- // in browser context
838
- $.ajax(url, { success: (data) => done(data); }
839
- }, 'http://ajax.callback.url/');
840
- ```
841
-
842
- @param fn function to be executed in browser context.
843
- @param ...args args to be passed to function.
881
+ * Provided function should execute a passed callback (as first argument) to signal it is finished.
882
+ *
883
+ * Example: In Vue.js to make components completely rendered we are waiting for [nextTick](https://vuejs.org/v2/api/#Vue-nextTick).
884
+ *
885
+ * ```js
886
+ * I.executeAsyncScript(function(done) {
887
+ * Vue.nextTick(done); // waiting for next tick
888
+ * });
889
+ * ```
890
+ *
891
+ * By passing value to `done()` function you can return values.
892
+ * Additional arguments can be passed as well, while `done` function is always last parameter in arguments list.
893
+ *
894
+ * ```js
895
+ * let val = await I.executeAsyncScript(function(url, done) {
896
+ * // in browser context
897
+ * $.ajax(url, { success: (data) => done(data); }
898
+ * }, 'http://ajax.callback.url/');
899
+ * ```
900
+ *
901
+ * @param {string|function} fn function to be executed in browser context.
902
+ * @param ...args args to be passed to function.
903
+ * {--end--}
844
904
  *
845
905
  * Wrapper for asynchronous [evaluate](https://github.com/segmentio/nightmare#evaluatefn-arg1-arg2).
846
906
  * Unlike NightmareJS implementation calling `done` will return its first argument.
@@ -852,10 +912,11 @@ let val = await I.executeAsyncScript(function(url, done) {
852
912
 
853
913
  /**
854
914
  * Resize the current window to provided width and height.
855
- First parameter can be set to `maximize`.
856
-
857
- @param width width in pixels or `maximize`.
858
- @param height height in pixels.
915
+ * First parameter can be set to `maximize`.
916
+ *
917
+ * @param {number} width width in pixels or `maximize`.
918
+ * @param {number} height height in pixels.
919
+ * {--end--}
859
920
  */
860
921
  async resizeWindow(width, height) {
861
922
  if (width === 'maximize') {
@@ -866,17 +927,18 @@ First parameter can be set to `maximize`.
866
927
 
867
928
  /**
868
929
  * Selects a checkbox or radio button.
869
- Element is located by label or name or CSS or XPath.
870
-
871
- The second parameter is a context (CSS or XPath locator) to narrow the search.
872
-
873
- ```js
874
- I.checkOption('#agree');
875
- I.checkOption('I Agree to Terms and Conditions');
876
- I.checkOption('agree', '//form');
877
- ```
878
- @param field checkbox located by label | name | CSS | XPath | strict locator.
879
- @param context (optional) element located by CSS | XPath | strict locator.
930
+ * Element is located by label or name or CSS or XPath.
931
+ *
932
+ * The second parameter is a context (CSS or XPath locator) to narrow the search.
933
+ *
934
+ * ```js
935
+ * I.checkOption('#agree');
936
+ * I.checkOption('I Agree to Terms and Conditions');
937
+ * I.checkOption('agree', '//form');
938
+ * ```
939
+ * @param {string|object} field checkbox located by label | name | CSS | XPath | strict locator.
940
+ * @param {string} context (optional, `null` by default) element located by CSS | XPath | strict locator.
941
+ * {--end--}
880
942
  */
881
943
  async checkOption(field, context = null) {
882
944
  const els = await findCheckable.call(this, field, context);
@@ -886,22 +948,44 @@ I.checkOption('agree', '//form');
886
948
  }
887
949
 
888
950
  /**
889
- * Fills a text field or textarea, after clearing its value, with the given string.
890
- Field is located by name, label, CSS, or XPath.
891
-
892
- ```js
893
- // by label
894
- I.fillField('Email', 'hello@world.com');
895
- // by name
896
- I.fillField('password', secret('123456'));
897
- // by CSS
898
- I.fillField('form#login input[name=username]', 'John');
899
- // or by strict locator
900
- I.fillField({css: 'form#login input[name=username]'}, 'John');
901
- ```
902
- @param field located by label|name|CSS|XPath|strict locator.
903
- @param value text value to fill.
951
+ * Unselects a checkbox or radio button.
952
+ * Element is located by label or name or CSS or XPath.
953
+ *
954
+ * The second parameter is a context (CSS or XPath locator) to narrow the search.
955
+ *
956
+ * ```js
957
+ * I.uncheckOption('#agree');
958
+ * I.uncheckOption('I Agree to Terms and Conditions');
959
+ * I.uncheckOption('agree', '//form');
960
+ * ```
961
+ * @param {string|object} field checkbox located by label | name | CSS | XPath | strict locator.
962
+ * @param {string} context (optional, `null` by default) element located by CSS | XPath | strict locator.
963
+ * {--end--}
964
+ */
965
+ async uncheckOption(field, context = null) {
966
+ const els = await findCheckable.call(this, field, context);
967
+ assertElementExists(els[0], field, 'Checkbox or radio');
968
+ return this.browser.evaluate(els => window.codeceptjs.unCheckEl(els[0]), els)
969
+ .wait(this.options.waitForAction);
970
+ }
904
971
 
972
+ /**
973
+ * Fills a text field or textarea, after clearing its value, with the given string.
974
+ * Field is located by name, label, CSS, or XPath.
975
+ *
976
+ * ```js
977
+ * // by label
978
+ * I.fillField('Email', 'hello@world.com');
979
+ * // by name
980
+ * I.fillField('password', secret('123456'));
981
+ * // by CSS
982
+ * I.fillField('form#login input[name=username]', 'John');
983
+ * // or by strict locator
984
+ * I.fillField({css: 'form#login input[name=username]'}, 'John');
985
+ * ```
986
+ * @param {string|object} field located by label|name|CSS|XPath|strict locator.
987
+ * @param {string} value text value to fill.
988
+ * {--end--}
905
989
  */
906
990
  async fillField(field, value) {
907
991
  const el = await findField.call(this, field);
@@ -912,13 +996,14 @@ I.fillField({css: 'form#login input[name=username]'}, 'John');
912
996
 
913
997
  /**
914
998
  * Clears a `<textarea>` or text `<input>` element's value.
915
-
916
- ```js
917
- I.clearField('Email');
918
- I.clearField('user[email]');
919
- I.clearField('#email');
920
- ```
921
- @param field located by label|name|CSS|XPath|strict locator.
999
+ *
1000
+ * ```js
1001
+ * I.clearField('Email');
1002
+ * I.clearField('user[email]');
1003
+ * I.clearField('#email');
1004
+ * ```
1005
+ * @param {string|object} editable field located by label|name|CSS|XPath|strict locator.
1006
+ * {--end--}
922
1007
  */
923
1008
  async clearField(field) {
924
1009
  return this.fillField(field, '');
@@ -926,13 +1011,14 @@ I.clearField('#email');
926
1011
 
927
1012
  /**
928
1013
  * Appends text to a input field or textarea.
929
- Field is located by name, label, CSS or XPath
930
-
931
- ```js
932
- I.appendField('#myTextField', 'appended');
933
- ```
934
- @param field located by label|name|CSS|XPath|strict locator
935
- @param value text value to append.
1014
+ * Field is located by name, label, CSS or XPath
1015
+ *
1016
+ * ```js
1017
+ * I.appendField('#myTextField', 'appended');
1018
+ * ```
1019
+ * @param {string|object} field located by label|name|CSS|XPath|strict locator
1020
+ * @param {string} value text value to append.
1021
+ * {--end--}
936
1022
  */
937
1023
  async appendField(field, value) {
938
1024
  const el = await findField.call(this, field);
@@ -943,16 +1029,17 @@ I.appendField('#myTextField', 'appended');
943
1029
 
944
1030
  /**
945
1031
  * Checks that the given input field or textarea equals to given value.
946
- For fuzzy locators, fields are matched by label text, the "name" attribute, CSS, and XPath.
947
-
948
- ```js
949
- I.seeInField('Username', 'davert');
950
- I.seeInField({css: 'form textarea'},'Type your comment here');
951
- I.seeInField('form input[type=hidden]','hidden_value');
952
- I.seeInField('#searchform input','Search');
953
- ```
954
- @param field located by label|name|CSS|XPath|strict locator.
955
- @param value value to check.
1032
+ * For fuzzy locators, fields are matched by label text, the "name" attribute, CSS, and XPath.
1033
+ *
1034
+ * ```js
1035
+ * I.seeInField('Username', 'davert');
1036
+ * I.seeInField({css: 'form textarea'},'Type your comment here');
1037
+ * I.seeInField('form input[type=hidden]','hidden_value');
1038
+ * I.seeInField('#searchform input','Search');
1039
+ * ```
1040
+ * @param {string|object} field located by label|name|CSS|XPath|strict locator.
1041
+ * @param {string} value value to check.
1042
+ * {--end--}
956
1043
  */
957
1044
  async seeInField(field, value) {
958
1045
  return proceedSeeInField.call(this, 'assert', field, value);
@@ -960,10 +1047,16 @@ I.seeInField('#searchform input','Search');
960
1047
 
961
1048
  /**
962
1049
  * Checks that value of input field or textare doesn't equal to given value
963
- Opposite to `seeInField`.
964
-
965
- @param field located by label|name|CSS|XPath|strict locator.
966
- @param value value to check.
1050
+ * Opposite to `seeInField`.
1051
+ *
1052
+ * ```js
1053
+ * I.dontSeeInField('email', 'user@user.com'); // field by name
1054
+ * I.dontSeeInField({ css: 'form input.email' }, 'user@user.com'); // field by CSS
1055
+ * ```
1056
+ *
1057
+ * @param {string|object} field located by label|name|CSS|XPath|strict locator.
1058
+ * @param {string} value value to check.
1059
+ * {--end--}
967
1060
  */
968
1061
  async dontSeeInField(field, value) {
969
1062
  return proceedSeeInField.call(this, 'negate', field, value);
@@ -999,13 +1092,15 @@ Opposite to `seeInField`.
999
1092
 
1000
1093
  /**
1001
1094
  * Verifies that the specified checkbox is checked.
1002
-
1003
- ```js
1004
- I.seeCheckboxIsChecked('Agree');
1005
- I.seeCheckboxIsChecked('#agree'); // I suppose user agreed to terms
1006
- I.seeCheckboxIsChecked({css: '#signup_form input[type=checkbox]'});
1007
- ```
1008
- @param field located by label|name|CSS|XPath|strict locator.
1095
+ *
1096
+ * ```js
1097
+ * I.seeCheckboxIsChecked('Agree');
1098
+ * I.seeCheckboxIsChecked('#agree'); // I suppose user agreed to terms
1099
+ * I.seeCheckboxIsChecked({css: '#signup_form input[type=checkbox]'});
1100
+ * ```
1101
+ *
1102
+ * @param {string|object} field located by label|name|CSS|XPath|strict locator.
1103
+ * {--end--}
1009
1104
  */
1010
1105
  async seeCheckboxIsChecked(field) {
1011
1106
  return proceedIsChecked.call(this, 'assert', field);
@@ -1013,8 +1108,15 @@ I.seeCheckboxIsChecked({css: '#signup_form input[type=checkbox]'});
1013
1108
 
1014
1109
  /**
1015
1110
  * Verifies that the specified checkbox is not checked.
1016
-
1017
- @param field located by label|name|CSS|XPath|strict locator.
1111
+ *
1112
+ * ```js
1113
+ * I.dontSeeeCheckboxIsChedcked('#agree'); // located by ID
1114
+ * I.dontSeeeCheckboxIsChedcked('I agree to terms'); // located by label
1115
+ * I.dontSeeeCheckboxIsChedcked('agree'); // located by name
1116
+ * ```
1117
+ *
1118
+ * @param {string|object} field located by label|name|CSS|XPath|strict locator.
1119
+ * {--end--}
1018
1120
  */
1019
1121
  async dontSeeCheckboxIsChecked(field) {
1020
1122
  return proceedIsChecked.call(this, 'negate', field);
@@ -1022,21 +1124,21 @@ I.seeCheckboxIsChecked({css: '#signup_form input[type=checkbox]'});
1022
1124
 
1023
1125
  /**
1024
1126
  * Attaches a file to element located by label, name, CSS or XPath
1025
- Path to file is relative current codecept directory (where codecept.json or codecept.conf.js is located).
1026
- File will be uploaded to remote system (if tests are running remotely).
1027
-
1028
- ```js
1029
- I.attachFile('Avatar', 'data/avatar.jpg');
1030
- I.attachFile('form input[name=avatar]', 'data/avatar.jpg');
1031
- ```
1032
-
1033
- @param locator field located by label|name|CSS|XPath|strict locator.
1034
- @param pathToFile local file path relative to codecept.json config file.
1127
+ * Path to file is relative current codecept directory (where codecept.json or codecept.conf.js is located).
1128
+ * File will be uploaded to remote system (if tests are running remotely).
1129
+ *
1130
+ * ```js
1131
+ * I.attachFile('Avatar', 'data/avatar.jpg');
1132
+ * I.attachFile('form input[name=avatar]', 'data/avatar.jpg');
1133
+ * ```
1134
+ *
1135
+ * @param {string|object} locator field located by label|name|CSS|XPath|strict locator.
1136
+ * @param {string} pathToFile local file path relative to codecept.json config file.
1137
+ * {--end--}
1035
1138
  *
1036
- * ##### Limitations:
1139
+ * Doesn't work if the Chromium DevTools panel is open (as Chromium allows only one attachment to the debugger at a time. [See more](https://github.com/rosshinkley/nightmare-upload#important-note-about-setting-file-upload-inputs))
1037
1140
  *
1038
- * * works only with CSS selectors.
1039
- * * doesn't work if the Chromium DevTools panel is open (as Chromium allows only one attachment to the debugger at a time. [See more](https://github.com/rosshinkley/nightmare-upload#important-note-about-setting-file-upload-inputs))
1141
+ * @param locator CSS locator (XPath not allowed)
1040
1142
  */
1041
1143
  async attachFile(locator, pathToFile) {
1042
1144
  const file = path.join(global.codecept_dir, pathToFile);
@@ -1054,14 +1156,16 @@ I.attachFile('form input[name=avatar]', 'data/avatar.jpg');
1054
1156
 
1055
1157
  /**
1056
1158
  * Retrieves a text from an element located by CSS or XPath and returns it to test.
1057
- Resumes test execution, so **should be used inside async with `await`** operator.
1058
-
1059
- ```js
1060
- let pin = await I.grabTextFrom('#pin');
1061
- ```
1062
- If multiple elements found returns an array of texts.
1063
-
1064
- @param locator element located by CSS|XPath|strict locator.
1159
+ * Resumes test execution, so **should be used inside async with `await`** operator.
1160
+ *
1161
+ * ```js
1162
+ * let pin = await I.grabTextFrom('#pin');
1163
+ * ```
1164
+ * If multiple elements found returns an array of texts.
1165
+ *
1166
+ * @param locator element located by CSS|XPath|strict locator.
1167
+ * @returns {Promise<string>} attribute value
1168
+ * {--end--}
1065
1169
  */
1066
1170
  async grabTextFrom(locator) {
1067
1171
  locator = new Locator(locator, 'css');
@@ -1078,12 +1182,14 @@ If multiple elements found returns an array of texts.
1078
1182
 
1079
1183
  /**
1080
1184
  * Retrieves a value from a form element located by CSS or XPath and returns it to test.
1081
- Resumes test execution, so **should be used inside async function with `await`** operator.
1082
-
1083
- ```js
1084
- let email = await I.grabValueFrom('input[name=email]');
1085
- ```
1086
- @param locator field located by label|name|CSS|XPath|strict locator.
1185
+ * Resumes test execution, so **should be used inside async function with `await`** operator.
1186
+ *
1187
+ * ```js
1188
+ * let email = await I.grabValueFrom('input[name=email]');
1189
+ * ```
1190
+ * @param {string|object} locator field located by label|name|CSS|XPath|strict locator.
1191
+ * @returns {Promise<string>} attribute value
1192
+ * {--end--}
1087
1193
  */
1088
1194
  async grabValueFrom(locator) {
1089
1195
  const el = await findField.call(this, locator);
@@ -1093,14 +1199,16 @@ let email = await I.grabValueFrom('input[name=email]');
1093
1199
 
1094
1200
  /**
1095
1201
  * Retrieves an attribute from an element located by CSS or XPath and returns it to test.
1096
- An array as a result will be returned if there are more than one matched element.
1097
- Resumes test execution, so **should be used inside async with `await`** operator.
1098
-
1099
- ```js
1100
- let hint = await I.grabAttributeFrom('#tooltip', 'title');
1101
- ```
1102
- @param locator element located by CSS|XPath|strict locator.
1103
- @param attr attribute name.
1202
+ * An array as a result will be returned if there are more than one matched element.
1203
+ * Resumes test execution, so **should be used inside async with `await`** operator.
1204
+ *
1205
+ * ```js
1206
+ * let hint = await I.grabAttributeFrom('#tooltip', 'title');
1207
+ * ```
1208
+ * @param {string|object} locator element located by CSS|XPath|strict locator.
1209
+ * @param {string} attr attribute name.
1210
+ * @returns {Promise<string>} attribute value
1211
+ * {--end--}
1104
1212
  */
1105
1213
  async grabAttributeFrom(locator, attr) {
1106
1214
  locator = new Locator(locator, 'css');
@@ -1118,14 +1226,16 @@ let hint = await I.grabAttributeFrom('#tooltip', 'title');
1118
1226
 
1119
1227
  /**
1120
1228
  * Retrieves the innerHTML from an element located by CSS or XPath and returns it to test.
1121
- Resumes test execution, so **should be used inside async function with `await`** operator.
1122
- If more than one element is found - an array of HTMLs returned.
1123
-
1124
- ```js
1125
- let postHTML = await I.grabHTMLFrom('#post');
1126
- ```
1127
-
1128
- @param locator element located by CSS|XPath|strict locator.
1229
+ * Resumes test execution, so **should be used inside async function with `await`** operator.
1230
+ * If more than one element is found - an array of HTMLs returned.
1231
+ *
1232
+ * ```js
1233
+ * let postHTML = await I.grabHTMLFrom('#post');
1234
+ * ```
1235
+ *
1236
+ * @param locator element located by CSS|XPath|strict locator.
1237
+ * @returns {Promise<string>} HTML code for an element
1238
+ * {--end--}
1129
1239
  */
1130
1240
  async grabHTMLFrom(locator) {
1131
1241
  locator = new Locator(locator, 'css');
@@ -1149,25 +1259,26 @@ let postHTML = await I.grabHTMLFrom('#post');
1149
1259
 
1150
1260
  /**
1151
1261
  * Selects an option in a drop-down select.
1152
- Field is searched by label | name | CSS | XPath.
1153
- Option is selected by visible text or by value.
1154
-
1155
- ```js
1156
- I.selectOption('Choose Plan', 'Monthly'); // select by label
1157
- I.selectOption('subscription', 'Monthly'); // match option by text
1158
- I.selectOption('subscription', '0'); // or by value
1159
- I.selectOption('//form/select[@name=account]','Premium');
1160
- I.selectOption('form select[name=account]', 'Premium');
1161
- I.selectOption({css: 'form select[name=account]'}, 'Premium');
1162
- ```
1163
-
1164
- Provide an array for the second argument to select multiple options.
1165
-
1166
- ```js
1167
- I.selectOption('Which OS do you use?', ['Android', 'iOS']);
1168
- ```
1169
- @param select field located by label|name|CSS|XPath|strict locator.
1170
- @param option visible text or value of option.
1262
+ * Field is searched by label | name | CSS | XPath.
1263
+ * Option is selected by visible text or by value.
1264
+ *
1265
+ * ```js
1266
+ * I.selectOption('Choose Plan', 'Monthly'); // select by label
1267
+ * I.selectOption('subscription', 'Monthly'); // match option by text
1268
+ * I.selectOption('subscription', '0'); // or by value
1269
+ * I.selectOption('//form/select[@name=account]','Premium');
1270
+ * I.selectOption('form select[name=account]', 'Premium');
1271
+ * I.selectOption({css: 'form select[name=account]'}, 'Premium');
1272
+ * ```
1273
+ *
1274
+ * Provide an array for the second argument to select multiple options.
1275
+ *
1276
+ * ```js
1277
+ * I.selectOption('Which OS do you use?', ['Android', 'iOS']);
1278
+ * ```
1279
+ * @param {string|object} select field located by label|name|CSS|XPath|strict locator.
1280
+ * @param {string|array} option visible text or value of option.
1281
+ * {--end--}
1171
1282
  */
1172
1283
  async selectOption(select, option) {
1173
1284
  const fetchAndCheckOption = function (el, locator) {
@@ -1211,12 +1322,13 @@ I.selectOption('Which OS do you use?', ['Android', 'iOS']);
1211
1322
 
1212
1323
  /**
1213
1324
  * Sets a cookie.
1214
-
1215
- ```js
1216
- I.setCookie({name: 'auth', value: true});
1217
- ```
1218
-
1219
- @param cookie cookie JSON object.
1325
+ *
1326
+ * ```js
1327
+ * I.setCookie({name: 'auth', value: true});
1328
+ * ```
1329
+ *
1330
+ * @param {object} cookie a cookie object.
1331
+ * {--end--}
1220
1332
  *
1221
1333
  * Wrapper for `.cookies.set(cookie)`.
1222
1334
  * [See more](https://github.com/segmentio/nightmare/blob/master/Readme.md#cookiessetcookie)
@@ -1227,12 +1339,13 @@ I.setCookie({name: 'auth', value: true});
1227
1339
 
1228
1340
  /**
1229
1341
  * Checks that cookie with given name exists.
1230
-
1231
- ```js
1232
- I.seeCookie('Auth');
1233
- ```
1234
-
1235
- @param name cookie name.
1342
+ *
1343
+ * ```js
1344
+ * I.seeCookie('Auth');
1345
+ * ```
1346
+ *
1347
+ * @param {string} name cookie name.
1348
+ * {--end--}
1236
1349
  *
1237
1350
  */
1238
1351
  async seeCookie(name) {
@@ -1242,8 +1355,13 @@ I.seeCookie('Auth');
1242
1355
 
1243
1356
  /**
1244
1357
  * Checks that cookie with given name does not exist.
1245
-
1246
- @param name cookie name.
1358
+ *
1359
+ * ```js
1360
+ * I.dontSeeCookie('auth'); // no auth cookie
1361
+ * ```
1362
+ *
1363
+ * @param {string} name cookie name.
1364
+ * {--end--}
1247
1365
  */
1248
1366
  async dontSeeCookie(name) {
1249
1367
  const res = await this.browser.cookies.get(name);
@@ -1252,25 +1370,21 @@ I.seeCookie('Auth');
1252
1370
 
1253
1371
  /**
1254
1372
  * Gets a cookie object by name.
1255
- If none provided gets all cookies.
1256
- * Resumes test execution, so **should be used inside async with `await`** operator.
1257
-
1258
- ```js
1259
- let cookie = await I.grabCookie('auth');
1260
- assert(cookie.value, '123456');
1261
- ```
1262
-
1263
- @param name (optional) cookie name.
1264
- *
1265
- * Returns cookie in JSON format. If name not passed returns all cookies for this domain.
1266
- *
1267
- * Multiple cookies can be received by passing query object:
1268
- *
1373
+ * If none provided gets all cookies.
1374
+ * * Resumes test execution, so **should be used inside async with `await`** operator.
1375
+ *
1269
1376
  * ```js
1270
- * I.grabCookie({ secure: true});
1377
+ * let cookie = await I.grabCookie('auth');
1378
+ * assert(cookie.value, '123456');
1271
1379
  * ```
1380
+ *
1381
+ * @param [name=null] cookie name.
1382
+ * @returns {Promise<string>} attribute value
1383
+ * {--end--}
1384
+ *
1385
+ * @returns Promise<object> Cookie in JSON format. If name not passed returns all cookies for this domain.
1272
1386
  *
1273
- * If you'd like get all cookies for all urls, use: `.grabCookie({ url: null }).`
1387
+ * Multiple cookies can be received by passing query object `I.grabCookie({ secure: true});`. If you'd like get all cookies for all urls, use: `.grabCookie({ url: null }).`
1274
1388
  */
1275
1389
  async grabCookie(name) {
1276
1390
  return this.browser.cookies.get(name);
@@ -1278,14 +1392,15 @@ assert(cookie.value, '123456');
1278
1392
 
1279
1393
  /**
1280
1394
  * Clears a cookie by name,
1281
- if none provided clears all cookies.
1282
-
1283
- ```js
1284
- I.clearCookie();
1285
- I.clearCookie('test');
1286
- ```
1287
-
1288
- @param cookie (optional) cookie name.
1395
+ * if none provided clears all cookies.
1396
+ *
1397
+ * ```js
1398
+ * I.clearCookie();
1399
+ * I.clearCookie('test');
1400
+ * ```
1401
+ *
1402
+ * @param {string} cookie (optional, `null` by default) cookie name
1403
+ * {--end--}
1289
1404
  */
1290
1405
  async clearCookie(cookie) {
1291
1406
  if (!cookie) {
@@ -1296,21 +1411,22 @@ I.clearCookie('test');
1296
1411
 
1297
1412
  /**
1298
1413
  * Waits for a function to return true (waits for 1 sec by default).
1299
- Running in browser context.
1300
-
1301
- ```js
1302
- I.waitForFunction(fn[, [args[, timeout]])
1303
- ```
1304
-
1305
- ```js
1306
- I.waitForFunction(() => window.requests == 0);
1307
- I.waitForFunction(() => window.requests == 0, 5); // waits for 5 sec
1308
- I.waitForFunction((count) => window.requests == count, [3], 5) // pass args and wait for 5 sec
1309
- ```
1310
-
1311
- @param fn to be executed in browser context.
1312
- @param argsOrSec (optional) arguments for function or seconds.
1313
- @param sec (optional) time in seconds to wait, 1 by default.
1414
+ * Running in browser context.
1415
+ *
1416
+ * ```js
1417
+ * I.waitForFunction(fn[, [args[, timeout]])
1418
+ * ```
1419
+ *
1420
+ * ```js
1421
+ * I.waitForFunction(() => window.requests == 0);
1422
+ * I.waitForFunction(() => window.requests == 0, 5); // waits for 5 sec
1423
+ * I.waitForFunction((count) => window.requests == count, [3], 5) // pass args and wait for 5 sec
1424
+ * ```
1425
+ *
1426
+ * @param {string|function} fn to be executed in browser context.
1427
+ * @param {array|number} argsOrSec (optional, `1` by default) arguments for function or seconds.
1428
+ * @param {number} sec (optional, `1` by default) time in seconds to wait
1429
+ * {--end--}
1314
1430
  */
1315
1431
  async waitForFunction(fn, argsOrSec = null, sec = null) {
1316
1432
  let args = [];
@@ -1327,13 +1443,13 @@ I.waitForFunction((count) => window.requests == count, [3], 5) // pass args and
1327
1443
 
1328
1444
  /**
1329
1445
  * Pauses execution for a number of seconds.
1330
-
1331
- ```js
1332
- I.wait(2); // wait 2 secs
1333
- ```
1334
-
1335
- @param sec number of second to wait.
1336
- @param sec time in seconds to wait.
1446
+ *
1447
+ * ```js
1448
+ * I.wait(2); // wait 2 secs
1449
+ * ```
1450
+ *
1451
+ * @param {number} sec number of second to wait.
1452
+ * {--end--}
1337
1453
  */
1338
1454
  async wait(sec) {
1339
1455
  return new Promise(((done) => {
@@ -1343,17 +1459,18 @@ I.wait(2); // wait 2 secs
1343
1459
 
1344
1460
  /**
1345
1461
  * Waits for a text to appear (by default waits for 1sec).
1346
- Element can be located by CSS or XPath.
1347
- Narrow down search results by providing context.
1348
-
1349
- ```js
1350
- I.waitForText('Thank you, form has been submitted');
1351
- I.waitForText('Thank you, form has been submitted', 5, '#modal');
1352
- ```
1353
-
1354
- @param text to wait for.
1355
- @param sec (optional) time in seconds to wait.
1356
- @param context (optional) element located by CSS|XPath|strict locator.
1462
+ * Element can be located by CSS or XPath.
1463
+ * Narrow down search results by providing context.
1464
+ *
1465
+ * ```js
1466
+ * I.waitForText('Thank you, form has been submitted');
1467
+ * I.waitForText('Thank you, form has been submitted', 5, '#modal');
1468
+ * ```
1469
+ *
1470
+ * @param {string }text to wait for.
1471
+ * @param {number} sec (optional, `1` by default) time in seconds to wait
1472
+ * @param {string|object} context (optional) element located by CSS|XPath|strict locator.
1473
+ * {--end--}
1357
1474
  */
1358
1475
  async waitForText(text, sec, context = null) {
1359
1476
  if (!context) {
@@ -1374,14 +1491,15 @@ I.waitForText('Thank you, form has been submitted', 5, '#modal');
1374
1491
 
1375
1492
  /**
1376
1493
  * Waits for an element to become visible on a page (by default waits for 1sec).
1377
- Element can be located by CSS or XPath.
1378
-
1379
- ```
1380
- I.waitForVisible('#popup');
1381
- ```
1382
-
1383
- @param locator element located by CSS|XPath|strict locator.
1384
- @param sec (optional) time in seconds to wait, 1 by default.
1494
+ * Element can be located by CSS or XPath.
1495
+ *
1496
+ * ```js
1497
+ * I.waitForVisible('#popup');
1498
+ * ```
1499
+ *
1500
+ * @param {string|object} locator element located by CSS|XPath|strict locator.
1501
+ * @param {number} sec (optional, `1` by default) time in seconds to wait
1502
+ * {--end--}
1385
1503
  */
1386
1504
  waitForVisible(locator, sec) {
1387
1505
  this.browser.options.waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
@@ -1400,14 +1518,15 @@ I.waitForVisible('#popup');
1400
1518
 
1401
1519
  /**
1402
1520
  * Waits for an element to hide (by default waits for 1sec).
1403
- Element can be located by CSS or XPath.
1404
-
1405
- ```
1406
- I.waitToHide('#popup');
1407
- ```
1408
-
1409
- @param locator element located by CSS|XPath|strict locator.
1410
- @param sec (optional) time in seconds to wait, 1 by default.
1521
+ * Element can be located by CSS or XPath.
1522
+ *
1523
+ * ```js
1524
+ * I.waitToHide('#popup');
1525
+ * ```
1526
+ *
1527
+ * @param {string|object} locator element located by CSS|XPath|strict locator.
1528
+ * @param {number} sec (optional, `1` by default) time in seconds to wait
1529
+ * {--end--}
1411
1530
  */
1412
1531
  async waitToHide(locator, sec = null) {
1413
1532
  return this.waitForInvisible(locator, sec);
@@ -1415,14 +1534,15 @@ I.waitToHide('#popup');
1415
1534
 
1416
1535
  /**
1417
1536
  * Waits for an element to be removed or become invisible on a page (by default waits for 1sec).
1418
- Element can be located by CSS or XPath.
1419
-
1420
- ```
1421
- I.waitForInvisible('#popup');
1422
- ```
1423
-
1424
- @param locator element located by CSS|XPath|strict locator.
1425
- @param sec (optional) time in seconds to wait, 1 by default.
1537
+ * Element can be located by CSS or XPath.
1538
+ *
1539
+ * ```js
1540
+ * I.waitForInvisible('#popup');
1541
+ * ```
1542
+ *
1543
+ * @param {string|object} locator element located by CSS|XPath|strict locator.
1544
+ * @param {number} sec (optional, `1` by default) time in seconds to wait
1545
+ * {--end--}
1426
1546
  */
1427
1547
  waitForInvisible(locator, sec) {
1428
1548
  this.browser.options.waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
@@ -1441,15 +1561,16 @@ I.waitForInvisible('#popup');
1441
1561
 
1442
1562
  /**
1443
1563
  * Waits for element to be present on page (by default waits for 1sec).
1444
- Element can be located by CSS or XPath.
1445
-
1446
- ```js
1447
- I.waitForElement('.btn.continue');
1448
- I.waitForElement('.btn.continue', 5); // wait for 5 secs
1449
- ```
1450
-
1451
- @param locator element located by CSS|XPath|strict locator.
1452
- @param sec (optional) time in seconds to wait, 1 by default.
1564
+ * Element can be located by CSS or XPath.
1565
+ *
1566
+ * ```js
1567
+ * I.waitForElement('.btn.continue');
1568
+ * I.waitForElement('.btn.continue', 5); // wait for 5 secs
1569
+ * ```
1570
+ *
1571
+ * @param {string|object} locator element located by CSS|XPath|strict locator.
1572
+ * @param {number} sec (optional, `1` by default) time in seconds to wait
1573
+ * {--end--}
1453
1574
  */
1454
1575
  async waitForElement(locator, sec) {
1455
1576
  this.browser.options.waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
@@ -1471,14 +1592,15 @@ I.waitForElement('.btn.continue', 5); // wait for 5 secs
1471
1592
 
1472
1593
  /**
1473
1594
  * Waits for an element to become not attached to the DOM on a page (by default waits for 1sec).
1474
- Element can be located by CSS or XPath.
1475
-
1476
- ```
1477
- I.waitForDetached('#popup');
1478
- ```
1479
-
1480
- @param locator element located by CSS|XPath|strict locator.
1481
- @param sec (optional) time in seconds to wait, 1 by default.
1595
+ * Element can be located by CSS or XPath.
1596
+ *
1597
+ * ```js
1598
+ * I.waitForDetached('#popup');
1599
+ * ```
1600
+ *
1601
+ * @param {string|object} locator element located by CSS|XPath|strict locator.
1602
+ * @param {number} sec (optional, `1` by default) time in seconds to wait
1603
+ * {--end--}
1482
1604
  */
1483
1605
  async waitForDetached(locator, sec) {
1484
1606
  this.browser.options.waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
@@ -1494,11 +1616,11 @@ I.waitForDetached('#popup');
1494
1616
 
1495
1617
  /**
1496
1618
  * Reload the current page.
1497
-
1498
- ```js
1499
- I.refreshPage();
1500
- ```
1501
-
1619
+ *
1620
+ * ```js
1621
+ * I.refreshPage();
1622
+ * ```
1623
+ * {--end--}
1502
1624
  */
1503
1625
  async refreshPage() {
1504
1626
  return this.browser.refresh();
@@ -1514,16 +1636,17 @@ I.refreshPage();
1514
1636
 
1515
1637
  /**
1516
1638
  * Saves a screenshot to ouput folder (set in codecept.json or codecept.conf.js).
1517
- Filename is relative to output folder.
1518
- Optionally resize the window to the full available page `scrollHeight` and `scrollWidth` to capture the entire page by passing `true` in as the second argument.
1519
-
1520
- ```js
1521
- I.saveScreenshot('debug.png');
1522
- I.saveScreenshot('debug.png', true) //resizes to available scrollHeight and scrollWidth before taking screenshot
1523
- ```
1524
-
1525
- @param fileName file name to save.
1526
- @param fullPage (optional) flag to enable fullscreen screenshot mode.
1639
+ * Filename is relative to output folder.
1640
+ * Optionally resize the window to the full available page `scrollHeight` and `scrollWidth` to capture the entire page by passing `true` in as the second argument.
1641
+ *
1642
+ * ```js
1643
+ * I.saveScreenshot('debug.png');
1644
+ * I.saveScreenshot('debug.png', true) //resizes to available scrollHeight and scrollWidth before taking screenshot
1645
+ * ```
1646
+ *
1647
+ * @param {string} fileName file name to save.
1648
+ * @param {boolean} fullPage (optional, `false` by default) flag to enable fullscreen screenshot mode.
1649
+ * {--end--}
1527
1650
  */
1528
1651
  async saveScreenshot(fileName, fullPage = this.options.fullPageScreenshots) {
1529
1652
  const outputFile = screenshotOutputFolder(fileName);
@@ -1547,16 +1670,17 @@ I.saveScreenshot('debug.png', true) //resizes to available scrollHeight and scro
1547
1670
 
1548
1671
  /**
1549
1672
  * Scrolls to element matched by locator.
1550
- Extra shift can be set with offsetX and offsetY options.
1551
-
1552
- ```js
1553
- I.scrollTo('footer');
1554
- I.scrollTo('#submit', 5, 5);
1555
- ```
1556
-
1557
- @param locator located by CSS|XPath|strict locator.
1558
- @param offsetX (optional) X-axis offset.
1559
- @param offsetY (optional) Y-axis offset.
1673
+ * Extra shift can be set with offsetX and offsetY options.
1674
+ *
1675
+ * ```js
1676
+ * I.scrollTo('footer');
1677
+ * I.scrollTo('#submit', 5, 5);
1678
+ * ```
1679
+ *
1680
+ * @param {string|object} locator located by CSS|XPath|strict locator.
1681
+ * @param {number} offsetX (optional, `0` by default) X-axis offset.
1682
+ * @param {number} offsetY (optional, `0` by default) Y-axis offset.
1683
+ * {--end--}
1560
1684
  */
1561
1685
  async scrollTo(locator, offsetX = 0, offsetY = 0) {
1562
1686
  if (typeof locator === 'number' && typeof offsetX === 'number') {
@@ -1579,10 +1703,11 @@ I.scrollTo('#submit', 5, 5);
1579
1703
 
1580
1704
  /**
1581
1705
  * Scroll page to the top.
1582
-
1583
- ```js
1584
- I.scrollPageToTop();
1585
- ```
1706
+ *
1707
+ * ```js
1708
+ * I.scrollPageToTop();
1709
+ * ```
1710
+ * {--end--}
1586
1711
  */
1587
1712
  async scrollPageToTop() {
1588
1713
  return this.executeScript(() => window.scrollTo(0, 0));
@@ -1590,10 +1715,11 @@ I.scrollPageToTop();
1590
1715
 
1591
1716
  /**
1592
1717
  * Scroll page to the bottom.
1593
-
1594
- ```js
1595
- I.scrollPageToBottom();
1596
- ```
1718
+ *
1719
+ * ```js
1720
+ * I.scrollPageToBottom();
1721
+ * ```
1722
+ * {--end--}
1597
1723
  */
1598
1724
  async scrollPageToBottom() {
1599
1725
  /* eslint-disable prefer-arrow-callback, comma-dangle */
@@ -1610,11 +1736,14 @@ I.scrollPageToBottom();
1610
1736
 
1611
1737
  /**
1612
1738
  * Retrieves a page scroll position and returns it to test.
1613
- Resumes test execution, so **should be used inside an async function with `await`** operator.
1614
-
1615
- ```js
1616
- let { x, y } = await I.grabPageScrollPosition();
1617
- ```
1739
+ * Resumes test execution, so **should be used inside an async function with `await`** operator.
1740
+ *
1741
+ * ```js
1742
+ * let { x, y } = await I.grabPageScrollPosition();
1743
+ * ```
1744
+ *
1745
+ * @returns {Promise<object>} scroll position
1746
+ * {--end--}
1618
1747
  */
1619
1748
  async grabPageScrollPosition() {
1620
1749
  /* eslint-disable comma-dangle */