codeceptjs 2.3.4 → 2.4.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 (269) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/README.md +28 -6
  3. package/bin/codecept.js +42 -0
  4. package/docs/advanced.md +45 -1
  5. package/docs/angular.md +3 -3
  6. package/docs/basics.md +162 -118
  7. package/docs/bdd.md +30 -5
  8. package/docs/best.md +8 -6
  9. package/docs/books.md +6 -1
  10. package/docs/build/Appium.js +95 -85
  11. package/docs/build/FileSystem.js +48 -3
  12. package/docs/build/GraphQL.js +3 -2
  13. package/docs/build/GraphQLDataFactory.js +1 -0
  14. package/docs/build/Mochawesome.js +3 -2
  15. package/docs/build/MockRequest.js +23 -5
  16. package/docs/build/Nightmare.js +87 -128
  17. package/docs/build/Protractor.js +107 -155
  18. package/docs/build/Puppeteer.js +190 -174
  19. package/docs/build/REST.js +13 -9
  20. package/docs/build/SeleniumWebdriver.js +0 -17
  21. package/docs/build/TestCafe.js +164 -158
  22. package/docs/build/WebDriver.js +236 -211
  23. package/docs/build/WebDriverIO.js +218 -187
  24. package/docs/changelog.md +57 -1
  25. package/docs/commands.md +41 -2
  26. package/docs/community-helpers.md +12 -1
  27. package/docs/configuration.md +5 -2
  28. package/docs/continuous-integration.md +22 -0
  29. package/docs/{helpers.md → custom-helpers.md} +16 -10
  30. package/docs/data.md +7 -6
  31. package/docs/detox.md +6 -6
  32. package/docs/email.md +4 -2
  33. package/docs/examples.md +22 -3
  34. package/docs/helpers/ApiDataFactory.md +15 -13
  35. package/docs/helpers/Appium.md +1011 -468
  36. package/docs/helpers/Detox.md +33 -26
  37. package/docs/helpers/FileSystem.md +43 -13
  38. package/docs/helpers/GraphQL.md +17 -15
  39. package/docs/helpers/GraphQLDataFactory.md +15 -13
  40. package/docs/helpers/Mochawesome.md +3 -1
  41. package/docs/helpers/MockRequest.md +37 -19
  42. package/docs/helpers/Nightmare.md +129 -240
  43. package/docs/helpers/Polly.md +1 -1
  44. package/docs/helpers/Protractor.md +157 -298
  45. package/docs/helpers/Puppeteer.md +216 -335
  46. package/docs/helpers/REST.md +29 -24
  47. package/docs/helpers/TestCafe.md +137 -235
  48. package/docs/helpers/WebDriver.md +250 -347
  49. package/docs/hooks.md +14 -10
  50. package/docs/index.md +112 -0
  51. package/docs/installation.md +3 -1
  52. package/docs/locators.md +19 -8
  53. package/docs/mobile-react-native-locators.md +2 -2
  54. package/docs/mobile.md +5 -3
  55. package/docs/nightmare.md +2 -1
  56. package/docs/pageobjects.md +4 -2
  57. package/docs/parallel.md +4 -2
  58. package/docs/plugins.md +41 -15
  59. package/docs/puppeteer.md +8 -6
  60. package/docs/quickstart.md +130 -0
  61. package/docs/react.md +4 -2
  62. package/docs/reports.md +6 -4
  63. package/docs/testcafe.md +10 -8
  64. package/docs/translation.md +4 -2
  65. package/docs/ui.md +56 -0
  66. package/docs/videos.md +11 -2
  67. package/docs/visual.md +7 -5
  68. package/docs/vue.md +121 -0
  69. package/docs/webapi/appendField.mustache +1 -1
  70. package/docs/webapi/attachFile.mustache +1 -1
  71. package/docs/webapi/checkOption.mustache +2 -2
  72. package/docs/webapi/clearCookie.mustache +1 -1
  73. package/docs/webapi/click.mustache +2 -2
  74. package/docs/webapi/clickLink.mustache +2 -2
  75. package/docs/webapi/dontSee.mustache +1 -2
  76. package/docs/webapi/dontSeeCheckboxIsChecked.mustache +1 -1
  77. package/docs/webapi/dontSeeElement.mustache +1 -1
  78. package/docs/webapi/dontSeeElementInDOM.mustache +1 -1
  79. package/docs/webapi/dontSeeInField.mustache +1 -1
  80. package/docs/webapi/doubleClick.mustache +2 -2
  81. package/docs/webapi/downloadFile.mustache +1 -1
  82. package/docs/webapi/dragSlider.mustache +1 -1
  83. package/docs/webapi/executeAsyncScript.mustache +2 -1
  84. package/docs/webapi/executeScript.mustache +2 -1
  85. package/docs/webapi/fillField.mustache +1 -1
  86. package/docs/webapi/grabAttributeFrom.mustache +1 -1
  87. package/docs/webapi/grabBrowserLogs.mustache +1 -1
  88. package/docs/webapi/grabCookie.mustache +2 -2
  89. package/docs/webapi/grabCssPropertyFrom.mustache +1 -1
  90. package/docs/webapi/grabHTMLFrom.mustache +1 -1
  91. package/docs/webapi/grabNumberOfVisibleElements.mustache +1 -1
  92. package/docs/webapi/grabPageScrollPosition.mustache +1 -1
  93. package/docs/webapi/grabTextFrom.mustache +2 -2
  94. package/docs/webapi/grabValueFrom.mustache +1 -1
  95. package/docs/webapi/moveCursorTo.mustache +3 -3
  96. package/docs/webapi/pressKey.mustache +1 -1
  97. package/docs/webapi/pressKeyWithKeyNormalization.mustache +1 -1
  98. package/docs/webapi/rightClick.mustache +2 -2
  99. package/docs/webapi/saveScreenshot.mustache +1 -1
  100. package/docs/webapi/scrollIntoView.mustache +10 -0
  101. package/docs/webapi/scrollTo.mustache +3 -3
  102. package/docs/webapi/see.mustache +1 -1
  103. package/docs/webapi/seeAttributesOnElements.mustache +1 -1
  104. package/docs/webapi/seeCheckboxIsChecked.mustache +1 -1
  105. package/docs/webapi/seeCssPropertiesOnElements.mustache +1 -1
  106. package/docs/webapi/seeElement.mustache +1 -1
  107. package/docs/webapi/seeElementInDOM.mustache +1 -1
  108. package/docs/webapi/seeInField.mustache +1 -1
  109. package/docs/webapi/seeNumberOfElements.mustache +1 -1
  110. package/docs/webapi/seeNumberOfVisibleElements.mustache +1 -1
  111. package/docs/webapi/seeTextEquals.mustache +8 -0
  112. package/docs/webapi/selectOption.mustache +2 -2
  113. package/docs/webapi/switchTo.mustache +1 -1
  114. package/docs/webapi/uncheckOption.mustache +2 -2
  115. package/docs/webapi/waitForClickable.mustache +10 -0
  116. package/docs/webapi/waitForDetached.mustache +2 -2
  117. package/docs/webapi/waitForElement.mustache +2 -2
  118. package/docs/webapi/waitForEnabled.mustache +2 -2
  119. package/docs/webapi/waitForFunction.mustache +2 -2
  120. package/docs/webapi/waitForInvisible.mustache +2 -2
  121. package/docs/webapi/waitForText.mustache +2 -2
  122. package/docs/webapi/waitForValue.mustache +1 -1
  123. package/docs/webapi/waitForVisible.mustache +2 -2
  124. package/docs/webapi/waitInUrl.mustache +1 -1
  125. package/docs/webapi/waitNumberOfVisibleElements.mustache +2 -2
  126. package/docs/webapi/waitToHide.mustache +2 -2
  127. package/docs/webapi/waitUntil.mustache +3 -2
  128. package/docs/webapi/waitUrlEquals.mustache +1 -1
  129. package/docs/webdriver.md +20 -18
  130. package/docs/wiki/.git/FETCH_HEAD +1 -0
  131. package/docs/wiki/.git/HEAD +1 -0
  132. package/docs/wiki/.git/ORIG_HEAD +1 -0
  133. package/docs/wiki/.git/config +11 -0
  134. package/docs/wiki/.git/description +1 -0
  135. package/docs/wiki/.git/hooks/applypatch-msg.sample +15 -0
  136. package/docs/wiki/.git/hooks/commit-msg.sample +24 -0
  137. package/docs/wiki/.git/hooks/fsmonitor-watchman.sample +114 -0
  138. package/docs/wiki/.git/hooks/post-update.sample +8 -0
  139. package/docs/wiki/.git/hooks/pre-applypatch.sample +14 -0
  140. package/docs/wiki/.git/hooks/pre-commit.sample +49 -0
  141. package/docs/wiki/.git/hooks/pre-push.sample +53 -0
  142. package/docs/wiki/.git/hooks/pre-rebase.sample +169 -0
  143. package/docs/wiki/.git/hooks/pre-receive.sample +24 -0
  144. package/docs/wiki/.git/hooks/prepare-commit-msg.sample +42 -0
  145. package/docs/wiki/.git/hooks/update.sample +128 -0
  146. package/docs/wiki/.git/index +0 -0
  147. package/docs/wiki/.git/info/exclude +6 -0
  148. package/docs/wiki/.git/logs/HEAD +4 -0
  149. package/docs/wiki/.git/logs/refs/heads/master +4 -0
  150. package/docs/wiki/.git/logs/refs/remotes/origin/HEAD +1 -0
  151. package/docs/wiki/.git/logs/refs/remotes/origin/master +3 -0
  152. package/docs/wiki/.git/objects/00/d216b0774d15db2d0a2a0d4ce249b5251acc55 +3 -0
  153. package/docs/wiki/.git/objects/09/01d87c5241905fdfe3493cfe8f04df4a2685ea +0 -0
  154. package/docs/wiki/.git/objects/0d/bdd0c20c4deb6a8cc81dbbf32ecf8c09238983 +2 -0
  155. package/docs/wiki/.git/objects/1a/c29e4fa82422c52392f22f0f2b8d1a759535bf +0 -0
  156. package/docs/wiki/.git/objects/27/12f92898d3e8f68e229b6cda76570d6c66d781 +0 -0
  157. package/docs/wiki/.git/objects/2d/dbe22c257166b648928eeb9460ecfb71ba702d +0 -0
  158. package/docs/wiki/.git/objects/2f/c942ec3773efd2678d9ff98035c61fcded81a1 +0 -0
  159. package/docs/wiki/.git/objects/40/a2856342c67796b48911a256b764fb06888b94 +5 -0
  160. package/docs/wiki/.git/objects/47/53181844fc4dc563cf3aa5e80462243cb58d38 +0 -0
  161. package/docs/wiki/.git/objects/4e/24a95fb2e4f8ffef51f19b694451a205c06f10 +3 -0
  162. package/docs/wiki/.git/objects/73/31ebd96f3c7e08a9f63f05a25f939afa0d4de1 +0 -0
  163. package/docs/wiki/.git/objects/86/19cbb2289caa502e33fccf0ed14eecf6ba2ba0 +0 -0
  164. package/docs/wiki/.git/objects/a4/72f797d9d74b87c9f71a2b1539d75bb07d1e35 +0 -0
  165. package/docs/wiki/.git/objects/c9/9f3e4bd227d6b050b2e416f9876df49583dbf6 +0 -0
  166. package/docs/wiki/.git/objects/ca/e609b4ef3e0ef85fcbe0d68d1a58246584b915 +0 -0
  167. package/docs/wiki/.git/objects/d5/8386ca72f6d550548f3d71d74e3ac73d5ad488 +0 -0
  168. package/docs/wiki/.git/objects/d9/c6874a6de524bdafeb563a20d847f4fdd59a86 +0 -0
  169. package/docs/wiki/.git/objects/f1/c944675bb38b40ae553b0be36c14674c79af54 +0 -0
  170. package/docs/wiki/.git/objects/pack/pack-28da0fc7e6c08d4c5350717bfbb7b1c53e8198ad.idx +0 -0
  171. package/docs/wiki/.git/objects/pack/pack-28da0fc7e6c08d4c5350717bfbb7b1c53e8198ad.pack +0 -0
  172. package/docs/wiki/.git/packed-refs +2 -0
  173. package/docs/wiki/.git/refs/heads/master +1 -0
  174. package/docs/wiki/.git/refs/remotes/origin/HEAD +1 -0
  175. package/docs/wiki/.git/refs/remotes/origin/master +1 -0
  176. package/docs/wiki/Books-&-Posts.md +27 -0
  177. package/docs/wiki/Community-Helpers.md +41 -0
  178. package/docs/wiki/Examples.md +138 -0
  179. package/docs/wiki/Home.md +11 -0
  180. package/docs/wiki/Release-process.md +25 -0
  181. package/docs/wiki/Roadmap.md +23 -0
  182. package/docs/wiki/Videos.md +19 -0
  183. package/lib/actor.js +18 -1
  184. package/lib/assert/error.js +3 -3
  185. package/lib/codecept.js +9 -6
  186. package/lib/command/configMigrate.js +7 -6
  187. package/lib/command/definitions.js +98 -350
  188. package/lib/command/generate.js +22 -17
  189. package/lib/command/gherkin/init.js +2 -1
  190. package/lib/command/gherkin/snippets.js +6 -6
  191. package/lib/command/gherkin/steps.js +0 -1
  192. package/lib/command/info.js +40 -0
  193. package/lib/command/init.js +54 -41
  194. package/lib/command/run-multiple.js +5 -4
  195. package/lib/command/run-rerun.js +39 -0
  196. package/lib/command/run-workers.js +4 -6
  197. package/lib/command/run.js +8 -18
  198. package/lib/command/utils.js +23 -2
  199. package/lib/command/workers/runTests.js +1 -2
  200. package/lib/config.js +10 -4
  201. package/lib/container.js +31 -6
  202. package/lib/data/dataTableArgument.js +31 -0
  203. package/lib/data/table.js +4 -0
  204. package/lib/event.js +65 -1
  205. package/lib/helper/Appium.js +52 -38
  206. package/lib/helper/FileSystem.js +48 -3
  207. package/lib/helper/GraphQL.js +3 -2
  208. package/lib/helper/GraphQLDataFactory.js +1 -0
  209. package/lib/helper/Mochawesome.js +3 -2
  210. package/lib/helper/MockRequest.js +23 -5
  211. package/lib/helper/Nightmare.js +5 -6
  212. package/lib/helper/Protractor.js +7 -8
  213. package/lib/helper/Puppeteer.js +76 -20
  214. package/lib/helper/REST.js +13 -9
  215. package/lib/helper/SeleniumWebdriver.js +0 -17
  216. package/lib/helper/TestCafe.js +84 -36
  217. package/lib/helper/WebDriver.js +113 -59
  218. package/lib/helper/WebDriverIO.js +43 -59
  219. package/lib/helper/clientscripts/nightmare.js +66 -4
  220. package/lib/helper/scripts/isElementClickable.js +24 -0
  221. package/lib/helper.js +34 -10
  222. package/lib/history.js +1 -1
  223. package/lib/hooks.js +2 -1
  224. package/lib/index.js +19 -0
  225. package/lib/interfaces/bdd.js +4 -0
  226. package/lib/interfaces/featureConfig.js +10 -3
  227. package/lib/interfaces/gherkin.js +6 -2
  228. package/lib/interfaces/scenarioConfig.js +17 -6
  229. package/lib/listener/config.js +1 -1
  230. package/lib/listener/exit.js +6 -0
  231. package/lib/listener/steps.js +0 -1
  232. package/lib/listener/trace.js +0 -1
  233. package/lib/locator.js +67 -2
  234. package/lib/output.js +53 -0
  235. package/lib/parser.js +2 -71
  236. package/lib/pause.js +3 -2
  237. package/lib/plugin/allure.js +41 -22
  238. package/lib/plugin/autoLogin.js +4 -1
  239. package/lib/plugin/pauseOnFail.js +38 -0
  240. package/lib/plugin/puppeteerCoverage.js +8 -7
  241. package/lib/plugin/screenshotOnFail.js +13 -8
  242. package/lib/plugin/stepByStepReport.js +7 -6
  243. package/lib/plugin/wdio.js +2 -1
  244. package/lib/recorder.js +85 -7
  245. package/lib/rerun.js +81 -0
  246. package/lib/secret.js +6 -0
  247. package/lib/session.js +9 -2
  248. package/lib/step.js +37 -2
  249. package/lib/store.js +5 -1
  250. package/lib/ui.js +34 -8
  251. package/lib/utils.js +6 -13
  252. package/lib/within.js +5 -0
  253. package/package.json +49 -29
  254. package/typings/Mocha.d.ts +21 -0
  255. package/typings/Protractor.d.ts +16 -0
  256. package/typings/index.d.ts +169 -0
  257. package/typings/jsdoc.conf.js +34 -0
  258. package/typings/jsdoc.namespace.js +29 -0
  259. package/typings/types.d.ts +9827 -0
  260. package/typings/utils.d.ts +7 -0
  261. package/docs/acceptance.md +0 -409
  262. package/docs/api/codecept.md +0 -75
  263. package/docs/api/config.md +0 -49
  264. package/docs/api/container.md +0 -66
  265. package/docs/api/helper.md +0 -116
  266. package/docs/api/output.md +0 -67
  267. package/docs/api/recorder.md +0 -63
  268. package/docs/helpers/SeleniumWebdriver.md +0 -92
  269. package/docs/helpers/WebDriverIO.md +0 -1671
