codeceptjs 4.0.0-beta.4 → 4.0.0-beta.5

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 (150) hide show
  1. package/README.md +134 -119
  2. package/bin/codecept.js +12 -2
  3. package/bin/test-server.js +53 -0
  4. package/docs/webapi/clearCookie.mustache +1 -1
  5. package/lib/actor.js +66 -102
  6. package/lib/ai.js +130 -121
  7. package/lib/assert/empty.js +3 -5
  8. package/lib/assert/equal.js +4 -7
  9. package/lib/assert/include.js +4 -6
  10. package/lib/assert/throws.js +2 -4
  11. package/lib/assert/truth.js +2 -2
  12. package/lib/codecept.js +139 -87
  13. package/lib/command/check.js +201 -0
  14. package/lib/command/configMigrate.js +2 -4
  15. package/lib/command/definitions.js +8 -26
  16. package/lib/command/generate.js +10 -14
  17. package/lib/command/gherkin/snippets.js +75 -73
  18. package/lib/command/gherkin/steps.js +1 -1
  19. package/lib/command/info.js +42 -8
  20. package/lib/command/init.js +13 -12
  21. package/lib/command/interactive.js +10 -2
  22. package/lib/command/list.js +1 -1
  23. package/lib/command/run-multiple/chunk.js +48 -45
  24. package/lib/command/run-multiple.js +12 -35
  25. package/lib/command/run-workers.js +21 -58
  26. package/lib/command/utils.js +5 -6
  27. package/lib/command/workers/runTests.js +262 -220
  28. package/lib/container.js +386 -238
  29. package/lib/data/context.js +10 -13
  30. package/lib/data/dataScenarioConfig.js +8 -8
  31. package/lib/data/dataTableArgument.js +6 -6
  32. package/lib/data/table.js +5 -11
  33. package/lib/effects.js +223 -0
  34. package/lib/element/WebElement.js +327 -0
  35. package/lib/els.js +158 -0
  36. package/lib/event.js +21 -17
  37. package/lib/heal.js +88 -80
  38. package/lib/helper/AI.js +2 -1
  39. package/lib/helper/ApiDataFactory.js +3 -6
  40. package/lib/helper/Appium.js +47 -51
  41. package/lib/helper/FileSystem.js +3 -3
  42. package/lib/helper/GraphQLDataFactory.js +3 -3
  43. package/lib/helper/JSONResponse.js +75 -37
  44. package/lib/helper/Mochawesome.js +31 -9
  45. package/lib/helper/Nightmare.js +35 -53
  46. package/lib/helper/Playwright.js +262 -267
  47. package/lib/helper/Protractor.js +54 -77
  48. package/lib/helper/Puppeteer.js +246 -260
  49. package/lib/helper/REST.js +5 -17
  50. package/lib/helper/TestCafe.js +21 -44
  51. package/lib/helper/WebDriver.js +151 -170
  52. package/lib/helper/extras/Popup.js +22 -22
  53. package/lib/helper/testcafe/testcafe-utils.js +26 -27
  54. package/lib/listener/emptyRun.js +55 -0
  55. package/lib/listener/exit.js +7 -10
  56. package/lib/listener/{retry.js → globalRetry.js} +5 -5
  57. package/lib/listener/globalTimeout.js +165 -0
  58. package/lib/listener/helpers.js +15 -15
  59. package/lib/listener/mocha.js +1 -1
  60. package/lib/listener/result.js +12 -0
  61. package/lib/listener/retryEnhancer.js +85 -0
  62. package/lib/listener/steps.js +32 -18
  63. package/lib/listener/store.js +20 -0
  64. package/lib/mocha/asyncWrapper.js +231 -0
  65. package/lib/{interfaces → mocha}/bdd.js +3 -3
  66. package/lib/mocha/cli.js +308 -0
  67. package/lib/mocha/factory.js +104 -0
  68. package/lib/{interfaces → mocha}/featureConfig.js +32 -12
  69. package/lib/{interfaces → mocha}/gherkin.js +26 -28
  70. package/lib/mocha/hooks.js +112 -0
  71. package/lib/mocha/index.js +12 -0
  72. package/lib/mocha/inject.js +29 -0
  73. package/lib/{interfaces → mocha}/scenarioConfig.js +31 -7
  74. package/lib/mocha/suite.js +82 -0
  75. package/lib/mocha/test.js +181 -0
  76. package/lib/mocha/types.d.ts +42 -0
  77. package/lib/mocha/ui.js +232 -0
  78. package/lib/output.js +82 -62
  79. package/lib/pause.js +160 -138
  80. package/lib/plugin/analyze.js +396 -0
  81. package/lib/plugin/auth.js +435 -0
  82. package/lib/plugin/autoDelay.js +8 -8
  83. package/lib/plugin/autoLogin.js +3 -338
  84. package/lib/plugin/commentStep.js +6 -1
  85. package/lib/plugin/coverage.js +10 -19
  86. package/lib/plugin/customLocator.js +3 -3
  87. package/lib/plugin/customReporter.js +52 -0
  88. package/lib/plugin/eachElement.js +1 -1
  89. package/lib/plugin/fakerTransform.js +1 -1
  90. package/lib/plugin/heal.js +36 -9
  91. package/lib/plugin/htmlReporter.js +1947 -0
  92. package/lib/plugin/pageInfo.js +140 -0
  93. package/lib/plugin/retryFailedStep.js +17 -18
  94. package/lib/plugin/retryTo.js +2 -113
  95. package/lib/plugin/screenshotOnFail.js +17 -58
  96. package/lib/plugin/selenoid.js +15 -35
  97. package/lib/plugin/standardActingHelpers.js +4 -1
  98. package/lib/plugin/stepByStepReport.js +56 -17
  99. package/lib/plugin/stepTimeout.js +5 -12
  100. package/lib/plugin/subtitles.js +4 -4
  101. package/lib/plugin/tryTo.js +3 -102
  102. package/lib/plugin/wdio.js +8 -10
  103. package/lib/recorder.js +155 -124
  104. package/lib/rerun.js +43 -42
  105. package/lib/result.js +161 -0
  106. package/lib/secret.js +1 -1
  107. package/lib/step/base.js +239 -0
  108. package/lib/step/comment.js +10 -0
  109. package/lib/step/config.js +50 -0
  110. package/lib/step/func.js +46 -0
  111. package/lib/step/helper.js +50 -0
  112. package/lib/step/meta.js +99 -0
  113. package/lib/step/record.js +74 -0
  114. package/lib/step/retry.js +11 -0
  115. package/lib/step/section.js +55 -0
  116. package/lib/step.js +21 -332
  117. package/lib/steps.js +50 -0
  118. package/lib/store.js +37 -5
  119. package/lib/template/heal.js +2 -11
  120. package/lib/test-server.js +323 -0
  121. package/lib/timeout.js +66 -0
  122. package/lib/utils.js +351 -218
  123. package/lib/within.js +75 -55
  124. package/lib/workerStorage.js +2 -1
  125. package/lib/workers.js +386 -276
  126. package/package.json +76 -70
  127. package/translations/de-DE.js +4 -3
  128. package/translations/fr-FR.js +4 -3
  129. package/translations/index.js +1 -0
  130. package/translations/it-IT.js +4 -3
  131. package/translations/ja-JP.js +4 -3
  132. package/translations/nl-NL.js +76 -0
  133. package/translations/pl-PL.js +4 -3
  134. package/translations/pt-BR.js +4 -3
  135. package/translations/ru-RU.js +4 -3
  136. package/translations/utils.js +9 -0
  137. package/translations/zh-CN.js +4 -3
  138. package/translations/zh-TW.js +4 -3
  139. package/typings/index.d.ts +188 -186
  140. package/typings/promiseBasedTypes.d.ts +18 -705
  141. package/typings/types.d.ts +301 -804
  142. package/lib/cli.js +0 -256
  143. package/lib/helper/ExpectHelper.js +0 -391
  144. package/lib/helper/SoftExpectHelper.js +0 -381
  145. package/lib/listener/artifacts.js +0 -19
  146. package/lib/listener/timeout.js +0 -109
  147. package/lib/mochaFactory.js +0 -113
  148. package/lib/plugin/debugErrors.js +0 -67
  149. package/lib/scenario.js +0 -224
  150. package/lib/ui.js +0 -236
