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
@@ -2,11 +2,12 @@
2
2
  const fs = require('fs');
3
3
  const assert = require('assert');
4
4
  const path = require('path');
5
+ const qrcode = require('qrcode-terminal');
5
6
  const requireg = require('requireg');
6
7
  const createTestCafe = require('testcafe');
7
8
  const { Selector, ClientFunction } = require('testcafe');
8
- const ElementNotFound = require('./errors/ElementNotFound');
9
9
 
10
+ const ElementNotFound = require('./errors/ElementNotFound');
10
11
  const testControllerHolder = require('./testcafe/testControllerHolder');
11
12
  const {
12
13
  mapError,
@@ -67,6 +68,21 @@ const getHtmlSource = t => ClientFunction(() => document.getElementsByTagName('h
67
68
  * }
68
69
  * ```
69
70
  *
71
+ * To use remote device you can provide 'remote' as browser parameter this will display a link with QR Code
72
+ * See https://devexpress.github.io/testcafe/documentation/recipes/test-on-remote-computers-and-mobile-devices.html
73
+ * #### Example #2: Remote browser connection
74
+ *
75
+ * ```js
76
+ * {
77
+ * helpers: {
78
+ * TestCafe : {
79
+ * url: "http://localhost",
80
+ * waitForTimeout: 15000,
81
+ * browser: "remote"
82
+ * }
83
+ * }
84
+ * }
85
+ * ```
70
86
  *
71
87
  * ## Access From Helpers
72
88
  *
@@ -96,7 +112,7 @@ class TestCafe extends Helper {
96
112
  this.context = undefined; // TODO Not sure if this applies to testcafe
97
113
 
98
114
 
99
- this.options = Object.assign({
115
+ this.options = {
100
116
  url: 'http://localhost',
101
117
  show: false,
102
118
  browser: 'chrome',
@@ -108,7 +124,8 @@ class TestCafe extends Helper {
108
124
  fullPageScreenshots: false,
109
125
  disableScreenshots: false,
110
126
  windowSize: undefined,
111
- }, config);
127
+ ...config,
128
+ };
112
129
  }
113
130
 
114
131
  // TOOD Do a requirements check
@@ -130,12 +147,12 @@ class TestCafe extends Helper {
130
147
  ];
131
148
  }
132
149
 
133
- async _startBrowser() {
150
+ async _configureAndStartBrowser() {
134
151
  this.dummyTestcafeFile = createTestFile(global.output_dir); // create a dummy test file to get hold of the test controller
135
152
 
136
153
  this.iteration += 2; // Use different ports for each test run
137
154
  // @ts-ignore
138
- this.testcafe = await createTestCafe('localhost', null, null);
155
+ this.testcafe = await createTestCafe('', null, null);
139
156
 
140
157
  this.debugSection('_before', 'Starting testcafe browser...');
141
158
 
@@ -143,6 +160,19 @@ class TestCafe extends Helper {
143
160
 
144
161
  // TODO Do we have to cleanup the runner?
145
162
  const runner = this.testcafe.createRunner();
163
+
164
+ this.options.browser !== 'remote' ? this._startBrowser(runner) : this._startRemoteBrowser(runner);
165
+
166
+ this.t = await testControllerHolder.get();
167
+ assert(this.t, 'Expected to have the testcafe test controller');
168
+
169
+ if (this.options.windowSize && this.options.windowSize.indexOf('x') > 0) {
170
+ const dimensions = this.options.windowSize.split('x');
171
+ await this.t.resizeWindow(parseInt(dimensions[0], 10), parseInt(dimensions[1], 10));
172
+ }
173
+ }
174
+
175
+ async _startBrowser(runner) {
146
176
  runner
147
177
  .src(this.dummyTestcafeFile)
148
178
  .screenshots(global.output_dir, !this.options.disableScreenshots)
@@ -166,16 +196,31 @@ class TestCafe extends Helper {
166
196
  this.isRunning = false;
167
197
  this.testcafe.close();
168
198
  });
199
+ }
169
200
 
170
- this.t = await testControllerHolder.get();
171
- assert(this.t, 'Expected to have the testcafe test controller');
172
-
173
- if (this.options.windowSize && this.options.windowSize.indexOf('x') > 0) {
174
- const dimensions = this.options.windowSize.split('x');
175
- await this.t.resizeWindow(parseInt(dimensions[0], 10), parseInt(dimensions[1], 10));
176
- }
201
+ async _startRemoteBrowser(runner) {
202
+ const remoteConnection = await this.testcafe.createBrowserConnection();
203
+ console.log('Connect your device to the following URL or scan QR Code: ', remoteConnection.url);
204
+ qrcode.generate(remoteConnection.url);
205
+ remoteConnection.once('ready', () => {
206
+ runner
207
+ .src(this.dummyTestcafeFile)
208
+ .browsers(remoteConnection)
209
+ .reporter('minimal')
210
+ .run({
211
+ selectorTimeout: this.options.waitForTimeout,
212
+ skipJsErrors: true,
213
+ skipUncaughtErrors: true,
214
+ })
215
+ .catch((err) => {
216
+ this.debugSection('_before', `Error ${err.toString()}`);
217
+ this.isRunning = false;
218
+ this.testcafe.close();
219
+ });
220
+ });
177
221
  }
178
222
 
223
+
179
224
  async _stopBrowser() {
180
225
  this.debugSection('_after', 'Stopping testcafe browser...');
181
226
 
@@ -190,19 +235,20 @@ class TestCafe extends Helper {
190
235
  this.isRunning = false;
191
236
  }
192
237
 
193
- _init() {}
238
+ _init() {
239
+ }
194
240
 
195
241
  async _beforeSuite() {
196
242
  if (!this.options.restart && !this.options.manualStart && !this.isRunning) {
197
243
  this.debugSection('Session', 'Starting singleton browser session');
198
- return this._startBrowser();
244
+ return this._configureAndStartBrowser();
199
245
  }
200
246
  }
201
247
 
202
248
 
203
249
  async _before() {
204
- if (this.options.restart && !this.options.manualStart) return this._startBrowser();
205
- if (!this.isRunning && !this.options.manualStart) return this._startBrowser();
250
+ if (this.options.restart && !this.options.manualStart) return this._configureAndStartBrowser();
251
+ if (!this.isRunning && !this.options.manualStart) return this._configureAndStartBrowser();
206
252
  this.context = null;
207
253
  }
208
254
 
@@ -269,7 +315,6 @@ class TestCafe extends Helper {
269
315
  * ```
270
316
  *
271
317
  * @param {string} url url path or global url.
272
- * {--end--}
273
318
  */
274
319
  async amOnPage(url) {
275
320
  if (!(/^\w+\:\/\//.test(url))) {
@@ -287,7 +332,6 @@ class TestCafe extends Helper {
287
332
  *
288
333
  * @param {number} width width in pixels or `maximize`.
289
334
  * @param {number} height height in pixels.
290
- * {--end--}
291
335
  */
292
336
  async resizeWindow(width, height) {
293
337
  if (width === 'maximize') {
@@ -320,9 +364,9 @@ class TestCafe extends Helper {
320
364
  * I.click({css: 'nav a.login'});
321
365
  * ```
322
366
  *
323
- * @param {string|object} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
324
- * @param {string|object} context (optional, `null` by default) element to search in CSS|XPath|Strict locator.
325
- * {--end--}
367
+ * @param {CodeceptJS.LocatorOrString} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
368
+ * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element to search in CSS|XPath|Strict locator.
369
+ *
326
370
  *
327
371
  */
328
372
  async click(locator, context = null) {
@@ -336,7 +380,7 @@ class TestCafe extends Helper {
336
380
  * ```js
337
381
  * I.refreshPage();
338
382
  * ```
339
- * {--end--}
383
+ *
340
384
  */
341
385
  async refreshPage() {
342
386
  // eslint-disable-next-line no-restricted-globals
@@ -351,9 +395,8 @@ class TestCafe extends Helper {
351
395
  * I.waitForVisible('#popup');
352
396
  * ```
353
397
  *
354
- * @param {string|object} locator element located by CSS|XPath|strict locator.
355
- * @param {number} sec (optional, `1` by default) time in seconds to wait
356
- * {--end--}
398
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
399
+ * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
357
400
  *
358
401
  */
359
402
  async waitForVisible(locator, sec) {
@@ -378,9 +421,9 @@ class TestCafe extends Helper {
378
421
  * // or by strict locator
379
422
  * I.fillField({css: 'form#login input[name=username]'}, 'John');
380
423
  * ```
381
- * @param {string|object} field located by label|name|CSS|XPath|strict locator.
424
+ * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator.
382
425
  * @param {string} value text value to fill.
383
- * {--end--}
426
+ *
384
427
  */
385
428
  async fillField(field, value) {
386
429
  const els = await findFields.call(this, field);
@@ -400,16 +443,16 @@ class TestCafe extends Helper {
400
443
  * I.clearField('#email');
401
444
  * ```
402
445
  * @param {string|object} editable field located by label|name|CSS|XPath|strict locator.
403
- * {--end--}
404
446
  */
405
447
  async clearField(field) {
406
448
  const els = await findFields.call(this, field);
407
449
  assertElementExists(els, field, 'Field');
408
450
  const el = await els.nth(0);
409
451
 
410
- return this.t
411
- .click(el)
412
- .pressKey('ctrl+a delete');
452
+ const res = await this.t
453
+ .selectText(el)
454
+ .pressKey('delete');
455
+ return res;
413
456
  }
414
457
 
415
458
  /**
@@ -419,9 +462,8 @@ class TestCafe extends Helper {
419
462
  * ```js
420
463
  * I.appendField('#myTextField', 'appended');
421
464
  * ```
422
- * @param {string|object} field located by label|name|CSS|XPath|strict locator
465
+ * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator
423
466
  * @param {string} value text value to append.
424
- * {--end--}
425
467
  *
426
468
  */
427
469
  async appendField(field, value) {
@@ -444,9 +486,8 @@ class TestCafe extends Helper {
444
486
  * I.attachFile('form input[name=avatar]', 'data/avatar.jpg');
445
487
  * ```
446
488
  *
447
- * @param {string|object} locator field located by label|name|CSS|XPath|strict locator.
489
+ * @param {CodeceptJS.LocatorOrString} locator field located by label|name|CSS|XPath|strict locator.
448
490
  * @param {string} pathToFile local file path relative to codecept.json config file.
449
- * {--end--}
450
491
  *
451
492
  */
452
493
  async attachFile(field, pathToFile) {
@@ -471,8 +512,7 @@ class TestCafe extends Helper {
471
512
  * I.pressKey(['Control','a']);
472
513
  * ```
473
514
  *
474
- * @param {string|array} key key or array of keys to press.
475
- * {--end--}
515
+ * @param {string|string[]} key key or array of keys to press.
476
516
  *
477
517
  * {{ keys }}
478
518
  */
@@ -493,10 +533,10 @@ class TestCafe extends Helper {
493
533
  * I.moveCursorTo('#submit', 5,5);
494
534
  * ```
495
535
  *
496
- * @param {string|object} locator located by CSS|XPath|strict locator.
497
- * @param {number} offsetX (optional, `0` by default) X-axis offset.
498
- * @param {number} offsetY (optional, `0` by default) Y-axis offset.
499
- * {--end--}
536
+ * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|strict locator.
537
+ * @param {number} [offsetX=0] (optional, `0` by default) X-axis offset.
538
+ * @param {number} [offsetY=0] (optional, `0` by default) Y-axis offset.
539
+ *
500
540
  *
501
541
  */
502
542
  async moveCursorTo(locator, offsetX = 0, offsetY = 0) {
@@ -519,9 +559,9 @@ class TestCafe extends Helper {
519
559
  * I.doubleClick('.btn.edit');
520
560
  * ```
521
561
  *
522
- * @param {string|object} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
523
- * @param {string|object} context (optional, `null` by default) element to search in CSS|XPath|Strict locator.
524
- * {--end--}
562
+ * @param {CodeceptJS.LocatorOrString} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
563
+ * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element to search in CSS|XPath|Strict locator.
564
+ *
525
565
  *
526
566
  */
527
567
  async doubleClick(locator, context = null) {
@@ -550,9 +590,9 @@ class TestCafe extends Helper {
550
590
  * I.rightClick('Click me', '.context');
551
591
  * ```
552
592
  *
553
- * @param {string|object} locator clickable element located by CSS|XPath|strict locator.
554
- * @param {string|object} context (optional, `null` by default) element located by CSS|XPath|strict locator.
555
- * {--end--}
593
+ * @param {CodeceptJS.LocatorOrString} locator clickable element located by CSS|XPath|strict locator.
594
+ * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element located by CSS|XPath|strict locator.
595
+ *
556
596
  *
557
597
  */
558
598
  async rightClick(locator, context = null) {
@@ -580,9 +620,8 @@ class TestCafe extends Helper {
580
620
  * I.checkOption('I Agree to Terms and Conditions');
581
621
  * I.checkOption('agree', '//form');
582
622
  * ```
583
- * @param {string|object} field checkbox located by label | name | CSS | XPath | strict locator.
584
- * @param {string} context (optional, `null` by default) element located by CSS | XPath | strict locator.
585
- * {--end--}
623
+ * @param {CodeceptJS.LocatorOrString} field checkbox located by label | name | CSS | XPath | strict locator.
624
+ * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element located by CSS | XPath | strict locator.
586
625
  */
587
626
  async checkOption(field, context = null) {
588
627
  const el = await findCheckable.call(this, field, context);
@@ -603,9 +642,8 @@ class TestCafe extends Helper {
603
642
  * I.uncheckOption('I Agree to Terms and Conditions');
604
643
  * I.uncheckOption('agree', '//form');
605
644
  * ```
606
- * @param {string|object} field checkbox located by label | name | CSS | XPath | strict locator.
607
- * @param {string} context (optional, `null` by default) element located by CSS | XPath | strict locator.
608
- * {--end--}
645
+ * @param {CodeceptJS.LocatorOrString} field checkbox located by label | name | CSS | XPath | strict locator.
646
+ * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element located by CSS | XPath | strict locator.
609
647
  */
610
648
  async uncheckOption(field, context = null) {
611
649
  const el = await findCheckable.call(this, field, context);
@@ -626,8 +664,8 @@ class TestCafe extends Helper {
626
664
  * I.seeCheckboxIsChecked({css: '#signup_form input[type=checkbox]'});
627
665
  * ```
628
666
  *
629
- * @param {string|object} field located by label|name|CSS|XPath|strict locator.
630
- * {--end--}
667
+ * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator.
668
+ *
631
669
  */
632
670
  async seeCheckboxIsChecked(field) {
633
671
  return proceedIsChecked.call(this, 'assert', field);
@@ -642,8 +680,8 @@ class TestCafe extends Helper {
642
680
  * I.dontSeeCheckboxIsChecked('agree'); // located by name
643
681
  * ```
644
682
  *
645
- * @param {string|object} field located by label|name|CSS|XPath|strict locator.
646
- * {--end--}
683
+ * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator.
684
+ *
647
685
  */
648
686
  async dontSeeCheckboxIsChecked(field) {
649
687
  return proceedIsChecked.call(this, 'negate', field);
@@ -668,9 +706,8 @@ class TestCafe extends Helper {
668
706
  * ```js
669
707
  * I.selectOption('Which OS do you use?', ['Android', 'iOS']);
670
708
  * ```
671
- * @param {string|object} select field located by label|name|CSS|XPath|strict locator.
672
- * @param {string|array} option visible text or value of option.
673
- * {--end--}
709
+ * @param {CodeceptJS.LocatorOrString} select field located by label|name|CSS|XPath|strict locator.
710
+ * @param {string|Array<*>} option visible text or value of option.
674
711
  */
675
712
  async selectOption(select, option) {
676
713
  const els = await findFields.call(this, select);
@@ -698,8 +735,9 @@ class TestCafe extends Helper {
698
735
  await this.t.click(optEl, clickOpts).catch(mapError);
699
736
  continue;
700
737
  }
701
- // eslint-disable-next-line no-empty
702
- } catch (err) {}
738
+ // eslint-disable-next-line no-empty
739
+ } catch (err) {
740
+ }
703
741
 
704
742
  try {
705
743
  const sel = `[value="${opt}"]`;
@@ -707,8 +745,9 @@ class TestCafe extends Helper {
707
745
  if (await optEl.count) {
708
746
  await this.t.click(optEl, clickOpts).catch(mapError);
709
747
  }
710
- // eslint-disable-next-line no-empty
711
- } catch (err) {}
748
+ // eslint-disable-next-line no-empty
749
+ } catch (err) {
750
+ }
712
751
  }
713
752
  }
714
753
 
@@ -720,24 +759,22 @@ class TestCafe extends Helper {
720
759
  * ```
721
760
  *
722
761
  * @param {string} url a fragment to check
723
- * {--end--}
724
762
  */
725
763
  async seeInCurrentUrl(url) {
726
764
  stringIncludes('url').assert(url, await getPageUrl(this.t)().catch(mapError));
727
765
  }
728
766
 
729
767
  /**
730
- * Checks that current url does not contain a provided fragment.
768
+ * Checks that current url does not contain a provided fragment.
731
769
  *
732
770
  * @param {string} url value to check.
733
- * {--end--}
734
- */
771
+ */
735
772
  async dontSeeInCurrentUrl(url) {
736
773
  stringIncludes('url').negate(url, await getPageUrl(this.t)().catch(mapError));
737
774
  }
738
775
 
739
776
  /**
740
- * Checks that current url is equal to provided one.
777
+ * Checks that current url is equal to provided one.
741
778
  * If a relative url provided, a configured url will be prepended to it.
742
779
  * So both examples will work:
743
780
  *
@@ -747,14 +784,13 @@ class TestCafe extends Helper {
747
784
  * ```
748
785
  *
749
786
  * @param {string} url value to check.
750
- * {--end--}
751
- */
787
+ */
752
788
  async seeCurrentUrlEquals(url) {
753
789
  urlEquals(this.options.url).assert(url, await getPageUrl(this.t)().catch(mapError));
754
790
  }
755
791
 
756
792
  /**
757
- * Checks that current url is not equal to provided one.
793
+ * Checks that current url is not equal to provided one.
758
794
  * If a relative url provided, a configured url will be prepended to it.
759
795
  *
760
796
  * ```js
@@ -763,8 +799,7 @@ class TestCafe extends Helper {
763
799
  * ```
764
800
  *
765
801
  * @param {string} url value to check.
766
- * {--end--}
767
- */
802
+ */
768
803
  async dontSeeCurrentUrlEquals(url) {
769
804
  urlEquals(this.options.url).negate(url, await getPageUrl(this.t)().catch(mapError));
770
805
  }
@@ -779,8 +814,7 @@ class TestCafe extends Helper {
779
814
  * I.see('Register', {css: 'form.register'}); // use strict locator
780
815
  * ```
781
816
  * @param {string} text expected on page.
782
- * @param {string|object} context (optional, `null` by default) element located by CSS|Xpath|strict locator in which to search for text.
783
- * {--end--}
817
+ * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element located by CSS|Xpath|strict locator in which to search for text.
784
818
  *
785
819
  */
786
820
  async see(text, context = null) {
@@ -806,9 +840,8 @@ class TestCafe extends Helper {
806
840
  * ```
807
841
  *
808
842
  * @param {string} text which is not present.
809
- * @param {string|object} context (optional) element located by CSS|XPath|strict locator in which to perfrom search.
810
- *
811
- * {--end--}
843
+ * @param {CodeceptJS.LocatorOrString} [context] (optional) element located by CSS|XPath|strict locator in which to perfrom search.
844
+ *
812
845
  *
813
846
  */
814
847
  async dontSee(text, context = null) {
@@ -831,8 +864,7 @@ class TestCafe extends Helper {
831
864
  * ```js
832
865
  * I.seeElement('#modal');
833
866
  * ```
834
- * @param {string|object} locator located by CSS|XPath|strict locator.
835
- * {--end--}
867
+ * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|strict locator.
836
868
  */
837
869
  async seeElement(locator) {
838
870
  const exists = (await findElements.call(this, this.context, locator)).filterVisible().exists;
@@ -848,8 +880,7 @@ class TestCafe extends Helper {
848
880
  * I.dontSeeElement('.modal'); // modal is not shown
849
881
  * ```
850
882
  *
851
- * @param {string|object} locator located by CSS|XPath|Strict locator.
852
- * {--end--}
883
+ * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|Strict locator.
853
884
  */
854
885
  async dontSeeElement(locator) {
855
886
  const exists = (await findElements.call(this, this.context, locator)).filterVisible().exists;
@@ -865,8 +896,8 @@ class TestCafe extends Helper {
865
896
  * ```js
866
897
  * I.seeElementInDOM('#modal');
867
898
  * ```
868
- * @param {string|object} locator element located by CSS|XPath|strict locator.
869
- * {--end--}
899
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
900
+ *
870
901
  */
871
902
  async seeElementInDOM(locator) {
872
903
  const exists = (await findElements.call(this, this.context, locator)).exists;
@@ -882,8 +913,7 @@ class TestCafe extends Helper {
882
913
  * I.dontSeeElementInDOM('.nav'); // checks that element is not on page visible or not
883
914
  * ```
884
915
  *
885
- * @param {string|object} locator located by CSS|XPath|Strict locator.
886
- * {--end--}
916
+ * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|Strict locator.
887
917
  */
888
918
  async dontSeeElementInDOM(locator) {
889
919
  const exists = (await findElements.call(this, this.context, locator)).exists;
@@ -900,9 +930,9 @@ class TestCafe extends Helper {
900
930
  * I.seeNumberOfVisibleElements('.buttons', 3);
901
931
  * ```
902
932
  *
903
- * @param {string|object} locator element located by CSS|XPath|strict locator.
933
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
904
934
  * @param {number} num number of elements.
905
- * {--end--}
935
+ *
906
936
  *
907
937
  */
908
938
  async seeNumberOfVisibleElements(locator, num) {
@@ -919,9 +949,8 @@ class TestCafe extends Helper {
919
949
  * let numOfElements = await I.grabNumberOfVisibleElements('p');
920
950
  * ```
921
951
  *
922
- * @param {string|object} locator located by CSS|XPath|strict locator.
952
+ * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|strict locator.
923
953
  * @returns {Promise<number>} number of visible elements
924
- * {--end--}
925
954
  */
926
955
  async grabNumberOfVisibleElements(locator) {
927
956
  const count = (await findElements.call(this, this.context, locator)).filterVisible().count;
@@ -938,9 +967,9 @@ class TestCafe extends Helper {
938
967
  * I.seeInField('form input[type=hidden]','hidden_value');
939
968
  * I.seeInField('#searchform input','Search');
940
969
  * ```
941
- * @param {string|object} field located by label|name|CSS|XPath|strict locator.
970
+ * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator.
942
971
  * @param {string} value value to check.
943
- * {--end--}
972
+ *
944
973
  */
945
974
  async seeInField(field, value) {
946
975
  // const expectedValue = findElements.call(this, this.context, field).value;
@@ -962,9 +991,8 @@ class TestCafe extends Helper {
962
991
  * I.dontSeeInField({ css: 'form input.email' }, 'user@user.com'); // field by CSS
963
992
  * ```
964
993
  *
965
- * @param {string|object} field located by label|name|CSS|XPath|strict locator.
994
+ * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator.
966
995
  * @param {string} value value to check.
967
- * {--end--}
968
996
  */
969
997
  async dontSeeInField(field, value) {
970
998
  // const expectedValue = findElements.call(this, this.context, field).value;
@@ -998,7 +1026,6 @@ class TestCafe extends Helper {
998
1026
  * I.seeInSource('<h1>Green eggs &amp; ham</h1>');
999
1027
  * ```
1000
1028
  * @param {string} text value to check.
1001
- * {--end--}
1002
1029
  */
1003
1030
  async seeInSource(text) {
1004
1031
  const source = await getHtmlSource(this.t)();
@@ -1013,7 +1040,7 @@ class TestCafe extends Helper {
1013
1040
  * ```
1014
1041
  *
1015
1042
  * @param {string} value to check.
1016
- * {--end--}
1043
+ *
1017
1044
  */
1018
1045
  async dontSeeInSource(text) {
1019
1046
  const source = await getHtmlSource(this.t)();
@@ -1032,8 +1059,7 @@ class TestCafe extends Helper {
1032
1059
  * ```
1033
1060
  *
1034
1061
  * @param {string} fileName file name to save.
1035
- * @param {boolean} fullPage (optional, `false` by default) flag to enable fullscreen screenshot mode.
1036
- * {--end--}
1062
+ * @param {boolean} [fullPage=false] (optional, `false` by default) flag to enable fullscreen screenshot mode.
1037
1063
  */
1038
1064
  async saveScreenshot(fileName, fullPage) {
1039
1065
  // TODO Implement full page screenshots
@@ -1054,7 +1080,6 @@ class TestCafe extends Helper {
1054
1080
  * ```
1055
1081
  *
1056
1082
  * @param {number} sec number of second to wait.
1057
- * {--end--}
1058
1083
  */
1059
1084
  async wait(sec) {
1060
1085
  return new Promise(((done) => {
@@ -1088,8 +1113,9 @@ class TestCafe extends Helper {
1088
1113
  * ```
1089
1114
  *
1090
1115
  * @param {string|function} fn function to be executed in browser context.
1091
- * @param ...args args to be passed to function.
1092
- * {--end--}
1116
+ * @param {...any} args to be passed to function.
1117
+ * @return {Promise<any>}
1118
+ *
1093
1119
  *
1094
1120
  * If a function returns a Promise It will wait for it resolution.
1095
1121
  */
@@ -1107,9 +1133,8 @@ class TestCafe extends Helper {
1107
1133
  * ```
1108
1134
  * If multiple elements found returns an array of texts.
1109
1135
  *
1110
- * @param locator element located by CSS|XPath|strict locator.
1111
- * @returns {Promise<string>} attribute value
1112
- * {--end--}
1136
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
1137
+ * @returns {Promise<string|string[]>} attribute value
1113
1138
  */
1114
1139
  async grabTextFrom(locator) {
1115
1140
  const sel = await findElements.call(this, this.context, locator);
@@ -1134,15 +1159,14 @@ class TestCafe extends Helper {
1134
1159
  * ```js
1135
1160
  * let hint = await I.grabAttributeFrom('#tooltip', 'title');
1136
1161
  * ```
1137
- * @param {string|object} locator element located by CSS|XPath|strict locator.
1162
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
1138
1163
  * @param {string} attr attribute name.
1139
1164
  * @returns {Promise<string>} attribute value
1140
- * {--end--}
1141
1165
  */
1142
1166
  async grabAttributeFrom(locator, attr) {
1143
1167
  const sel = await findElements.call(this, this.context, locator);
1144
1168
  assertElementExists(sel);
1145
- return (await sel.nth(0)).value;
1169
+ return (await sel.nth(0)).getAttribute(attr);
1146
1170
  }
1147
1171
 
1148
1172
  /**
@@ -1152,12 +1176,13 @@ class TestCafe extends Helper {
1152
1176
  * ```js
1153
1177
  * let email = await I.grabValueFrom('input[name=email]');
1154
1178
  * ```
1155
- * @param {string|object} locator field located by label|name|CSS|XPath|strict locator.
1179
+ * @param {CodeceptJS.LocatorOrString} locator field located by label|name|CSS|XPath|strict locator.
1156
1180
  * @returns {Promise<string>} attribute value
1157
- * {--end--}
1158
1181
  */
1159
1182
  async grabValueFrom(locator) {
1160
- return this.grabAttributeFrom(locator, 'value');
1183
+ const sel = await findElements.call(this, this.context, locator);
1184
+ assertElementExists(sel);
1185
+ return (await sel.nth(0)).value;
1161
1186
  }
1162
1187
 
1163
1188
  /**
@@ -1169,7 +1194,6 @@ class TestCafe extends Helper {
1169
1194
  * ```
1170
1195
  *
1171
1196
  * @returns {Promise<string>} source code
1172
- * {--end--}
1173
1197
  */
1174
1198
  async grabSource() {
1175
1199
  return ClientFunction(() => document.documentElement.innerHTML).with({ boundTestRun: this.t })();
@@ -1198,7 +1222,6 @@ class TestCafe extends Helper {
1198
1222
  * ```
1199
1223
  *
1200
1224
  * @returns {Promise<string>} current URL
1201
- * {--end--}
1202
1225
  */
1203
1226
  async grabCurrentUrl() {
1204
1227
  return ClientFunction(() => document.location.href).with({ boundTestRun: this.t })();
@@ -1212,8 +1235,7 @@ class TestCafe extends Helper {
1212
1235
  * let { x, y } = await I.grabPageScrollPosition();
1213
1236
  * ```
1214
1237
  *
1215
- * @returns {Promise<object>} scroll position
1216
- * {--end--}
1238
+ * @returns {Promise<Object<string, *>>} scroll position
1217
1239
  */
1218
1240
  async grabPageScrollPosition() {
1219
1241
  return ClientFunction(() => ({ x: window.pageXOffset, y: window.pageYOffset })).with({ boundTestRun: this.t })();
@@ -1225,7 +1247,7 @@ class TestCafe extends Helper {
1225
1247
  * ```js
1226
1248
  * I.scrollPageToTop();
1227
1249
  * ```
1228
- * {--end--}
1250
+ *
1229
1251
  */
1230
1252
  scrollPageToTop() {
1231
1253
  return ClientFunction(() => window.scrollTo(0, 0)).with({ boundTestRun: this.t })().catch(mapError);
@@ -1237,7 +1259,7 @@ class TestCafe extends Helper {
1237
1259
  * ```js
1238
1260
  * I.scrollPageToBottom();
1239
1261
  * ```
1240
- * {--end--}
1262
+ *
1241
1263
  */
1242
1264
  scrollPageToBottom() {
1243
1265
  return ClientFunction(() => {
@@ -1259,10 +1281,9 @@ class TestCafe extends Helper {
1259
1281
  * I.scrollTo('#submit', 5, 5);
1260
1282
  * ```
1261
1283
  *
1262
- * @param {string|object} locator located by CSS|XPath|strict locator.
1263
- * @param {number} offsetX (optional, `0` by default) X-axis offset.
1264
- * @param {number} offsetY (optional, `0` by default) Y-axis offset.
1265
- * {--end--}
1284
+ * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|strict locator.
1285
+ * @param {number} [offsetX=0] (optional, `0` by default) X-axis offset.
1286
+ * @param {number} [offsetY=0] (optional, `0` by default) Y-axis offset.
1266
1287
  */
1267
1288
  async scrollTo(locator, offsetX = 0, offsetY = 0) {
1268
1289
  if (typeof locator === 'number' && typeof offsetX === 'number') {
@@ -1300,8 +1321,7 @@ class TestCafe extends Helper {
1300
1321
  * I.switchTo(); // switch back to main page
1301
1322
  * ```
1302
1323
  *
1303
- * @param {string|object} locator (optional, `null` by default) element located by CSS|XPath|strict locator.
1304
- * {--end--}
1324
+ * @param {?CodeceptJS.LocatorOrString} [locator=null] (optional, `null` by default) element located by CSS|XPath|strict locator.
1305
1325
  */
1306
1326
  async switchTo(locator) {
1307
1327
  if (Number.isInteger(locator)) {
@@ -1326,7 +1346,6 @@ class TestCafe extends Helper {
1326
1346
  * ```
1327
1347
  *
1328
1348
  * @param {object} cookie a cookie object.
1329
- * {--end--}
1330
1349
  */
1331
1350
  async setCookie(cookie) {
1332
1351
  if (Array.isArray(cookie)) {
@@ -1351,7 +1370,7 @@ class TestCafe extends Helper {
1351
1370
  * ```
1352
1371
  *
1353
1372
  * @param {string} name cookie name.
1354
- * {--end--}
1373
+ *
1355
1374
  *
1356
1375
  */
1357
1376
  async seeCookie(name) {
@@ -1367,7 +1386,6 @@ class TestCafe extends Helper {
1367
1386
  * ```
1368
1387
  *
1369
1388
  * @param {string} name cookie name.
1370
- * {--end--}
1371
1389
  */
1372
1390
  async dontSeeCookie(name) {
1373
1391
  const cookie = await this.grabCookie(name);
@@ -1377,16 +1395,15 @@ class TestCafe extends Helper {
1377
1395
  /**
1378
1396
  * Gets a cookie object by name.
1379
1397
  * If none provided gets all cookies.
1380
- * * Resumes test execution, so **should be used inside async with `await`** operator.
1398
+ * Resumes test execution, so **should be used inside async with `await`** operator.
1381
1399
  *
1382
1400
  * ```js
1383
1401
  * let cookie = await I.grabCookie('auth');
1384
1402
  * assert(cookie.value, '123456');
1385
1403
  * ```
1386
1404
  *
1387
- * @param [name=null] cookie name.
1405
+ * @param {?string} [name=null] cookie name.
1388
1406
  * @returns {Promise<string>} attribute value
1389
- * {--end--}
1390
1407
  *
1391
1408
  * Returns cookie in JSON format. If name not passed returns all cookies for this domain.
1392
1409
  */
@@ -1416,8 +1433,7 @@ class TestCafe extends Helper {
1416
1433
  * I.clearCookie('test');
1417
1434
  * ```
1418
1435
  *
1419
- * @param {string} cookie (optional, `null` by default) cookie name
1420
- * {--end--}
1436
+ * @param {?string} [cookie=null] (optional, `null` by default) cookie name
1421
1437
  */
1422
1438
  async clearCookie(cookieName) {
1423
1439
  const clearCookies = ClientFunction(() => {
@@ -1444,8 +1460,7 @@ class TestCafe extends Helper {
1444
1460
  * ```
1445
1461
  *
1446
1462
  * @param {string} urlPart value to check.
1447
- * @param {number} sec (optional, `1` by default) time in seconds to wait
1448
- * {--end--}
1463
+ * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
1449
1464
  */
1450
1465
  async waitInUrl(urlPart, sec = null) {
1451
1466
  const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
@@ -1470,8 +1485,7 @@ class TestCafe extends Helper {
1470
1485
  * ```
1471
1486
  *
1472
1487
  * @param {string} urlPart value to check.
1473
- * @param {number} sec (optional, `1` by default) time in seconds to wait
1474
- * {--end--}
1488
+ * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
1475
1489
  */
1476
1490
  async waitUrlEquals(urlPart, sec = null) {
1477
1491
  const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
@@ -1507,9 +1521,9 @@ class TestCafe extends Helper {
1507
1521
  * ```
1508
1522
  *
1509
1523
  * @param {string|function} fn to be executed in browser context.
1510
- * @param {array|number} argsOrSec (optional, `1` by default) arguments for function or seconds.
1511
- * @param {number} sec (optional, `1` by default) time in seconds to wait
1512
- * {--end--}
1524
+ * @param {any[]|number} [argsOrSec] (optional, `1` by default) arguments for function or seconds.
1525
+ * @param {number} [sec] (optional, `1` by default) time in seconds to wait
1526
+ *
1513
1527
  */
1514
1528
  async waitForFunction(fn, argsOrSec = null, sec = null) {
1515
1529
  let args = [];
@@ -1522,10 +1536,7 @@ class TestCafe extends Helper {
1522
1536
  }
1523
1537
  const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
1524
1538
 
1525
- const clientFn = createClientFunction((urlPart) => {
1526
- const currUrl = decodeURIComponent(decodeURIComponent(decodeURIComponent(window.location.href)));
1527
- return currUrl.indexOf(urlPart) > -1;
1528
- }, args);
1539
+ const clientFn = createClientFunction(fn, args).with({ boundTestRun: this.t });
1529
1540
 
1530
1541
  return waitForFunction(clientFn, waitTimeout);
1531
1542
  }
@@ -1537,10 +1548,9 @@ class TestCafe extends Helper {
1537
1548
  * I.waitNumberOfVisibleElements('a', 3);
1538
1549
  * ```
1539
1550
  *
1540
- * @param {string|object} locator element located by CSS|XPath|strict locator.
1551
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
1541
1552
  * @param {number} num number of elements.
1542
- * @param {number} sec (optional, `1` by default) time in seconds to wait
1543
- * {--end--}
1553
+ * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
1544
1554
  */
1545
1555
  async waitNumberOfVisibleElements(locator, num, sec) {
1546
1556
  const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
@@ -1560,9 +1570,8 @@ class TestCafe extends Helper {
1560
1570
  * I.waitForElement('.btn.continue', 5); // wait for 5 secs
1561
1571
  * ```
1562
1572
  *
1563
- * @param {string|object} locator element located by CSS|XPath|strict locator.
1564
- * @param {number} sec (optional, `1` by default) time in seconds to wait
1565
- * {--end--}
1573
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
1574
+ * @param {number} [sec] (optional, `1` by default) time in seconds to wait
1566
1575
  */
1567
1576
  async waitForElement(locator, sec) {
1568
1577
  const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
@@ -1580,9 +1589,8 @@ class TestCafe extends Helper {
1580
1589
  * I.waitToHide('#popup');
1581
1590
  * ```
1582
1591
  *
1583
- * @param {string|object} locator element located by CSS|XPath|strict locator.
1584
- * @param {number} sec (optional, `1` by default) time in seconds to wait
1585
- * {--end--}
1592
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
1593
+ * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
1586
1594
  */
1587
1595
  async waitToHide(locator, sec) {
1588
1596
  const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
@@ -1600,9 +1608,8 @@ class TestCafe extends Helper {
1600
1608
  * I.waitForInvisible('#popup');
1601
1609
  * ```
1602
1610
  *
1603
- * @param {string|object} locator element located by CSS|XPath|strict locator.
1604
- * @param {number} sec (optional, `1` by default) time in seconds to wait
1605
- * {--end--}
1611
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
1612
+ * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
1606
1613
  */
1607
1614
  async waitForInvisible(locator, sec) {
1608
1615
  const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
@@ -1623,9 +1630,8 @@ class TestCafe extends Helper {
1623
1630
  * ```
1624
1631
  *
1625
1632
  * @param {string }text to wait for.
1626
- * @param {number} sec (optional, `1` by default) time in seconds to wait
1627
- * @param {string|object} context (optional) element located by CSS|XPath|strict locator.
1628
- * {--end--}
1633
+ * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
1634
+ * @param {CodeceptJS.LocatorOrString} [context] (optional) element located by CSS|XPath|strict locator.
1629
1635
  *
1630
1636
  */
1631
1637
  async waitForText(text, sec = null, context = null) {
@@ -1657,7 +1663,7 @@ async function waitForFunction(browserFn, waitTimeout) {
1657
1663
  let result;
1658
1664
  try {
1659
1665
  result = await browserFn();
1660
- // eslint-disable-next-line no-empty
1666
+ // eslint-disable-next-line no-empty
1661
1667
  } catch (err) {
1662
1668
  throw new Error(`Error running function ${err.toString()}`);
1663
1669
  }