@@ -1,4 +1,9 @@
1
+ const axios = require('axios');
2
+ const fs = require('fs');
3
+ const fsExtra = require('fs-extra');
1
4
  const requireg = require('requireg');
5
+ const path = require('path');
6
+
2
7
  const Helper = require('../helper');
3
8
  const Locator = require('../locator');
4
9
  const recorder = require('../recorder');
@@ -7,11 +12,13 @@ const { urlEquals } = require('../assert/equal');
7
12
  const { equals } = require('../assert/equal');
8
13
  const { empty } = require('../assert/empty');
9
14
  const { truth } = require('../assert/truth');
15
+ const isElementClickable = require('./scripts/isElementClickable');
10
16
  const {
11
17
  xpathLocator,
12
18
  ucfirst,
13
19
  fileExists,
14
20
  chunkArray,
21
+ toCamelCase,
15
22
  convertCssPropertiesToCamelCase,
16
23
  screenshotOutputFolder,
17
24
  getNormalizedKeyAttributeValue,
@@ -21,18 +28,15 @@ const {
21
28
  isColorProperty,
22
29
  convertColorToRGBA,
23
30
  } = require('../colorUtils');
24
- const path = require('path');
25
31
  const ElementNotFound = require('./errors/ElementNotFound');
26
32
  const RemoteBrowserConnectionRefused = require('./errors/RemoteBrowserConnectionRefused');
27
33
  const Popup = require('./extras/Popup');
28
34
  const Console = require('./extras/Console');
29
35
  const findReact = require('./extras/React');
30
- const axios = require('axios');
31
- const fs = require('fs');
32
- const fsExtra = require('fs-extra');
33
36
 
34
37
  let puppeteer;
35
38
  let perfTiming;
39
+ let isAuthenticated = false;
36
40
  const popupStore = new Popup();
37
41
  const consoleLogStore = new Console();
38
42
 
@@ -50,6 +54,7 @@ const consoleLogStore = new Console();
50
54
  * This helper should be configured in codecept.json or codecept.conf.js
51
55
  *
52
56
  * * `url`: base url of website to be tested
57
+ * * `basicAuth`: (optional) the basic authentication to pass to base url. Example: {username: 'username', password: 'password'}
53
58
  * * `show`: (optional, default: false) - show Google Chrome window for debug.
54
59
  * * `restart`: (optional, default: true) - restart browser between tests.
55
60
  * * `disableScreenshots`: (optional, default: false) - don't save screenshot on failure.
@@ -127,6 +132,22 @@ const consoleLogStore = new Console();
127
132
  * }
