codeceptjs 4.0.0-beta.2 → 4.0.0-beta.21

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 (209) hide show
  1. package/README.md +133 -120
  2. package/bin/codecept.js +107 -96
  3. package/bin/test-server.js +64 -0
  4. package/docs/webapi/clearCookie.mustache +1 -1
  5. package/docs/webapi/click.mustache +5 -1
  6. package/lib/actor.js +73 -103
  7. package/lib/ai.js +159 -188
  8. package/lib/assert/empty.js +22 -24
  9. package/lib/assert/equal.js +30 -37
  10. package/lib/assert/error.js +14 -14
  11. package/lib/assert/include.js +43 -48
  12. package/lib/assert/throws.js +11 -11
  13. package/lib/assert/truth.js +22 -22
  14. package/lib/assert.js +20 -18
  15. package/lib/codecept.js +262 -162
  16. package/lib/colorUtils.js +50 -52
  17. package/lib/command/check.js +206 -0
  18. package/lib/command/configMigrate.js +56 -51
  19. package/lib/command/definitions.js +96 -109
  20. package/lib/command/dryRun.js +77 -79
  21. package/lib/command/generate.js +234 -194
  22. package/lib/command/gherkin/init.js +42 -33
  23. package/lib/command/gherkin/snippets.js +76 -74
  24. package/lib/command/gherkin/steps.js +20 -17
  25. package/lib/command/info.js +74 -38
  26. package/lib/command/init.js +301 -290
  27. package/lib/command/interactive.js +41 -32
  28. package/lib/command/list.js +28 -27
  29. package/lib/command/run-multiple/chunk.js +51 -48
  30. package/lib/command/run-multiple/collection.js +5 -5
  31. package/lib/command/run-multiple/run.js +5 -1
  32. package/lib/command/run-multiple.js +97 -97
  33. package/lib/command/run-rerun.js +19 -25
  34. package/lib/command/run-workers.js +68 -92
  35. package/lib/command/run.js +39 -27
  36. package/lib/command/utils.js +80 -64
  37. package/lib/command/workers/runTests.js +388 -226
  38. package/lib/config.js +109 -50
  39. package/lib/container.js +765 -261
  40. package/lib/data/context.js +60 -61
  41. package/lib/data/dataScenarioConfig.js +47 -47
  42. package/lib/data/dataTableArgument.js +32 -32
  43. package/lib/data/table.js +22 -22
  44. package/lib/effects.js +307 -0
  45. package/lib/element/WebElement.js +327 -0
  46. package/lib/els.js +160 -0
  47. package/lib/event.js +173 -163
  48. package/lib/globals.js +141 -0
  49. package/lib/heal.js +89 -85
  50. package/lib/helper/AI.js +131 -41
  51. package/lib/helper/ApiDataFactory.js +107 -75
  52. package/lib/helper/Appium.js +542 -404
  53. package/lib/helper/FileSystem.js +100 -79
  54. package/lib/helper/GraphQL.js +44 -43
  55. package/lib/helper/GraphQLDataFactory.js +52 -52
  56. package/lib/helper/JSONResponse.js +126 -88
  57. package/lib/helper/Mochawesome.js +54 -29
  58. package/lib/helper/Playwright.js +2547 -1316
  59. package/lib/helper/Puppeteer.js +1578 -1181
  60. package/lib/helper/REST.js +209 -68
  61. package/lib/helper/WebDriver.js +1482 -1342
  62. package/lib/helper/errors/ConnectionRefused.js +6 -6
  63. package/lib/helper/errors/ElementAssertion.js +11 -16
  64. package/lib/helper/errors/ElementNotFound.js +5 -9
  65. package/lib/helper/errors/RemoteBrowserConnectionRefused.js +5 -5
  66. package/lib/helper/extras/Console.js +11 -11
  67. package/lib/helper/extras/PlaywrightLocator.js +110 -0
  68. package/lib/helper/extras/PlaywrightPropEngine.js +18 -18
  69. package/lib/helper/extras/PlaywrightReactVueLocator.js +17 -8
  70. package/lib/helper/extras/PlaywrightRestartOpts.js +25 -11
  71. package/lib/helper/extras/Popup.js +22 -22
  72. package/lib/helper/extras/React.js +27 -28
  73. package/lib/helper/network/actions.js +36 -42
  74. package/lib/helper/network/utils.js +78 -84
  75. package/lib/helper/scripts/blurElement.js +5 -5
  76. package/lib/helper/scripts/focusElement.js +5 -5
  77. package/lib/helper/scripts/highlightElement.js +8 -8
  78. package/lib/helper/scripts/isElementClickable.js +34 -34
  79. package/lib/helper.js +2 -3
  80. package/lib/history.js +23 -19
  81. package/lib/hooks.js +8 -8
  82. package/lib/html.js +94 -104
  83. package/lib/index.js +38 -27
  84. package/lib/listener/config.js +30 -23
  85. package/lib/listener/emptyRun.js +54 -0
  86. package/lib/listener/enhancedGlobalRetry.js +110 -0
  87. package/lib/listener/exit.js +16 -18
  88. package/lib/listener/globalRetry.js +70 -0
  89. package/lib/listener/globalTimeout.js +181 -0
  90. package/lib/listener/helpers.js +76 -51
  91. package/lib/listener/mocha.js +10 -11
  92. package/lib/listener/result.js +11 -0
  93. package/lib/listener/retryEnhancer.js +85 -0
  94. package/lib/listener/steps.js +71 -59
  95. package/lib/listener/store.js +20 -0
  96. package/lib/locator.js +214 -197
  97. package/lib/mocha/asyncWrapper.js +274 -0
  98. package/lib/mocha/bdd.js +167 -0
  99. package/lib/mocha/cli.js +341 -0
  100. package/lib/mocha/factory.js +163 -0
  101. package/lib/mocha/featureConfig.js +89 -0
  102. package/lib/mocha/gherkin.js +231 -0
  103. package/lib/mocha/hooks.js +121 -0
  104. package/lib/mocha/index.js +21 -0
  105. package/lib/mocha/inject.js +46 -0
  106. package/lib/{interfaces → mocha}/scenarioConfig.js +58 -34
  107. package/lib/mocha/suite.js +89 -0
  108. package/lib/mocha/test.js +184 -0
  109. package/lib/mocha/types.d.ts +42 -0
  110. package/lib/mocha/ui.js +242 -0
  111. package/lib/output.js +141 -71
  112. package/lib/parser.js +54 -44
  113. package/lib/pause.js +173 -145
  114. package/lib/plugin/analyze.js +403 -0
  115. package/lib/plugin/{autoLogin.js → auth.js} +178 -79
  116. package/lib/plugin/autoDelay.js +36 -40
  117. package/lib/plugin/coverage.js +131 -78
  118. package/lib/plugin/customLocator.js +22 -21
  119. package/lib/plugin/customReporter.js +53 -0
  120. package/lib/plugin/enhancedRetryFailedStep.js +99 -0
  121. package/lib/plugin/heal.js +101 -110
  122. package/lib/plugin/htmlReporter.js +3648 -0
  123. package/lib/plugin/pageInfo.js +140 -0
  124. package/lib/plugin/pauseOnFail.js +12 -11
  125. package/lib/plugin/retryFailedStep.js +82 -47
  126. package/lib/plugin/screenshotOnFail.js +111 -92
  127. package/lib/plugin/stepByStepReport.js +159 -101
  128. package/lib/plugin/stepTimeout.js +20 -25
  129. package/lib/plugin/subtitles.js +38 -38
  130. package/lib/recorder.js +193 -130
  131. package/lib/rerun.js +94 -49
  132. package/lib/result.js +238 -0
  133. package/lib/retryCoordinator.js +207 -0
  134. package/lib/secret.js +20 -18
  135. package/lib/session.js +95 -89
  136. package/lib/step/base.js +239 -0
  137. package/lib/step/comment.js +10 -0
  138. package/lib/step/config.js +50 -0
  139. package/lib/step/func.js +46 -0
  140. package/lib/step/helper.js +50 -0
  141. package/lib/step/meta.js +99 -0
  142. package/lib/step/record.js +74 -0
  143. package/lib/step/retry.js +11 -0
  144. package/lib/step/section.js +55 -0
  145. package/lib/step.js +18 -329
  146. package/lib/steps.js +54 -0
  147. package/lib/store.js +38 -7
  148. package/lib/template/heal.js +3 -12
  149. package/lib/template/prompts/generatePageObject.js +31 -0
  150. package/lib/template/prompts/healStep.js +13 -0
  151. package/lib/template/prompts/writeStep.js +9 -0
  152. package/lib/test-server.js +334 -0
  153. package/lib/timeout.js +60 -0
  154. package/lib/transform.js +8 -8
  155. package/lib/translation.js +34 -21
  156. package/lib/utils/loaderCheck.js +124 -0
  157. package/lib/utils/mask_data.js +47 -0
  158. package/lib/utils/typescript.js +237 -0
  159. package/lib/utils.js +411 -228
  160. package/lib/workerStorage.js +37 -34
  161. package/lib/workers.js +532 -296
  162. package/package.json +124 -95
  163. package/translations/de-DE.js +5 -3
  164. package/translations/fr-FR.js +5 -4
  165. package/translations/index.js +22 -12
  166. package/translations/it-IT.js +4 -3
  167. package/translations/ja-JP.js +4 -3
  168. package/translations/nl-NL.js +76 -0
  169. package/translations/pl-PL.js +4 -3
  170. package/translations/pt-BR.js +4 -3
  171. package/translations/ru-RU.js +4 -3
  172. package/translations/utils.js +10 -0
  173. package/translations/zh-CN.js +4 -3
  174. package/translations/zh-TW.js +4 -3
  175. package/typings/index.d.ts +546 -185
  176. package/typings/promiseBasedTypes.d.ts +150 -875
  177. package/typings/types.d.ts +547 -992
  178. package/lib/cli.js +0 -249
  179. package/lib/dirname.js +0 -5
  180. package/lib/helper/Expect.js +0 -425
  181. package/lib/helper/ExpectHelper.js +0 -399
  182. package/lib/helper/MockServer.js +0 -223
  183. package/lib/helper/Nightmare.js +0 -1411
  184. package/lib/helper/Protractor.js +0 -1835
  185. package/lib/helper/SoftExpectHelper.js +0 -381
  186. package/lib/helper/TestCafe.js +0 -1410
  187. package/lib/helper/clientscripts/nightmare.js +0 -213
  188. package/lib/helper/testcafe/testControllerHolder.js +0 -42
  189. package/lib/helper/testcafe/testcafe-utils.js +0 -63
  190. package/lib/interfaces/bdd.js +0 -98
  191. package/lib/interfaces/featureConfig.js +0 -69
  192. package/lib/interfaces/gherkin.js +0 -195
  193. package/lib/listener/artifacts.js +0 -19
  194. package/lib/listener/retry.js +0 -68
  195. package/lib/listener/timeout.js +0 -109
  196. package/lib/mochaFactory.js +0 -110
  197. package/lib/plugin/allure.js +0 -15
  198. package/lib/plugin/commentStep.js +0 -136
  199. package/lib/plugin/debugErrors.js +0 -67
  200. package/lib/plugin/eachElement.js +0 -127
  201. package/lib/plugin/fakerTransform.js +0 -49
  202. package/lib/plugin/retryTo.js +0 -121
  203. package/lib/plugin/selenoid.js +0 -371
  204. package/lib/plugin/standardActingHelpers.js +0 -9
  205. package/lib/plugin/tryTo.js +0 -105
  206. package/lib/plugin/wdio.js +0 -246
  207. package/lib/scenario.js +0 -222
  208. package/lib/ui.js +0 -238
  209. package/lib/within.js +0 -70