@@ -205,10 +205,7 @@ class REST extends Helper {
205
205
 
206
206
  if (request.data instanceof Secret) {
207
207
  _debugRequest.data = '*****'
208
- request.data =
209
- typeof request.data === 'object' && !(request.data instanceof Secret)
210
- ? { ...request.data.toString() }
211
- : request.data.toString()
208
+ request.data = typeof request.data === 'object' && !(request.data instanceof Secret) ? { ...request.data.toString() } : request.data.toString()
212
209
  }
213
210
 
214
211
  if (typeof request.data === 'string') {
@@ -221,9 +218,7 @@ class REST extends Helper {
221
218
  await this.config.onRequest(request)
222
219
  }
223
220
 
224
- this.options.prettyPrintJson
225
- ? this.debugSection('Request', beautify(JSON.stringify(_debugRequest)))
226
- : this.debugSection('Request', JSON.stringify(_debugRequest))
221
+ this.options.prettyPrintJson ? this.debugSection('Request', beautify(JSON.stringify(_debugRequest))) : this.debugSection('Request', JSON.stringify(_debugRequest))
227
222
 
228
223
  if (this.options.printCurl) {
229
224
  this.debugSection('CURL Request', curlize(request))
@@ -240,9 +235,7 @@ class REST extends Helper {
240
235
  if (this.config.onResponse) {
241
236
  await this.config.onResponse(response)
242
237
  }
243
- this.options.prettyPrintJson
244
- ? this.debugSection('Response', beautify(JSON.stringify(response.data)))
245
- : this.debugSection('Response', JSON.stringify(response.data))
238
+ this.options.prettyPrintJson ? this.debugSection('Response', beautify(JSON.stringify(response.data))) : this.debugSection('Response', JSON.stringify(response.data))
246
239
  return response
247
240
  }
248
241
 
@@ -437,13 +430,8 @@ class REST extends Helper {
437
430
  module.exports = REST
438
431
 
439
432
  function curlize(request) {
440
- if (request.data?.constructor.name.toLowerCase() === 'formdata')
441
- return 'cURL is not printed as the request body is not a JSON'
442
- let curl =
443
- `curl --location --request ${request.method ? request.method.toUpperCase() : 'GET'} ${request.baseURL} `.replace(
444
- "'",
445
- '',
446
- )
433
+ if (request.data?.constructor.name.toLowerCase() === 'formdata') return 'cURL is not printed as the request body is not a JSON'
434
+ let curl = `curl --location --request ${request.method ? request.method.toUpperCase() : 'GET'} ${request.baseURL} `.replace("'", '')
447
435
 
448
436
  if (request.headers) {
449
437
  Object.entries(request.headers).forEach(([key, value]) => {
@@ -21,9 +21,8 @@ const Locator = require('../locator')
21
21
  /**
22
22
  * Client Functions
23
23
  */
24
- const getPageUrl = (t) => ClientFunction(() => document.location.href).with({ boundTestRun: t })
25
- const getHtmlSource = (t) =>
26
- ClientFunction(() => document.getElementsByTagName('html')[0].innerHTML).with({ boundTestRun: t })
24
+ const getPageUrl = t => ClientFunction(() => document.location.href).with({ boundTestRun: t })
25
+ const getHtmlSource = t => ClientFunction(() => document.getElementsByTagName('html')[0].innerHTML).with({ boundTestRun: t })
27
26
 
28
27
  /**
29
28
  * Uses [TestCafe](https://github.com/DevExpress/testcafe) library to run cross-browser tests.
@@ -187,7 +186,7 @@ class TestCafe extends Helper {
187
186
  assertionTimeout: this.options.waitForTimeout,
188
187
  takeScreenshotsOnFails: true,
189
188
  })
190
- .catch((err) => {
189
+ .catch(err => {
191
190
  this.debugSection('_before', `Error ${err.toString()}`)
192
191
  this.isRunning = false
193
192
  this.testcafe.close()
@@ -208,7 +207,7 @@ class TestCafe extends Helper {
208
207
  skipJsErrors: true,
209
208
  skipUncaughtErrors: true,
210
209
  })
211
- .catch((err) => {
210
+ .catch(err => {
212
211
  this.debugSection('_before', `Error ${err.toString()}`)
213
212
  this.isRunning = false
214
213
  this.testcafe.close()
@@ -260,7 +259,7 @@ class TestCafe extends Helper {
260
259
  await this.clearCookie()
261
260
 
262
261
  // TODO IMHO that should only happen when
263
- await this.executeScript(() => localStorage.clear()).catch((err) => {
262
+ await this.executeScript(() => localStorage.clear()).catch(err => {
264
263
  if (!(err.message.indexOf("Storage is disabled inside 'data:' URLs.") > -1)) throw err
265
264
  })
266
265
  }
@@ -383,7 +382,6 @@ class TestCafe extends Helper {
383
382
  * {{> refreshPage }}
384
383
  */
385
384
  async refreshPage() {
386
- // eslint-disable-next-line no-restricted-globals
387
385
  return this.t.eval(() => location.reload(true), { boundTestRun: this.t }).catch(mapError)
388
386
  }
389
387
 
@@ -394,9 +392,7 @@ class TestCafe extends Helper {
394
392
  async waitForVisible(locator, sec) {
395
393
  const timeout = sec ? sec * 1000 : undefined
396
394
 
397
- return (await findElements.call(this, this.context, locator))
398
- .with({ visibilityCheck: true, timeout })()
399
- .catch(mapError)
395
+ return (await findElements.call(this, this.context, locator)).with({ visibilityCheck: true, timeout })().catch(mapError)
400
396
  }
401
397
 
402
398
  /**
@@ -565,7 +561,6 @@ class TestCafe extends Helper {
565
561
  await this.t.click(optEl).catch(mapError)
566
562
  continue
567
563
  }
568
- // eslint-disable-next-line no-empty
569
564
  } catch (err) {}
570
565
 
571
566
  try {
@@ -574,7 +569,6 @@ class TestCafe extends Helper {
574
569
  if (await optEl.count) {
575
570
  await this.t.click(optEl).catch(mapError)
576
571
  }
577
- // eslint-disable-next-line no-empty
578
572
  } catch (err) {}
579
573
  }
580
574
  }
@@ -634,10 +628,7 @@ class TestCafe extends Helper {
634
628
  els = (await findElements.call(this, this.context, 'body')).withText(text)
635
629
  }
636
630
 
637
- return this.t
638
- .expect(els.filterVisible().count)
639
- .eql(0, `Element with text "${text}" can still be seen`)
640
- .catch(mapError)
631
+ return this.t.expect(els.filterVisible().count).eql(0, `Element with text "${text}" can still be seen`).catch(mapError)
641
632
  }
642
633
 
643
634
  /**
@@ -789,7 +780,7 @@ class TestCafe extends Helper {
789
780
  * {{> wait }}
790
781
  */
791
782
  async wait(sec) {
792
- return new Promise((done) => {
783
+ return new Promise(done => {
793
784
  setTimeout(done, sec * 1000)
794
785
  })
795
786
  }
@@ -938,10 +929,7 @@ class TestCafe extends Helper {
938
929
  return ClientFunction(() => {
939
930
  const body = document.body
940
931
  const html = document.documentElement
941
- window.scrollTo(
942
- 0,
943
- Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight),
944
- )
932
+ window.scrollTo(0, Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight))
945
933
  })
946
934
  .with({ boundTestRun: this.t })()
947
935
  .catch(mapError)
@@ -957,7 +945,7 @@ class TestCafe extends Helper {
957
945
  locator = null
958
946
  }
959
947
 
960
- const scrollBy = ClientFunction((offset) => {
948
+ const scrollBy = ClientFunction(offset => {
961
949
  if (window && window.scrollBy && offset) {
962
950
  window.scrollBy(offset.x, offset.y)
963
951
  }
@@ -1042,10 +1030,10 @@ class TestCafe extends Helper {
1042
1030
  async grabCookie(name) {
1043
1031
  if (!name) {
1044
1032
  const getCookie = ClientFunction(() => {
1045
- return document.cookie.split(';').map((c) => c.split('='))
1033
+ return document.cookie.split(';').map(c => c.split('='))
1046
1034
  }).with({ boundTestRun: this.t })
1047
1035
  const cookies = await getCookie()
1048
- return cookies.map((cookie) => ({ name: cookie[0].trim(), value: cookie[1] }))
1036
+ return cookies.map(cookie => ({ name: cookie[0].trim(), value: cookie[1] }))
1049
1037
  }
1050
1038
  const getCookie = ClientFunction(
1051
1039
  () => {
@@ -1088,7 +1076,7 @@ class TestCafe extends Helper {
1088
1076
  const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout
1089
1077
 
1090
1078
  const clientFn = createClientFunction(
1091
- (urlPart) => {
1079
+ urlPart => {
1092
1080
  const currUrl = decodeURIComponent(decodeURIComponent(decodeURIComponent(window.location.href)))
1093
1081
  return currUrl.indexOf(urlPart) > -1
1094
1082
  },
@@ -1113,7 +1101,7 @@ class TestCafe extends Helper {
1113
1101
  }
1114
1102
 
1115
1103
  const clientFn = createClientFunction(
1116
- (urlPart) => {
1104
+ urlPart => {
1117
1105
  const currUrl = decodeURIComponent(decodeURIComponent(decodeURIComponent(window.location.href)))
1118
1106
  return currUrl === urlPart
1119
1107
  },
@@ -1174,9 +1162,7 @@ class TestCafe extends Helper {
1174
1162
  async waitToHide(locator, sec) {
1175
1163
  const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout
1176
1164
 
1177
- return this.t
1178
- .expect(createSelector(locator).filterHidden().with({ boundTestRun: this.t }).exists)
1179
- .notOk({ timeout: waitTimeout })
1165
+ return this.t.expect(createSelector(locator).filterHidden().with({ boundTestRun: this.t }).exists).notOk({ timeout: waitTimeout })
1180
1166
  }
1181
1167
 
1182
1168
  /**
@@ -1185,9 +1171,7 @@ class TestCafe extends Helper {
1185
1171
  async waitForInvisible(locator, sec) {
1186
1172
  const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout
1187
1173
 
1188
- return this.t
1189
- .expect(createSelector(locator).filterVisible().with({ boundTestRun: this.t }).exists)
1190
- .ok({ timeout: waitTimeout })
1174
+ return this.t.expect(createSelector(locator).filterVisible().with({ boundTestRun: this.t }).exists).ok({ timeout: waitTimeout })
1191
1175
  }
1192
1176
 
1193
1177
  /**
@@ -1214,7 +1198,7 @@ class TestCafe extends Helper {
1214
1198
 
1215
1199
  async function waitForFunction(browserFn, waitTimeout) {
1216
1200
  const pause = () =>
1217
- new Promise((done) => {
1201
+ new Promise(done => {
1218
1202
  setTimeout(done, 50)
1219
1203
  })
1220
1204
 
@@ -1238,13 +1222,13 @@ async function waitForFunction(browserFn, waitTimeout) {
1238
1222
  }
1239
1223
  }
1240
1224
 
1241
- const createSelector = (locator) => {
1225
+ const createSelector = locator => {
1242
1226
  locator = new Locator(locator, 'css')
1243
1227
  if (locator.isXPath()) return elementByXPath(locator.value)
1244
1228
  return Selector(locator.simplify())
1245
1229
  }
1246
1230
 
1247
- const elementByXPath = (xpath) => {
1231
+ const elementByXPath = xpath => {
1248
1232
  assert(xpath, 'xpath is required')
1249
1233
 
1250
1234
  return Selector(
@@ -1277,9 +1261,7 @@ async function findElements(matcher, locator) {
1277
1261
  locator = new Locator(locator, 'css')
1278
1262
 
1279
1263
  if (!locator.isXPath()) {
1280
- return matcher
1281
- ? matcher.find(locator.simplify())
1282
- : Selector(locator.simplify()).with({ timeout: 0, boundTestRun: this.t })
1264
+ return matcher ? matcher.find(locator.simplify()) : Selector(locator.simplify()).with({ timeout: 0, boundTestRun: this.t })
1283
1265
  }
1284
1266
 
1285
1267
  if (!matcher) return elementByXPath(locator.value).with({ timeout: 0, boundTestRun: this.t })
@@ -1308,12 +1290,7 @@ async function proceedClick(locator, context = null) {
1308
1290
 
1309
1291
  const els = await findClickable.call(this, matcher, locator)
1310
1292
  if (context) {
1311
- await assertElementExists(
1312
- els,
1313
- locator,
1314
- 'Clickable element',
1315
- `was not found inside element ${new Locator(context).toString()}`,
1316
- )
1293
+ await assertElementExists(els, locator, 'Clickable element', `was not found inside element ${new Locator(context).toString()}`)
1317
1294
  } else {
1318
1295
  await assertElementExists(els, locator, 'Clickable element')
1319
1296
  }