128
133
  * ```
129
134
  *
135
+ * #### Example #5: Target URL with provided basic authentication
136
+ *
137
+ * ```js
138
+ * {
139
+ * helpers: {
140
+ * Puppeteer : {
141
+ * url: 'http://localhost',
142
+ * basicAuth: {username: 'username', password: 'password'},
143
+ * show: true
144
+ * }
145
+ * }
146
+ * }
147
+ * ```
148
+ *
149
+ *
150
+ *
130
151
  * Note: When connecting to remote browser `show` and specific `chrome` options (e.g. `headless` or `devtools`) are ignored.
131
152
  *
132
153
  * ## Access From Helpers
@@ -185,7 +206,10 @@ class Puppeteer extends Helper {
185
206
 
186
207
  _setConfig(config) {
187
208
  this.options = this._validateConfig(config);
188
- this.puppeteerOptions = Object.assign({ headless: !this.options.show }, this._getOptions(config));
209
+ this.puppeteerOptions = {
210
+ headless: !this.options.show,
211
+ ...this._getOptions(config),
212
+ };
189
213
  this.isRemoteBrowser = !!this.puppeteerOptions.browserWSEndpoint;
190
214
  popupStore.defaultAction = this.options.defaultPopupAction;
191
215
  }
@@ -247,9 +271,13 @@ class Puppeteer extends Helper {
247
271
  this.debugSection('Session', 'cleaning cookies and localStorage');
248
272
  await this.clearCookie();
249
273
  }
250
- await this.executeScript('localStorage.clear();').catch((err) => {
251
- if (!(err.message.indexOf("Storage is disabled inside 'data:' URLs.") > -1)) throw err;
252
- });
274
+ const currentUrl = await this.grabCurrentUrl();
275
+
276
+ if (currentUrl.startsWith('http')) {
277
+ await this.executeScript('localStorage.clear();').catch((err) => {
278
+ if (!(err.message.indexOf("Storage is disabled inside 'data:' URLs.") > -1)) throw err;
279
+ });
280
+ }
253
281
  await this.closeOtherTabs();
254
282
  return this.browser;
255
283
  }
@@ -401,6 +429,7 @@ class Puppeteer extends Helper {
401
429
  * ```js
402
430
  * await I.grabPopupText();
403
431
  * ```
432
+ * @return {Promise<string | null>}
404
433
  */
405
434
  async grabPopupText() {
406
435
  if (popupStore.popup) {
@@ -517,12 +546,19 @@ class Puppeteer extends Helper {
517
546
  * ```
518
547
  *
519
548
  * @param {string} url url path or global url.
520
- * {--end--}
521
549
  */