@@ -0,0 +1,85 @@
1
+ import event from '../event.js'
2
+ import { enhanceMochaTest } from '../mocha/test.js'
3
+
4
+ /**
5
+ * Enhance retried tests by copying CodeceptJS-specific properties from the original test
6
+ * This fixes the issue where Mocha's shallow clone during retries loses CodeceptJS properties
7
+ */
8
+ export default function () {
9
+ event.dispatcher.on(event.test.before, test => {
10
+ // Check if this test is a retry (has a reference to the original test)
11
+ const originalTest = test.retriedTest && test.retriedTest()
12
+
13
+ if (originalTest) {
14
+ // This is a retried test - copy CodeceptJS-specific properties from the original
15
+ copyCodeceptJSProperties(originalTest, test)
16
+
17
+ // Ensure the test is enhanced with CodeceptJS functionality
18
+ enhanceMochaTest(test)
19
+ }
20
+ })
21
+ }
22
+
23
+ /**
24
+ * Copy CodeceptJS-specific properties from the original test to the retried test
25
+ * @param {CodeceptJS.Test} originalTest - The original test object
26
+ * @param {CodeceptJS.Test} retriedTest - The retried test object
27
+ */
28
+ function copyCodeceptJSProperties(originalTest, retriedTest) {
29
+ // Copy CodeceptJS-specific properties
30
+ if (originalTest.opts !== undefined) {
31
+ retriedTest.opts = originalTest.opts ? { ...originalTest.opts } : {}
32
+ }
33
+
34
+ if (originalTest.tags !== undefined) {
35
+ retriedTest.tags = originalTest.tags ? [...originalTest.tags] : []
36
+ }
37
+
38
+ if (originalTest.notes !== undefined) {
39
+ retriedTest.notes = originalTest.notes ? [...originalTest.notes] : []
40
+ }
41
+
42
+ if (originalTest.meta !== undefined) {
43
+ retriedTest.meta = originalTest.meta ? { ...originalTest.meta } : {}
44
+ }
45
+
46
+ if (originalTest.artifacts !== undefined) {
47
+ retriedTest.artifacts = originalTest.artifacts ? [...originalTest.artifacts] : []
48
+ }
49
+
50
+ if (originalTest.steps !== undefined) {
51
+ retriedTest.steps = originalTest.steps ? [...originalTest.steps] : []
52
+ }
53
+
54
+ if (originalTest.config !== undefined) {
55
+ retriedTest.config = originalTest.config ? { ...originalTest.config } : {}
56
+ }
57
+
58
+ if (originalTest.inject !== undefined) {
59
+ retriedTest.inject = originalTest.inject ? { ...originalTest.inject } : {}
60
+ }
61
+
62
+ // Copy methods that might be missing
63
+ if (originalTest.addNote && !retriedTest.addNote) {
64
+ retriedTest.addNote = function (type, note) {
65
+ this.notes = this.notes || []
66
+ this.notes.push({ type, text: note })
67
+ }
68
+ }
69
+
70
+ if (originalTest.applyOptions && !retriedTest.applyOptions) {
71
+ retriedTest.applyOptions = originalTest.applyOptions.bind(retriedTest)
72
+ }
73
+
74
+ if (originalTest.simplify && !retriedTest.simplify) {
75
+ retriedTest.simplify = originalTest.simplify.bind(retriedTest)
76
+ }
77
+
78
+ // Preserve the uid if it exists
79
+ if (originalTest.uid !== undefined) {
80
+ retriedTest.uid = originalTest.uid
81
+ }
82
+
83
+ // Mark as enhanced
84
+ retriedTest.codeceptjs = true
85
+ }
@@ -1,86 +1,98 @@
1
- import debug from 'debug';
2
- import * as event from '../event.js';
3
- import { store } from '../store.js';
4
- import * as output from '../output.js';
1
+ import debugModule from 'debug'
2
+ const debug = debugModule('codeceptjs:steps')
3
+ import event from '../event.js'
4
+ import store from '../store.js'
5
+ import output from '../output.js'
6
+ import { BeforeHook, AfterHook, BeforeSuiteHook, AfterSuiteHook } from '../mocha/hooks.js'
7
+ import recorder from '../recorder.js'
5
8
 