522
550
  async amOnPage(url) {
523
551
  if (!(/^\w+\:\/\//.test(url))) {
524
552
  url = this.options.url + url;
525
553
  }
554
+
555
+ if (this.config.basicAuth && (isAuthenticated !== true)) {
556
+ if (url.includes(this.options.url)) {
557
+ this.page.authenticate(this.config.basicAuth);
558
+ isAuthenticated = true;
559
+ }
560
+ }
561
+
526
562
  await this.page.goto(url, { waitUntil: this.options.waitForNavigation });
527
563
 
528
564
  const performanceTiming = JSON.parse(await this.page.evaluate(() => JSON.stringify(window.performance.timing)));
@@ -544,7 +580,6 @@ class Puppeteer extends Helper {
544
580
  *
545
581
  * @param {number} width width in pixels or `maximize`.
546
582
  * @param {number} height height in pixels.
547
- * {--end--}
548
583
  *
549
584
  * Unlike other drivers Puppeteer changes the size of a viewport, not the window!
550
585
  * Puppeteer does not control the window of a browser so it can't adjust its real size.
@@ -586,10 +621,10 @@ class Puppeteer extends Helper {
586
621
  * I.moveCursorTo('#submit', 5,5);
587
622
  * ```
588
623
  *
589
- * @param {string|object} locator located by CSS|XPath|strict locator.
590
- * @param {number} offsetX (optional, `0` by default) X-axis offset.
591
- * @param {number} offsetY (optional, `0` by default) Y-axis offset.
592
- * {--end--}
624
+ * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|strict locator.
625
+ * @param {number} [offsetX=0] (optional, `0` by default) X-axis offset.
626
+ * @param {number} [offsetY=0] (optional, `0` by default) Y-axis offset.
627
+ *
593
628
  * {{ react }}
594
629
  */
595
630
  async moveCursorTo(locator, offsetX = 0, offsetY = 0) {
@@ -611,7 +646,6 @@ class Puppeteer extends Helper {
611
646
  *
612
647
  * @param {string|object} srcElement located by CSS|XPath|strict locator.
613
648
  * @param {string|object} destElement located by CSS|XPath|strict locator.
614
- * {--end--}
615
649
  */
616
650
  async dragAndDrop(srcElement, destElement) {
617
651
  return proceedDragAndDrop.call(this, srcElement, destElement);
@@ -623,7 +657,7 @@ class Puppeteer extends Helper {
623
657
  * ```js
624
658
  * I.refreshPage();
625
659
  * ```
626
- * {--end--}
660
+ *
627
661
  */
628
662
  async refreshPage() {
629
663
  return this.page.reload({ timeout: this.options.getPageTimeout, waitUntil: this.options.waitForNavigation });
@@ -635,7 +669,7 @@ class Puppeteer extends Helper {
635
669
  * ```js
636
670
  * I.scrollPageToTop();
637
671
  * ```
638
- * {--end--}
672
+ *
639
673
  */
640
674
  scrollPageToTop() {
641
675
  return this.executeScript(() => {
@@ -649,7 +683,7 @@ class Puppeteer extends Helper {
649
683
  * ```js
650
684
  * I.scrollPageToBottom();
651
685
  * ```
652
- * {--end--}
686
+ *
653
687
  */
654
688
  scrollPageToBottom() {
655
689
  return this.executeScript(() => {
@@ -671,10 +705,9 @@ class Puppeteer extends Helper {
671
705
  * I.scrollTo('#submit', 5, 5);
672
706
  * ```
673
707
  *
674
- * @param {string|object} locator located by CSS|XPath|strict locator.
675
- * @param {number} offsetX (optional, `0` by default) X-axis offset.
676
- * @param {number} offsetY (optional, `0` by default) Y-axis offset.
677
- * {--end--}
708
+ * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|strict locator.
709
+ * @param {number} [offsetX=0] (optional, `0` by default) X-axis offset.
710
+ * @param {number} [offsetY=0] (optional, `0` by default) Y-axis offset.
678
711
  */
679
712
  async scrollTo(locator, offsetX = 0, offsetY = 0) {
680
713
  if (typeof locator === 'number' && typeof offsetX === 'number') {
@@ -703,7 +736,6 @@ class Puppeteer extends Helper {
703
736
  * ```
704
737
  *
705
738
  * @param {string} text text value to check.
706
- * {--end--}
707
739
  */
708
740
  async seeInTitle(text) {
709
741
  const title = await this.page.title();
@@ -718,8 +750,7 @@ class Puppeteer extends Helper {
718
750
  * let { x, y } = await I.grabPageScrollPosition();
719
751
  * ```
720
752
  *
721
- * @returns {Promise<object>} scroll position
722
- * {--end--}
753
+ * @returns {Promise<Object<string, *>>} scroll position
723
754
  */
724
755
  async grabPageScrollPosition() {
725
756
  /* eslint-disable comma-dangle */
@@ -753,7 +784,6 @@ class Puppeteer extends Helper {
753
784
  * ```
754
785
  *
755
786
  * @param {string} text value to check.
756
- * {--end--}
757
787
  */
758
788
  async dontSeeInTitle(text) {
759
789
  const title = await this.page.title();
@@ -769,7 +799,6 @@ class Puppeteer extends Helper {
769
799
  * ```
770
800
  *
771
801
  * @returns {Promise<string>} title
772
- * {--end--}
773
802
  */
774
803
  async grabTitle() {
775
804
  return this.page.title();
@@ -927,7 +956,6 @@ class Puppeteer extends Helper {
927
956
  * ```
928
957
  *
929
958
  * @returns {Promise<number>} number of open tabs
930
- * {--end--}
931
959
  */
932
960
  async grabNumberOfOpenTabs() {
933
961
  const pages = await this.browser.pages();
@@ -941,8 +969,7 @@ class Puppeteer extends Helper {
941
969
  * ```js
942
970
  * I.seeElement('#modal');
943
971
  * ```
944
- * @param {string|object} locator located by CSS|XPath|strict locator.
945
- * {--end--}
972
+ * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|strict locator.
946
973
  * {{ react }}
947
974
  */
948
975
  async seeElement(locator) {
@@ -958,8 +985,7 @@ class Puppeteer extends Helper {
958
985
  * I.dontSeeElement('.modal'); // modal is not shown
959
986
  * ```
960
987
  *
961
- * @param {string|object} locator located by CSS|XPath|Strict locator.
962
- * {--end--}
988
+ * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|Strict locator.
963
989
  * {{ react }}
964
990
  */
965
991
  async dontSeeElement(locator) {
@@ -975,8 +1001,8 @@ class Puppeteer extends Helper {
975
1001
  * ```js
976
1002
  * I.seeElementInDOM('#modal');
977
1003
  * ```
978
- * @param {string|object} locator element located by CSS|XPath|strict locator.
979
- * {--end--}
1004
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
1005
+ *
980
1006
  */
981
1007
  async seeElementInDOM(locator) {
982
1008
  const els = await this._locate(locator);
@@ -990,8 +1016,7 @@ class Puppeteer extends Helper {
990
1016
  * I.dontSeeElementInDOM('.nav'); // checks that element is not on page visible or not
991
1017
  * ```
992
1018
  *
993
- * @param {string|object} locator located by CSS|XPath|Strict locator.
994
- * {--end--}
1019
+ * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|Strict locator.
995
1020
  */
996
1021
  async dontSeeElementInDOM(locator) {
997
1022
  const els = await this._locate(locator);
@@ -1021,9 +1046,9 @@ class Puppeteer extends Helper {
1021
1046
  * I.click({css: 'nav a.login'});
1022
1047
  * ```
1023
1048
  *
1024
- * @param {string|object} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
1025
- * @param {string|object} context (optional, `null` by default) element to search in CSS|XPath|Strict locator.
1026
- * {--end--}
1049
+ * @param {CodeceptJS.LocatorOrString} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
1050
+ * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element to search in CSS|XPath|Strict locator.
1051
+ *
1027
1052
  *
1028
1053
  * {{ react }}
1029
1054
  */
@@ -1037,9 +1062,8 @@ class Puppeteer extends Helper {
1037
1062
  * ```js
1038
1063
  * I.clickLink('Logout', '#nav');
1039
1064
  * ```
1040
- * @param {string|object} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator
1041
- * @param {string|object} context (optional, `null` by default) element to search in CSS|XPath|Strict locator
1042
- * {--end--}
1065
+ * @param {CodeceptJS.LocatorOrString} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator
1066
+ * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element to search in CSS|XPath|Strict locator
1043
1067
  *
1044
1068
  * {{ react }}
1045
1069
  */
@@ -1150,9 +1174,9 @@ class Puppeteer extends Helper {
1150
1174
  * I.doubleClick('.btn.edit');
1151
1175
  * ```
1152
1176
  *
1153
- * @param {string|object} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
1154
- * @param {string|object} context (optional, `null` by default) element to search in CSS|XPath|Strict locator.
1155
- * {--end--}
1177
+ * @param {CodeceptJS.LocatorOrString} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
1178
+ * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element to search in CSS|XPath|Strict locator.
1179
+ *
1156
1180
  *
1157
1181
  * {{ react }}
1158
1182
  */
@@ -1172,9 +1196,9 @@ class Puppeteer extends Helper {
1172
1196
  * I.rightClick('Click me', '.context');
1173
1197
  * ```
1174
1198
  *
1175
- * @param {string|object} locator clickable element located by CSS|XPath|strict locator.
1176
- * @param {string|object} context (optional, `null` by default) element located by CSS|XPath|strict locator.
1177
- * {--end--}
1199
+ * @param {CodeceptJS.LocatorOrString} locator clickable element located by CSS|XPath|strict locator.
1200
+ * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element located by CSS|XPath|strict locator.
1201
+ *
1178
1202
  *
1179
1203
  * {{ react }}
1180
1204
  */
@@ -1193,9 +1217,8 @@ class Puppeteer extends Helper {
1193
1217
  * I.checkOption('I Agree to Terms and Conditions');
1194
1218
  * I.checkOption('agree', '//form');
1195
1219
  * ```
1196
- * @param {string|object} field checkbox located by label | name | CSS | XPath | strict locator.
1197
- * @param {string} context (optional, `null` by default) element located by CSS | XPath | strict locator.
1198
- * {--end--}
1220
+ * @param {CodeceptJS.LocatorOrString} field checkbox located by label | name | CSS | XPath | strict locator.
1221
+ * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element located by CSS | XPath | strict locator.
1199
1222
  */
1200
1223
  async checkOption(field, context = null) {
1201
1224
  const elm = await this._locateCheckable(field, context);
@@ -1219,9 +1242,8 @@ class Puppeteer extends Helper {
1219
1242
  * I.uncheckOption('I Agree to Terms and Conditions');
1220
1243
  * I.uncheckOption('agree', '//form');
1221
1244
  * ```
1222
- * @param {string|object} field checkbox located by label | name | CSS | XPath | strict locator.
1223
- * @param {string} context (optional, `null` by default) element located by CSS | XPath | strict locator.
1224
- * {--end--}
1245
+ * @param {CodeceptJS.LocatorOrString} field checkbox located by label | name | CSS | XPath | strict locator.
1246
+ * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element located by CSS | XPath | strict locator.
1225
1247
  */
1226
1248
  async uncheckOption(field, context = null) {
1227
1249
  const elm = await this._locateCheckable(field, context);
@@ -1243,8 +1265,8 @@ class Puppeteer extends Helper {
1243
1265
  * I.seeCheckboxIsChecked({css: '#signup_form input[type=checkbox]'});
1244
1266
  * ```
1245
1267
  *
1246
- * @param {string|object} field located by label|name|CSS|XPath|strict locator.
1247
- * {--end--}
1268
+ * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator.
1269
+ *
1248
1270
  */
1249
1271
  async seeCheckboxIsChecked(field) {
1250
1272
  return proceedIsChecked.call(this, 'assert', field);
@@ -1259,8 +1281,8 @@ class Puppeteer extends Helper {
1259
1281
  * I.dontSeeCheckboxIsChecked('agree'); // located by name
1260
1282
  * ```
1261
1283
  *
1262
- * @param {string|object} field located by label|name|CSS|XPath|strict locator.
1263
- * {--end--}
1284
+ * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator.
1285
+ *
1264
1286
  */
1265
1287
  async dontSeeCheckboxIsChecked(field) {
1266
1288
  return proceedIsChecked.call(this, 'negate', field);
@@ -1278,7 +1300,7 @@ class Puppeteer extends Helper {
1278
1300
  * ```
1279
1301
  *
1280
1302
  * @param {string} key name of key to press down.
1281
- * {--end--}
1303
+ *
1282
1304
  */
1283
1305
  async pressKeyDown(key) {
1284
1306
  key = getNormalizedKey.call(this, key);
@@ -1298,7 +1320,7 @@ class Puppeteer extends Helper {
1298
1320
  * ```
1299
1321
  *
1300
1322
  * @param {string} key name of key to release.
1301
- * {--end--}
1323
+ *
1302
1324
  */
1303
1325
  async pressKeyUp(key) {
1304
1326
  key = getNormalizedKey.call(this, key);
@@ -1365,8 +1387,8 @@ class Puppeteer extends Helper {
1365
1387
  * - `'Space'`
1366
1388
  * - `'Tab'`
1367
1389
  *
1368
- * @param {string|array} key key or array of keys to press.
1369
- * {--end--}
1390
+ * @param {string|string[]} key key or array of keys to press.
1391
+ *
1370
1392
  *
1371
1393
  * _Note:_ Shortcuts like `'Meta'` + `'A'` do not work on macOS ([GoogleChrome/puppeteer#1313](https://github.com/GoogleChrome/puppeteer/issues/1313)).
1372
1394
  */
@@ -1409,9 +1431,9 @@ class Puppeteer extends Helper {
1409
1431
  * // or by strict locator
1410
1432
  * I.fillField({css: 'form#login input[name=username]'}, 'John');
1411
1433
  * ```
1412
- * @param {string|object} field located by label|name|CSS|XPath|strict locator.
1434
+ * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator.
1413
1435
  * @param {string} value text value to fill.
1414
- * {--end--}
1436
+ *
1415
1437
  * {{ react }}
1416
1438
  */
1417
1439
  async fillField(field, value) {
@@ -1439,7 +1461,6 @@ class Puppeteer extends Helper {
1439
1461
  * I.clearField('#email');
1440
1462
  * ```
1441
1463
  * @param {string|object} editable field located by label|name|CSS|XPath|strict locator.
1442
- * {--end--}
1443
1464
  */
1444
1465
  async clearField(field) {
1445
1466
  return this.fillField(field, '');
@@ -1452,9 +1473,8 @@ class Puppeteer extends Helper {
1452
1473
  * ```js
1453
1474
  * I.appendField('#myTextField', 'appended');
1454
1475
  * ```
1455
- * @param {string|object} field located by label|name|CSS|XPath|strict locator
1476
+ * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator
1456
1477
  * @param {string} value text value to append.
1457
- * {--end--}
1458
1478
  *
1459
1479
  * {{ react }}
1460
1480
  */
@@ -1476,9 +1496,9 @@ class Puppeteer extends Helper {
1476
1496
  * I.seeInField('form input[type=hidden]','hidden_value');
1477
1497
  * I.seeInField('#searchform input','Search');
1478
1498
  * ```
1479
- * @param {string|object} field located by label|name|CSS|XPath|strict locator.
1499
+ * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator.
1480
1500
  * @param {string} value value to check.
1481
- * {--end--}
1501
+ *
1482
1502
  */
1483
1503
  async seeInField(field, value) {
1484
1504
  return proceedSeeInField.call(this, 'assert', field, value);
@@ -1493,9 +1513,8 @@ class Puppeteer extends Helper {
1493
1513
  * I.dontSeeInField({ css: 'form input.email' }, 'user@user.com'); // field by CSS
1494
1514
  * ```
1495
1515
  *
1496
- * @param {string|object} field located by label|name|CSS|XPath|strict locator.
1516
+ * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator.
1497
1517
  * @param {string} value value to check.
1498
- * {--end--}
1499
1518
  */
1500
1519
  async dontSeeInField(field, value) {
1501
1520
  return proceedSeeInField.call(this, 'negate', field, value);
@@ -1512,9 +1531,8 @@ class Puppeteer extends Helper {
1512
1531
  * I.attachFile('form input[name=avatar]', 'data/avatar.jpg');
1513
1532
  * ```
1514
1533
  *
1515
- * @param {string|object} locator field located by label|name|CSS|XPath|strict locator.
1534
+ * @param {CodeceptJS.LocatorOrString} locator field located by label|name|CSS|XPath|strict locator.
1516
1535
  * @param {string} pathToFile local file path relative to codecept.json config file.
1517
- * {--end--}
1518
1536
  */
1519
1537
  async attachFile(locator, pathToFile) {
1520
1538
  const file = path.join(global.codecept_dir, pathToFile);
@@ -1547,9 +1565,8 @@ class Puppeteer extends Helper {
1547
1565
  * ```js
1548
1566
  * I.selectOption('Which OS do you use?', ['Android', 'iOS']);
1549
1567
  * ```
1550
- * @param {string|object} select field located by label|name|CSS|XPath|strict locator.
1551
- * @param {string|array} option visible text or value of option.
1552
- * {--end--}
1568
+ * @param {CodeceptJS.LocatorOrString} select field located by label|name|CSS|XPath|strict locator.
1569
+ * @param {string|Array<*>} option visible text or value of option.
1553
1570
  */
1554
1571
  async selectOption(select, option) {
1555
1572
  const els = await findFields.call(this, select);
@@ -1587,9 +1604,8 @@ class Puppeteer extends Helper {
1587
1604
  * let numOfElements = await I.grabNumberOfVisibleElements('p');
1588
1605
  * ```
1589
1606
  *
1590
- * @param {string|object} locator located by CSS|XPath|strict locator.
1607
+ * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|strict locator.
1591
1608
  * @returns {Promise<number>} number of visible elements
1592
- * {--end--}
1593
1609
  * {{ react }}
1594
1610
  */
1595
1611
  async grabNumberOfVisibleElements(locator) {
@@ -1606,7 +1622,6 @@ class Puppeteer extends Helper {
1606
1622
  * ```
1607
1623
  *
1608
1624
  * @param {string} url a fragment to check
1609
- * {--end--}
1610
1625
  */
1611
1626
  async seeInCurrentUrl(url) {
1612
1627
  stringIncludes('url').assert(url, await this._getPageUrl());
@@ -1616,7 +1631,6 @@ class Puppeteer extends Helper {
1616
1631
  * Checks that current url does not contain a provided fragment.
1617
1632
  *
1618
1633
  * @param {string} url value to check.
1619
- * {--end--}
1620
1634
  */
1621
1635
  async dontSeeInCurrentUrl(url) {
1622
1636
  stringIncludes('url').negate(url, await this._getPageUrl());
@@ -1633,7 +1647,6 @@ class Puppeteer extends Helper {
1633
1647
  * ```
1634
1648
  *
1635
1649
  * @param {string} url value to check.
1636
- * {--end--}
1637
1650
  */
1638
1651
  async seeCurrentUrlEquals(url) {
1639
1652
  urlEquals(this.options.url).assert(url, await this._getPageUrl());
@@ -1649,7 +1662,6 @@ class Puppeteer extends Helper {
1649
1662
  * ```
1650
1663
  *
1651
1664
  * @param {string} url value to check.
1652
- * {--end--}
1653
1665
  */
1654
1666
  async dontSeeCurrentUrlEquals(url) {
1655
1667
  urlEquals(this.options.url).negate(url, await this._getPageUrl());
@@ -1665,8 +1677,7 @@ class Puppeteer extends Helper {
1665
1677
  * I.see('Register', {css: 'form.register'}); // use strict locator
1666
1678
  * ```
1667
1679
  * @param {string} text expected on page.
1668
- * @param {string|object} context (optional, `null` by default) element located by CSS|Xpath|strict locator in which to search for text.
1669
- * {--end--}
1680
+ * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element located by CSS|Xpath|strict locator in which to search for text.
1670
1681
  *
1671
1682
  * {{ react }}
1672
1683
  */
@@ -1676,10 +1687,13 @@ class Puppeteer extends Helper {
1676
1687
 
1677
1688
  /**
1678
1689
  * Checks that text is equal to provided one.
1679
- *
1690
+ *
1680
1691
  * ```js
1681
1692
  * I.seeTextEquals('text', 'h1');
1682
1693
  * ```
1694
+ *
1695
+ * @param {string} text element value to check.
1696
+ * @param {CodeceptJS.LocatorOrString?} [context=null] element located by CSS|XPath|strict locator.
1683
1697
  */
1684
1698
  async seeTextEquals(text, context = null) {
1685
1699
  return proceedSee.call(this, 'assert', text, context, true);
@@ -1695,9 +1709,8 @@ class Puppeteer extends Helper {
1695
1709
  * ```
1696
1710
  *
1697
1711
  * @param {string} text which is not present.
1698
- * @param {string|object} context (optional) element located by CSS|XPath|strict locator in which to perfrom search.
1699
- *
1700
- * {--end--}
1712
+ * @param {CodeceptJS.LocatorOrString} [context] (optional) element located by CSS|XPath|strict locator in which to perfrom search.
1713
+ *
1701
1714
  *
1702
1715
  * {{ react }}
1703
1716
  */
@@ -1714,7 +1727,6 @@ class Puppeteer extends Helper {
1714
1727
  * ```
1715
1728
  *
1716
1729
  * @returns {Promise<string>} source code
1717
- * {--end--}
1718
1730
  */
1719
1731
  async grabSource() {
1720
1732
  return this.page.content();
@@ -1727,6 +1739,7 @@ class Puppeteer extends Helper {
1727
1739
  * let logs = await I.grabBrowserLogs();
1728
1740
  * console.log(JSON.stringify(logs))
1729
1741
  * ```
1742
+ * @return {Promise<any[]>}
1730
1743
  */
1731
1744
  async grabBrowserLogs() {
1732
1745
  const logs = consoleLogStore.entries;
@@ -1744,7 +1757,6 @@ class Puppeteer extends Helper {
1744
1757
  * ```
1745
1758
  *
1746
1759
  * @returns {Promise<string>} current URL
1747
- * {--end--}
1748
1760
  */
1749
1761
  async grabCurrentUrl() {
1750
1762
  return this._getPageUrl();
@@ -1757,7 +1769,6 @@ class Puppeteer extends Helper {
1757
1769
  * I.seeInSource('<h1>Green eggs &amp; ham</h1>');
1758
1770
  * ```
1759
1771
  * @param {string} text value to check.
1760
- * {--end--}
1761
1772
  */
1762
1773
  async seeInSource(text) {
1763
1774
  const source = await this.page.content();
@@ -1772,7 +1783,7 @@ class Puppeteer extends Helper {
1772
1783
  * ```
1773
1784
  *
1774
1785
  * @param {string} value to check.
1775
- * {--end--}
1786
+ *
1776
1787
  */
1777
1788
  async dontSeeInSource(text) {
1778
1789
  const source = await this.page.content();
@@ -1789,9 +1800,9 @@ class Puppeteer extends Helper {
1789
1800
  * I.seeNumberOfElements('#submitBtn', 1);
1790
1801
  * ```
1791
1802
  *
1792
- * @param {string|object} locator element located by CSS|XPath|strict locator.
1803
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
1793
1804
  * @param {number} num number of elements.
1794
- * {--end--}
1805
+ *
1795
1806
  *
1796
1807
  * {{ react }}
1797
1808
  */
@@ -1808,9 +1819,9 @@ class Puppeteer extends Helper {
1808
1819
  * I.seeNumberOfVisibleElements('.buttons', 3);
1809
1820
  * ```
1810
1821
  *
1811
- * @param {string|object} locator element located by CSS|XPath|strict locator.
1822
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
1812
1823
  * @param {number} num number of elements.
1813
- * {--end--}
1824
+ *
1814
1825
  *
1815
1826
  * {{ react }}
1816
1827
  */
@@ -1827,7 +1838,6 @@ class Puppeteer extends Helper {
1827
1838
  * ```
1828
1839
  *
1829
1840
  * @param {object} cookie a cookie object.
1830
- * {--end--}
1831
1841
  */
1832
1842
  async setCookie(cookie) {
1833
1843
  if (Array.isArray(cookie)) {
@@ -1844,7 +1854,7 @@ class Puppeteer extends Helper {
1844
1854
  * ```
1845
1855
  *
1846
1856
  * @param {string} name cookie name.
1847
- * {--end--}
1857
+ *
1848
1858
  *
1849
1859
  */
1850
1860
  async seeCookie(name) {
@@ -1860,7 +1870,6 @@ class Puppeteer extends Helper {
1860
1870
  * ```
1861
1871
  *
1862
1872
  * @param {string} name cookie name.
1863
- * {--end--}
1864
1873
  */
1865
1874
  async dontSeeCookie(name) {
1866
1875
  const cookies = await this.page.cookies();
@@ -1870,16 +1879,15 @@ class Puppeteer extends Helper {
1870
1879
  /**
1871
1880
  * Gets a cookie object by name.
1872
1881
  * If none provided gets all cookies.
1873
- * * Resumes test execution, so **should be used inside async with `await`** operator.
1882
+ * Resumes test execution, so **should be used inside async with `await`** operator.
1874
1883
  *
1875
1884
  * ```js
1876
1885
  * let cookie = await I.grabCookie('auth');
1877
1886
  * assert(cookie.value, '123456');
1878
1887
  * ```
1879
1888
  *
1880
- * @param [name=null] cookie name.
1889
+ * @param {?string} [name=null] cookie name.
1881
1890
  * @returns {Promise<string>} attribute value
1882
- * {--end--}
1883
1891
  *
1884
1892
  * Returns cookie in JSON format. If name not passed returns all cookies for this domain.
1885
1893
  */
@@ -1899,8 +1907,7 @@ class Puppeteer extends Helper {
1899
1907
  * I.clearCookie('test');
1900
1908
  * ```
1901
1909
  *
1902
- * @param {string} cookie (optional, `null` by default) cookie name
1903
- * {--end--}
1910
+ * @param {?string} [cookie=null] (optional, `null` by default) cookie name
1904
1911
  */
1905
1912
  async clearCookie(name) {
1906
1913
  const cookies = await this.page.cookies();
@@ -1937,8 +1944,9 @@ class Puppeteer extends Helper {
1937
1944
  * ```
1938
1945
  *
1939
1946
  * @param {string|function} fn function to be executed in browser context.
1940
- * @param ...args args to be passed to function.
1941
- * {--end--}
1947
+ * @param {...any} args to be passed to function.
1948
+ * @return {Promise<any>}
1949
+ *
1942
1950
  *
1943
1951
  * If a function returns a Promise It will wait for it resolution.
1944
1952
  */
@@ -1973,8 +1981,9 @@ class Puppeteer extends Helper {
1973
1981
  * ```
1974
1982
  *
1975
1983
  * @param {string|function} fn function to be executed in browser context.
1976
- * @param ...args args to be passed to function.
1977
- * {--end--}
1984
+ * @param {...any} args to be passed to function.
1985
+ * @return {Promise<any>}
1986
+ *
1978
1987
  *
1979
1988
  * Asynchronous scripts can also be executed with `executeScript` if a function returns a Promise.
1980
1989
  */
@@ -2003,9 +2012,8 @@ class Puppeteer extends Helper {
2003
2012
  * ```
2004
2013
  * If multiple elements found returns an array of texts.
2005
2014
  *
2006
- * @param locator element located by CSS|XPath|strict locator.
2007
- * @returns {Promise<string>} attribute value
2008
- * {--end--}
2015
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
2016
+ * @returns {Promise<string|string[]>} attribute value
2009
2017
  * {{ react }}
2010
2018
  */
2011
2019
  async grabTextFrom(locator) {
@@ -2026,9 +2034,8 @@ class Puppeteer extends Helper {
2026
2034
  * ```js
2027
2035
  * let email = await I.grabValueFrom('input[name=email]');
2028
2036
  * ```
2029
- * @param {string|object} locator field located by label|name|CSS|XPath|strict locator.
2037
+ * @param {CodeceptJS.LocatorOrString} locator field located by label|name|CSS|XPath|strict locator.
2030
2038
  * @returns {Promise<string>} attribute value
2031
- * {--end--}
2032
2039
  */
2033
2040
  async grabValueFrom(locator) {
2034
2041
  const els = await findFields.call(this, locator);
@@ -2045,14 +2052,13 @@ class Puppeteer extends Helper {
2045
2052
  * let postHTML = await I.grabHTMLFrom('#post');
2046
2053
  * ```
2047
2054
  *
2048
- * @param locator element located by CSS|XPath|strict locator.
2055
+ * @param {CodeceptJS.LocatorOrString} element located by CSS|XPath|strict locator.
2049
2056
  * @returns {Promise<string>} HTML code for an element
2050
- * {--end--}
2051
2057
  */
2052
2058
  async grabHTMLFrom(locator) {
2053
2059
  const els = await this._locate(locator);
2054
2060
  assertElementExists(els, locator);
2055
- const values = await Promise.all(els.map(el => this.page.evaluate(element => element.innerHTML, el)));
2061
+ const values = await Promise.all(els.map(el => el.executionContext().evaluate(element => element.innerHTML, el)));
2056
2062
  if (Array.isArray(values) && values.length === 1) {
2057
2063
  return values[0];
2058
2064
  }
@@ -2067,16 +2073,15 @@ class Puppeteer extends Helper {
2067
2073
  * const value = await I.grabCssPropertyFrom('h3', 'font-weight');
2068
2074
  * ```
2069
2075
  *
2070
- * @param {string|object} locator element located by CSS|XPath|strict locator.
2076
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
2071
2077
  * @param {string} cssProperty CSS property name.
2072
2078
  * @returns {Promise<string>} CSS value
2073
- * {--end--}
2074
2079
  * {{ react }}
2075
2080
  */
2076
2081
  async grabCssPropertyFrom(locator, cssProperty) {
2077
2082
  const els = await this._locate(locator);
2078
2083
  const res = await Promise.all(els.map(el => el.executionContext().evaluate(el => JSON.parse(JSON.stringify(getComputedStyle(el))), el)));
2079
- const cssValues = res.map(props => props[cssProperty]);
2084
+ const cssValues = res.map(props => props[toCamelCase(cssProperty)]);
2080
2085
 
2081
2086
  if (res.length > 0) {
2082
2087
  return cssValues;
@@ -2091,9 +2096,8 @@ class Puppeteer extends Helper {
2091
2096
  * I.seeCssPropertiesOnElements('h3', { 'font-weight': "bold"});
2092
2097
  * ```
2093
2098
  *
2094
- * @param {string|object} locator located by CSS|XPath|strict locator.
2099
+ * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|strict locator.
2095
2100
  * @param {object} cssProperties object with CSS properties and their values to check.
2096
- * {--end--}
2097
2101
  * {{ react }}
2098
2102
  */
2099
2103
  async seeCssPropertiesOnElements(locator, cssProperties) {
@@ -2138,9 +2142,8 @@ class Puppeteer extends Helper {
2138
2142
  * I.seeAttributesOnElements('//form', { method: "post"});
2139
2143
  * ```
2140
2144
  *
2141
- * @param {string|object} locator located by CSS|XPath|strict locator.
2145
+ * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|strict locator.
2142
2146
  * @param {object} attributes attributes and their values to check.
2143
- * {--end--}
2144
2147
  * {{ react }}
2145
2148
  */
2146
2149
  async seeAttributesOnElements(locator, attributes) {
@@ -2179,9 +2182,8 @@ class Puppeteer extends Helper {
2179
2182
  * I.dragSlider('#slider', -70);
2180
2183
  * ```
2181
2184
  *
2182
- * @param {string|object} locator located by label|name|CSS|XPath|strict locator.
2185
+ * @param {CodeceptJS.LocatorOrString} locator located by label|name|CSS|XPath|strict locator.
2183
2186
  * @param {number} offsetX position to drag.
2184
- * {--end--}
2185
2187
  * {{ react }}
2186
2188
  */
2187
2189
  async dragSlider(locator, offsetX = 0) {
@@ -2210,10 +2212,9 @@ class Puppeteer extends Helper {
2210
2212
  * ```js
2211
2213
  * let hint = await I.grabAttributeFrom('#tooltip', 'title');
2212
2214
  * ```
2213
- * @param {string|object} locator element located by CSS|XPath|strict locator.
2215
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
2214
2216
  * @param {string} attr attribute name.
2215
2217
  * @returns {Promise<string>} attribute value
2216
- * {--end--}
2217
2218
  * {{ react }}
2218
2219
  */
2219
2220
  async grabAttributeFrom(locator, attr) {
@@ -2240,8 +2241,7 @@ class Puppeteer extends Helper {
2240
2241
  * ```
2241
2242
  *
2242
2243
  * @param {string} fileName file name to save.
2243
- * @param {boolean} fullPage (optional, `false` by default) flag to enable fullscreen screenshot mode.
2244
- * {--end--}
2244
+ * @param {boolean} [fullPage=false] (optional, `false` by default) flag to enable fullscreen screenshot mode.
2245
2245
  */
2246
2246
  async saveScreenshot(fileName, fullPage) {
2247
2247
  const fullPageOption = fullPage || this.options.fullPageScreenshots;
@@ -2267,7 +2267,6 @@ class Puppeteer extends Helper {
2267
2267
  * ```
2268
2268
  *
2269
2269
  * @param {number} sec number of second to wait.
2270
- * {--end--}
2271
2270
  */
2272
2271
  async wait(sec) {
2273
2272
  return new Promise(((done) => {
@@ -2279,9 +2278,8 @@ class Puppeteer extends Helper {
2279
2278
  * Waits for element to become enabled (by default waits for 1sec).
2280
2279
  * Element can be located by CSS or XPath.
2281
2280
  *
2282
- * @param {string|object} locator element located by CSS|XPath|strict locator.
2283
- * @param sec (optional) time in seconds to wait, 1 by default.
2284
- * {--end--}
2281
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
2282
+ * @param {number} [sec=1] (optional) time in seconds to wait, 1 by default.
2285
2283
  */
2286
2284
  async waitForEnabled(locator, sec) {
2287
2285
  const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
@@ -2319,8 +2317,7 @@ class Puppeteer extends Helper {
2319
2317
  *
2320
2318
  * @param {string|object} field input field.
2321
2319
  * @param {string }value expected value.
2322
- * @param {number} sec (optional, `1` by default) time in seconds to wait
2323
- * {--end--}
2320
+ * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
2324
2321
  */
2325
2322
  async waitForValue(field, value, sec) {
2326
2323
  const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
@@ -2357,10 +2354,9 @@ class Puppeteer extends Helper {
2357
2354
  * I.waitNumberOfVisibleElements('a', 3);
2358
2355
  * ```
2359
2356
  *
2360
- * @param {string|object} locator element located by CSS|XPath|strict locator.
2357
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
2361
2358
  * @param {number} num number of elements.
2362
- * @param {number} sec (optional, `1` by default) time in seconds to wait
2363
- * {--end--}
2359
+ * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
2364
2360
  * {{ react }}
2365
2361
  */
2366
2362
  async waitNumberOfVisibleElements(locator, num, sec) {
@@ -2390,6 +2386,31 @@ class Puppeteer extends Helper {
2390
2386
  });
2391
2387
  }
2392
2388
 
2389
+ /**
2390
+ * Waits for element to be clickable (by default waits for 1sec).
2391
+ * Element can be located by CSS or XPath.
2392
+ *
2393
+ * ```js
2394
+ * I.waitForClickable('.btn.continue');
2395
+ * I.waitForClickable('.btn.continue', 5); // wait for 5 secs
2396
+ * ```
2397
+ *
2398
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
2399
+ * @param {number} [sec] (optional, `1` by default) time in seconds to wait
2400
+ */
2401
+ async waitForClickable(locator, waitTimeout) {
2402
+ const els = await this._locate(locator);
2403
+ assertElementExists(els, locator);
2404
+
2405
+ return this.waitForFunction(isElementClickable, [els[0]], waitTimeout).catch(async (e) => {
2406
+ if (/failed: timeout/i.test(e.message)) {
2407
+ throw new Error(`element ${new Locator(locator).toString()} still not clickable after ${waitTimeout || this.options.waitForTimeout / 1000} sec`);
2408
+ } else {
2409
+ throw e;
2410
+ }
2411
+ });
2412
+ }
2413
+
2393
2414
  /**
2394
2415
  * Waits for element to be present on page (by default waits for 1sec).
2395
2416
  * Element can be located by CSS or XPath.
@@ -2399,9 +2420,8 @@ class Puppeteer extends Helper {
2399
2420
  * I.waitForElement('.btn.continue', 5); // wait for 5 secs
2400
2421
  * ```
2401
2422
  *
2402
- * @param {string|object} locator element located by CSS|XPath|strict locator.
2403
- * @param {number} sec (optional, `1` by default) time in seconds to wait
2404
- * {--end--}
2423
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
2424
+ * @param {number} [sec] (optional, `1` by default) time in seconds to wait
2405
2425
  * {{ react }}
2406
2426
  */
2407
2427
  async waitForElement(locator, sec) {
@@ -2428,9 +2448,8 @@ class Puppeteer extends Helper {
2428
2448
  * I.waitForVisible('#popup');
2429
2449
  * ```
2430
2450
  *
2431
- * @param {string|object} locator element located by CSS|XPath|strict locator.
2432
- * @param {number} sec (optional, `1` by default) time in seconds to wait
2433
- * {--end--}
2451
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
2452
+ * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
2434
2453
  *
2435
2454
  * This method accepts [React selectors](https://codecept.io/react).
2436
2455
  */
@@ -2458,9 +2477,8 @@ class Puppeteer extends Helper {
2458
2477
  * I.waitForInvisible('#popup');
2459
2478
  * ```
2460
2479
  *
2461
- * @param {string|object} locator element located by CSS|XPath|strict locator.
2462
- * @param {number} sec (optional, `1` by default) time in seconds to wait
2463
- * {--end--}
2480
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
2481
+ * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
2464
2482
  */
2465
2483
  async waitForInvisible(locator, sec) {
2466
2484
  const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
@@ -2486,9 +2504,8 @@ class Puppeteer extends Helper {
2486
2504
  * I.waitToHide('#popup');
2487
2505
  * ```
2488
2506
  *
2489
- * @param {string|object} locator element located by CSS|XPath|strict locator.
2490
- * @param {number} sec (optional, `1` by default) time in seconds to wait
2491
- * {--end--}
2507
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
2508
+ * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
2492
2509
  */
2493
2510
  async waitToHide(locator, sec) {
2494
2511
  const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
@@ -2520,8 +2537,7 @@ class Puppeteer extends Helper {
2520
2537
  * ```
2521
2538
  *
2522
2539
  * @param {string} urlPart value to check.
2523
- * @param {number} sec (optional, `1` by default) time in seconds to wait
2524
- * {--end--}
2540
+ * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
2525
2541
  */
2526
2542
  async waitInUrl(urlPart, sec = null) {
2527
2543
  const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
@@ -2548,8 +2564,7 @@ class Puppeteer extends Helper {
2548
2564
  * ```
2549
2565
  *
2550
2566
  * @param {string} urlPart value to check.
2551
- * @param {number} sec (optional, `1` by default) time in seconds to wait
2552
- * {--end--}
2567
+ * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
2553
2568
  */
2554
2569
  async waitUrlEquals(urlPart, sec = null) {
2555
2570
  const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
@@ -2583,9 +2598,8 @@ class Puppeteer extends Helper {
2583
2598
  * ```
2584
2599
  *
2585
2600
  * @param {string }text to wait for.
2586
- * @param {number} sec (optional, `1` by default) time in seconds to wait
2587
- * @param {string|object} context (optional) element located by CSS|XPath|strict locator.
2588
- * {--end--}
2601
+ * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
2602
+ * @param {CodeceptJS.LocatorOrString} [context] (optional) element located by CSS|XPath|strict locator.
2589
2603
  */
2590
2604
  async waitForText(text, sec = null, context = null) {
2591
2605
  const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
@@ -2605,10 +2619,11 @@ class Puppeteer extends Helper {
2605
2619
 
2606
2620
  if (locator.isXPath()) {
2607
2621
  waiter = contextObject.waitForFunction((locator, text, $XPath) => {
2622
+ eval($XPath); // eslint-disable-line no-eval
2608
2623
  const el = $XPath(null, locator);
2609
2624
  if (!el.length) return false;
2610
2625
  return el[0].innerText.indexOf(text) > -1;
2611
- }, { timeout: waitTimeout }, locator.value, text, $XPath);
2626
+ }, { timeout: waitTimeout }, locator.value, text, $XPath.toString());
2612
2627
  }
2613
2628
  } else {
2614
2629
  waiter = contextObject.waitForFunction(text => document.body.innerText.indexOf(text) > -1, { timeout: waitTimeout }, text);
@@ -2628,7 +2643,7 @@ class Puppeteer extends Helper {
2628
2643
  * ```
2629
2644
  *
2630
2645
  * @param {string|function} urlOrPredicate
2631
- * @param {number?} [sec=null] seconds to wait
2646
+ * @param {?number} [sec=null] seconds to wait
2632
2647
  */
2633
2648
  async waitForRequest(urlOrPredicate, sec = null) {
2634
2649
  const timeout = sec ? sec * 1000 : this.options.waitForTimeout;
@@ -2644,7 +2659,7 @@ class Puppeteer extends Helper {
2644
2659
  * ```
2645
2660
  *
2646
2661
  * @param {string|function} urlOrPredicate
2647
- * @param {number?} [sec=null] number of seconds to wait
2662
+ * @param {?number} [sec=null] number of seconds to wait
2648
2663
  */
2649
2664
  async waitForResponse(urlOrPredicate, sec = null) {
2650
2665
  const timeout = sec ? sec * 1000 : this.options.waitForTimeout;
@@ -2659,8 +2674,7 @@ class Puppeteer extends Helper {
2659
2674
  * I.switchTo(); // switch back to main page
2660
2675
  * ```
2661
2676
  *
2662
- * @param {string|object} locator (optional, `null` by default) element located by CSS|XPath|strict locator.
2663
- * {--end--}
2677
+ * @param {?CodeceptJS.LocatorOrString} [locator=null] (optional, `null` by default) element located by CSS|XPath|strict locator.
2664
2678
  */
2665
2679
  async switchTo(locator) {
2666
2680
  if (Number.isInteger(locator)) {
@@ -2679,7 +2693,8 @@ class Puppeteer extends Helper {
2679
2693
  throw new Error('Element #invalidIframeSelector was not found by text|CSS|XPath');
2680
2694
  }
2681
2695
  return;
2682
- } else if (!locator) {
2696
+ }
2697
+ if (!locator) {
2683
2698
  this.context = await this.page.mainFrame().$('body');
2684
2699
  return;
2685
2700
  }
@@ -2711,9 +2726,9 @@ class Puppeteer extends Helper {
2711
2726
  * ```
2712
2727
  *
2713
2728
  * @param {string|function} fn to be executed in browser context.
2714
- * @param {array|number} argsOrSec (optional, `1` by default) arguments for function or seconds.
2715
- * @param {number} sec (optional, `1` by default) time in seconds to wait
2716
- * {--end--}
2729
+ * @param {any[]|number} [argsOrSec] (optional, `1` by default) arguments for function or seconds.
2730
+ * @param {number} [sec] (optional, `1` by default) time in seconds to wait
2731
+ *
2717
2732
  */
2718
2733
  async waitForFunction(fn, argsOrSec = null, sec = null) {
2719
2734
  let args = [];
@@ -2737,7 +2752,11 @@ class Puppeteer extends Helper {
2737
2752
  * @param {*} opts
2738
2753
  */
2739
2754
  async waitForNavigation(opts = {}) {
2740
- opts = Object.assign({ timeout: this.options.getPageTimeout, waitUntil: this.options.waitForNavigation }, opts);
2755
+ opts = {
2756
+ timeout: this.options.getPageTimeout,
2757
+ waitUntil: this.options.waitForNavigation,
2758
+ ...opts,
2759
+ };
2741
2760
  return this.page.waitForNavigation(opts);
2742
2761
  }
2743
2762
 
@@ -2750,9 +2769,9 @@ class Puppeteer extends Helper {
2750
2769
  * ```
2751
2770
  *
2752
2771
  * @param {function|string} fn function which is executed in browser context.
2753
- * @param {number} sec (optional, `1` by default) time in seconds to wait
2772
+ * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
2754
2773
  * @param {string} [timeoutMsg=''] message to show in case of timeout fail.
2755
- * {--end--}
2774
+ * @param {?number} [interval=null]
2756
2775
  */
2757
2776
  async waitUntil(fn, sec = null) {
2758
2777
  console.log('This method will remove in CodeceptJS 1.4; use `waitForFunction` instead!');
@@ -2776,9 +2795,8 @@ class Puppeteer extends Helper {
2776
2795
  * I.waitForDetached('#popup');
2777
2796
  * ```
2778
2797
  *
2779
- * @param {string|object} locator element located by CSS|XPath|strict locator.
2780
- * @param {number} sec (optional, `1` by default) time in seconds to wait
2781
- * {--end--}
2798
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
2799
+ * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
2782
2800
  */
2783
2801
  async waitForDetached(locator, sec) {
2784
2802
  const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
@@ -2827,7 +2845,6 @@ class Puppeteer extends Helper {
2827
2845
  * loadEventEnd: 241
2828
2846
  * }
2829
2847
  * ```
2830
- * {--end--}
2831
2848
  */
2832
2849
  async grabDataFromPerformanceTiming() {
2833
2850
  return perfTiming;
@@ -2854,7 +2871,6 @@ class Puppeteer extends Helper {
2854
2871
  * @param {string|object} locator element located by CSS|XPath|strict locator.
2855
2872
  * @param {string} elementSize x, y, width or height of the given element.
2856
2873
  * @returns {object} Element bounding rectangle
2857
- * {--end--}
2858
2874
  */
2859
2875
  async grabElementBoundingRect(locator, prop) {
2860
2876
  const els = await this._locate(locator);