6
- debug('codeceptjs:steps');
9
+ let currentTest
10
+ let currentHook
7
11
 
8
- let currentTest;
9
- let currentHook;
12
+ // Session names that should not contribute steps to the main test trace
13
+ const EXCLUDED_SESSIONS = ['tryTo', 'hopeThat']
10
14
 
11
15
  /**
12
16
  * Register steps inside tests
13
17
  */
14
18
  export default function () {
15
- event.dispatcher.on(event.test.before, (test) => {
16
- test.startedAt = +new Date();
17
- test.artifacts = {};
18
- });
19
+ event.dispatcher.on(event.test.before, test => {
20
+ test.startedAt = +new Date()
21
+ })
19
22
 
20
- event.dispatcher.on(event.test.started, (test) => {
21
- currentTest = test;
22
- currentTest.steps = [];
23
- if (!('retryNum' in currentTest)) currentTest.retryNum = 0;
24
- else currentTest.retryNum += 1;
25
- });
23
+ event.dispatcher.on(event.test.started, test => {
24
+ currentTest = test
25
+ currentTest.steps = []
26
+ if (!('retryNum' in currentTest)) currentTest.retryNum = 0
27
+ else currentTest.retryNum += 1
28
+ output.scenario.started(test)
29
+ })
26
30
 
27
- event.dispatcher.on(event.test.after, (test) => {
28
- currentTest = null;
29
- });
31
+ event.dispatcher.on(event.test.after, test => {
32
+ currentTest = null
33
+ })
30
34
 
31
- event.dispatcher.on(event.test.finished, (test) => {
32
- });
35
+ event.dispatcher.on(event.test.finished, test => {})
33
36
 
34
- event.dispatcher.on(event.hook.started, (suite) => {
35
- currentHook = suite.ctx.test;
36
- currentHook.steps = [];
37
+ event.dispatcher.on(event.hook.started, hook => {
38
+ currentHook = hook.ctx.test
39
+ currentHook.steps = []
37
40
 
38
- if (suite.ctx && suite.ctx.test) output.output.log(`--- STARTED ${suite.ctx.test.title} ---`);
39
- });
41
+ output.hook.started(hook)
40
42
 
41
- event.dispatcher.on(event.hook.passed, (suite) => {
42
- currentHook = null;
43
- if (suite.ctx && suite.ctx.test) output.output.log(`--- ENDED ${suite.ctx.test.title} ---`);
44
- });
43
+ if (hook.ctx && hook.ctx.test) debug(`--- STARTED ${hook.ctx.test.title} ---`)
44
+ })
45
+
46
+ event.dispatcher.on(event.hook.passed, hook => {
47
+ currentHook = null
48
+ output.hook.passed(hook)
49
+ if (hook.ctx && hook.ctx.test) debug(`--- ENDED ${hook.ctx.test.title} ---`)
50
+ })
45
51
 
46
52
  event.dispatcher.on(event.test.failed, () => {
47
53
  const cutSteps = function (current) {
48
- const failureIndex = current.steps.findIndex(el => el.status === 'failed');
54
+ const failureIndex = current.steps.findIndex(el => el.status === 'failed')
49
55
  // To be sure that failed test will be failed in report
50
- current.state = 'failed';
51
- current.steps.length = failureIndex + 1;
52
- return current;
53
- };
56
+ current.state = 'failed'
57
+ current.steps.length = failureIndex + 1
58
+ return current
59
+ }
54
60
  if (currentHook && Array.isArray(currentHook.steps) && currentHook.steps.length) {
55
- currentHook = cutSteps(currentHook);
56
- return currentHook = null;
61
+ currentHook = cutSteps(currentHook)
62
+ return (currentHook = null)
57
63
  }
58
- if (!currentTest) return;
64
+ if (!currentTest) return
59
65
  // last step is failing step
60
- if (!currentTest.steps.length) return;
61
- return currentTest = cutSteps(currentTest);
62
- });
66
+ if (!currentTest.steps.length) return
67
+ return (currentTest = cutSteps(currentTest))
68
+ })
63
69
 
64
70
  event.dispatcher.on(event.test.passed, () => {
65
- if (!currentTest) return;
71
+ if (!currentTest) return
66
72
  // To be sure that passed test will be passed in report
67
- delete currentTest.err;
68
- currentTest.state = 'passed';
69
- });
73
+ delete currentTest.err
74
+ currentTest.state = 'passed'
75
+ })
70
76
 
71
- event.dispatcher.on(event.step.started, (step) => {
72
- step.startedAt = +new Date();
73
- step.test = currentTest;
77
+ event.dispatcher.on(event.step.started, step => {
78
+ store.currentStep = step
74
79
  if (currentHook && Array.isArray(currentHook.steps)) {
75
- return currentHook.steps.push(step);
80
+ return currentHook.steps.push(step)
81
+ }
82
+ if (!currentTest || !currentTest.steps) return
83
+
84
+ // Check if we're in a session that should be excluded from main test steps
85
+ const currentSessionId = recorder.getCurrentSessionId()
86
+ if (currentSessionId && EXCLUDED_SESSIONS.includes(currentSessionId)) {
87
+ // Skip adding this step to the main test steps
88
+ return
76
89
  }
77
- if (!currentTest || !currentTest.steps) return;
78
- currentTest.steps.push(step);
79
- });
80
-
81
- event.dispatcher.on(event.step.finished, (step) => {
82
- step.finishedAt = +new Date();
83
- if (step.startedAt) step.duration = step.finishedAt - step.startedAt;
84
- debug(`Step '${step}' finished; Duration: ${step.duration || 0}ms`);
85
- });
90
+
91
+ currentTest.steps.push(step)
92
+ })
93
+
94
+ event.dispatcher.on(event.step.finished, step => {
95
+ store.currentStep = null
96
+ store.stepOptions = null
97
+ })
86
98
  }
@@ -0,0 +1,20 @@
1
+ import event from '../event.js'
2
+ import store from '../store.js'
3
+
4
+ export default function () {
5
+ event.dispatcher.on(event.suite.before, suite => {
6
+ store.currentSuite = suite
7
+ })
8
+
9
+ event.dispatcher.on(event.suite.after, () => {
10
+ store.currentSuite = null
11
+ })
12
+
13
+ event.dispatcher.on(event.test.before, test => {
14
+ store.currentTest = test
15
+ })
16
+
17
+ event.dispatcher.on(event.test.finished, () => {
18
+ store.currentTest = null
19
+ })
20
+ }