codeceptjs 3.7.6-beta.4 → 4.0.0-beta.10.esm-aria

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 (191) hide show
  1. package/README.md +1 -3
  2. package/bin/codecept.js +51 -53
  3. package/bin/test-server.js +14 -3
  4. package/docs/webapi/click.mustache +5 -1
  5. package/lib/actor.js +15 -11
  6. package/lib/ai.js +72 -107
  7. package/lib/assert/empty.js +9 -8
  8. package/lib/assert/equal.js +15 -17
  9. package/lib/assert/error.js +2 -2
  10. package/lib/assert/include.js +9 -11
  11. package/lib/assert/throws.js +1 -1
  12. package/lib/assert/truth.js +8 -5
  13. package/lib/assert.js +18 -18
  14. package/lib/codecept.js +102 -75
  15. package/lib/colorUtils.js +48 -50
  16. package/lib/command/check.js +32 -27
  17. package/lib/command/configMigrate.js +11 -10
  18. package/lib/command/definitions.js +16 -10
  19. package/lib/command/dryRun.js +16 -16
  20. package/lib/command/generate.js +62 -27
  21. package/lib/command/gherkin/init.js +36 -38
  22. package/lib/command/gherkin/snippets.js +14 -14
  23. package/lib/command/gherkin/steps.js +21 -18
  24. package/lib/command/info.js +8 -8
  25. package/lib/command/init.js +36 -29
  26. package/lib/command/interactive.js +11 -10
  27. package/lib/command/list.js +10 -9
  28. package/lib/command/run-multiple/chunk.js +5 -5
  29. package/lib/command/run-multiple/collection.js +5 -5
  30. package/lib/command/run-multiple/run.js +3 -3
  31. package/lib/command/run-multiple.js +16 -13
  32. package/lib/command/run-rerun.js +6 -7
  33. package/lib/command/run-workers.js +24 -9
  34. package/lib/command/run.js +23 -8
  35. package/lib/command/utils.js +20 -18
  36. package/lib/command/workers/runTests.js +197 -114
  37. package/lib/config.js +124 -51
  38. package/lib/container.js +438 -87
  39. package/lib/data/context.js +6 -5
  40. package/lib/data/dataScenarioConfig.js +1 -1
  41. package/lib/data/dataTableArgument.js +1 -1
  42. package/lib/data/table.js +1 -1
  43. package/lib/effects.js +94 -10
  44. package/lib/element/WebElement.js +2 -2
  45. package/lib/els.js +11 -9
  46. package/lib/event.js +11 -10
  47. package/lib/globals.js +141 -0
  48. package/lib/heal.js +12 -12
  49. package/lib/helper/AI.js +11 -11
  50. package/lib/helper/ApiDataFactory.js +50 -19
  51. package/lib/helper/Appium.js +19 -27
  52. package/lib/helper/FileSystem.js +32 -12
  53. package/lib/helper/GraphQL.js +3 -3
  54. package/lib/helper/GraphQLDataFactory.js +4 -4
  55. package/lib/helper/JSONResponse.js +25 -29
  56. package/lib/helper/Mochawesome.js +7 -4
  57. package/lib/helper/Playwright.js +902 -164
  58. package/lib/helper/Puppeteer.js +383 -76
  59. package/lib/helper/REST.js +29 -12
  60. package/lib/helper/WebDriver.js +268 -61
  61. package/lib/helper/clientscripts/PollyWebDriverExt.js +1 -1
  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 +18 -9
  70. package/lib/helper/extras/PlaywrightRestartOpts.js +34 -23
  71. package/lib/helper/extras/Popup.js +1 -1
  72. package/lib/helper/extras/React.js +29 -30
  73. package/lib/helper/network/actions.js +29 -44
  74. package/lib/helper/network/utils.js +76 -83
  75. package/lib/helper/scripts/blurElement.js +6 -6
  76. package/lib/helper/scripts/focusElement.js +6 -6
  77. package/lib/helper/scripts/highlightElement.js +9 -9
  78. package/lib/helper/scripts/isElementClickable.js +34 -34
  79. package/lib/helper.js +2 -1
  80. package/lib/history.js +23 -20
  81. package/lib/hooks.js +10 -10
  82. package/lib/html.js +90 -100
  83. package/lib/index.js +48 -21
  84. package/lib/listener/config.js +19 -12
  85. package/lib/listener/emptyRun.js +6 -7
  86. package/lib/listener/enhancedGlobalRetry.js +6 -6
  87. package/lib/listener/exit.js +4 -3
  88. package/lib/listener/globalRetry.js +5 -5
  89. package/lib/listener/globalTimeout.js +30 -14
  90. package/lib/listener/helpers.js +39 -14
  91. package/lib/listener/mocha.js +3 -4
  92. package/lib/listener/result.js +4 -5
  93. package/lib/listener/retryEnhancer.js +3 -3
  94. package/lib/listener/steps.js +8 -7
  95. package/lib/listener/store.js +3 -3
  96. package/lib/locator.js +213 -192
  97. package/lib/mocha/asyncWrapper.js +105 -62
  98. package/lib/mocha/bdd.js +99 -13
  99. package/lib/mocha/cli.js +59 -26
  100. package/lib/mocha/factory.js +78 -19
  101. package/lib/mocha/featureConfig.js +1 -1
  102. package/lib/mocha/gherkin.js +56 -24
  103. package/lib/mocha/hooks.js +12 -3
  104. package/lib/mocha/index.js +13 -4
  105. package/lib/mocha/inject.js +22 -5
  106. package/lib/mocha/scenarioConfig.js +2 -2
  107. package/lib/mocha/suite.js +9 -2
  108. package/lib/mocha/test.js +10 -7
  109. package/lib/mocha/ui.js +28 -18
  110. package/lib/output.js +10 -8
  111. package/lib/parser.js +44 -44
  112. package/lib/pause.js +15 -16
  113. package/lib/plugin/analyze.js +19 -12
  114. package/lib/plugin/auth.js +20 -21
  115. package/lib/plugin/autoDelay.js +12 -8
  116. package/lib/plugin/coverage.js +28 -11
  117. package/lib/plugin/customLocator.js +3 -3
  118. package/lib/plugin/customReporter.js +3 -2
  119. package/lib/plugin/enhancedRetryFailedStep.js +6 -6
  120. package/lib/plugin/heal.js +14 -9
  121. package/lib/plugin/htmlReporter.js +724 -99
  122. package/lib/plugin/pageInfo.js +10 -10
  123. package/lib/plugin/pauseOnFail.js +4 -3
  124. package/lib/plugin/retryFailedStep.js +48 -5
  125. package/lib/plugin/screenshotOnFail.js +75 -37
  126. package/lib/plugin/stepByStepReport.js +14 -14
  127. package/lib/plugin/stepTimeout.js +4 -3
  128. package/lib/plugin/subtitles.js +6 -5
  129. package/lib/recorder.js +33 -14
  130. package/lib/rerun.js +69 -26
  131. package/lib/result.js +4 -4
  132. package/lib/retryCoordinator.js +2 -2
  133. package/lib/secret.js +18 -17
  134. package/lib/session.js +95 -89
  135. package/lib/step/base.js +7 -7
  136. package/lib/step/comment.js +2 -2
  137. package/lib/step/config.js +1 -1
  138. package/lib/step/func.js +3 -3
  139. package/lib/step/helper.js +3 -3
  140. package/lib/step/meta.js +5 -5
  141. package/lib/step/record.js +11 -11
  142. package/lib/step/retry.js +3 -3
  143. package/lib/step/section.js +3 -3
  144. package/lib/step.js +7 -10
  145. package/lib/steps.js +9 -5
  146. package/lib/store.js +1 -1
  147. package/lib/template/heal.js +1 -1
  148. package/lib/template/prompts/generatePageObject.js +31 -0
  149. package/lib/template/prompts/healStep.js +13 -0
  150. package/lib/template/prompts/writeStep.js +9 -0
  151. package/lib/test-server.js +17 -6
  152. package/lib/timeout.js +1 -7
  153. package/lib/transform.js +8 -8
  154. package/lib/translation.js +32 -18
  155. package/lib/utils/mask_data.js +4 -10
  156. package/lib/utils.js +66 -64
  157. package/lib/workerStorage.js +17 -17
  158. package/lib/workers.js +214 -84
  159. package/package.json +41 -37
  160. package/translations/de-DE.js +2 -2
  161. package/translations/fr-FR.js +2 -2
  162. package/translations/index.js +23 -10
  163. package/translations/it-IT.js +2 -2
  164. package/translations/ja-JP.js +2 -2
  165. package/translations/nl-NL.js +2 -2
  166. package/translations/pl-PL.js +2 -2
  167. package/translations/pt-BR.js +2 -2
  168. package/translations/ru-RU.js +2 -2
  169. package/translations/utils.js +4 -3
  170. package/translations/zh-CN.js +2 -2
  171. package/translations/zh-TW.js +2 -2
  172. package/typings/index.d.ts +5 -3
  173. package/typings/promiseBasedTypes.d.ts +4 -0
  174. package/typings/types.d.ts +4 -0
  175. package/lib/helper/Nightmare.js +0 -1486
  176. package/lib/helper/Protractor.js +0 -1840
  177. package/lib/helper/TestCafe.js +0 -1391
  178. package/lib/helper/clientscripts/nightmare.js +0 -213
  179. package/lib/helper/testcafe/testControllerHolder.js +0 -42
  180. package/lib/helper/testcafe/testcafe-utils.js +0 -61
  181. package/lib/plugin/allure.js +0 -15
  182. package/lib/plugin/autoLogin.js +0 -5
  183. package/lib/plugin/commentStep.js +0 -141
  184. package/lib/plugin/eachElement.js +0 -127
  185. package/lib/plugin/fakerTransform.js +0 -49
  186. package/lib/plugin/retryTo.js +0 -16
  187. package/lib/plugin/selenoid.js +0 -364
  188. package/lib/plugin/standardActingHelpers.js +0 -6
  189. package/lib/plugin/tryTo.js +0 -16
  190. package/lib/plugin/wdio.js +0 -247
  191. package/lib/within.js +0 -90
package/lib/config.js CHANGED
@@ -1,11 +1,7 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
- const {
4
- fileExists,
5
- isFile,
6
- deepMerge,
7
- deepClone,
8
- } = require('./utils');
1
+ import fs from 'fs'
2
+ import path from 'path'
3
+ import { createRequire } from 'module'
4
+ import { fileExists, isFile, deepMerge, deepClone } from './utils.js'
9
5
 
10
6
  const defaultConfig = {
11
7
  output: './_output',
@@ -33,18 +29,12 @@ const defaultConfig = {
33
29
  timeout: 0,
34
30
  },
35
31
  ],
36
- };
32
+ }
37
33
 
38
- let hooks = [];
39
- let config = {};
34
+ let hooks = []
35
+ let config = {}
40
36
 
41
- const configFileNames = [
42
- 'codecept.config.js',
43
- 'codecept.conf.js',
44
- 'codecept.js',
45
- 'codecept.config.ts',
46
- 'codecept.conf.ts',
47
- ];
37
+ const configFileNames = ['codecept.config.js', 'codecept.conf.js', 'codecept.js', 'codecept.config.cjs', 'codecept.conf.cjs', 'codecept.config.ts', 'codecept.conf.ts']
48
38
 
49
39
  /**
50
40
  * Current configuration
@@ -57,9 +47,9 @@ class Config {
57
47
  * @return {Object<string, *>}
58
48
  */
59
49
  static create(newConfig) {
60
- config = deepMerge(deepClone(defaultConfig), newConfig);
61
- hooks.forEach(f => f(config));
62
- return config;
50
+ config = deepMerge(deepClone(defaultConfig), newConfig)
51
+ hooks.forEach(f => f(config))
52
+ return config
63
53
  }
64
54
 
65
55
  /**
@@ -75,34 +65,45 @@ class Config {
75
65
  * @param {string} configFile
76
66
  * @return {*}
77
67
  */
78
- static load(configFile) {
79
- configFile = path.resolve(configFile || '.');
68
+ static async load(configFile) {
69
+ configFile = path.resolve(configFile || '.')
80
70
 
81
71
  if (!fileExists(configFile)) {
82
- configFile = configFile.replace('.js', '.ts');
83
-
84
- if (!fileExists(configFile)) {
85
- throw new Error(`Config file ${configFile} does not exist. Execute 'codeceptjs init' to create config`);
72
+ // Try different extensions if the file doesn't exist
73
+ const extensions = ['.ts', '.cjs', '.mjs']
74
+ let found = false
75
+
76
+ for (const ext of extensions) {
77
+ const altConfig = configFile.replace(/\.js$/, ext)
78
+ if (fileExists(altConfig)) {
79
+ configFile = altConfig
80
+ found = true
81
+ break
82
+ }
83
+ }
84
+
85
+ if (!found) {
86
+ throw new Error(`Config file ${configFile} does not exist. Execute 'codeceptjs init' to create config`)
86
87
  }
87
88
  }
88
89
 
89
90
  // is config file
90
91
  if (isFile(configFile)) {
91
- return loadConfigFile(configFile);
92
+ return await loadConfigFile(configFile)
92
93
  }
93
94
 
94
95
  for (const name of configFileNames) {
95
96
  // is path to directory
96
- const jsConfig = path.join(configFile, name);
97
+ const jsConfig = path.join(configFile, name)
97
98
 
98
99
  if (isFile(jsConfig)) {
99
- return loadConfigFile(jsConfig);
100
+ return await loadConfigFile(jsConfig)
100
101
  }
101
102
  }
102
103
 
103
- const configPaths = configFileNames.map(name => path.join(configFile, name)).join(' or ');
104
+ const configPaths = configFileNames.map(name => path.join(configFile, name)).join(' or ')
104
105
 
105
- throw new Error(`Can not load config from ${configPaths}\nCodeceptJS is not initialized in this dir. Execute 'codeceptjs init' to start`);
106
+ throw new Error(`Can not load config from ${configPaths}\nCodeceptJS is not initialized in this dir. Execute 'codeceptjs init' to start`)
106
107
  }
107
108
 
108
109
  /**
@@ -113,13 +114,13 @@ class Config {
113
114
  */
114
115
  static get(key, val) {
115
116
  if (key) {
116
- return config[key] || val;
117
+ return config[key] || val
117
118
  }
118
- return config;
119
+ return config
119
120
  }
120
121
 
121
122
  static addHook(fn) {
122
- hooks.push(fn);
123
+ hooks.push(fn)
123
124
  }
124
125
 
125
126
  /**
@@ -129,7 +130,7 @@ class Config {
129
130
  * @return {Object<string, *>}
130
131
  */
131
132
  static append(additionalConfig) {
132
- return config = deepMerge(config, additionalConfig);
133
+ return (config = deepMerge(config, additionalConfig))
133
134
  }
134
135
 
135
136
  /**
@@ -137,33 +138,105 @@ class Config {
137
138
  * @return {Object<string, *>}
138
139
  */
139
140
  static reset() {
140
- hooks = [];
141
- return config = { ...defaultConfig };
141
+ hooks = []
142
+ return (config = { ...defaultConfig })
142
143
  }
143
144
  }
144
145
 
145
- module.exports = Config;
146
+ export default Config
146
147
 
147
- function loadConfigFile(configFile) {
148
- const extensionName = path.extname(configFile);
148
+ async function loadConfigFile(configFile) {
149
+ const require = createRequire(import.meta.url)
150
+ const extensionName = path.extname(configFile)
149
151
 
150
- if (extensionName === '.ts') {
152
+ // .conf.js config file
153
+ if (extensionName === '.js' || extensionName === '.ts' || extensionName === '.cjs') {
154
+ let configModule
151
155
  try {
152
- require('ts-node/register');
153
- } catch (err) {
154
- console.log('ts-node package is required to parse codecept.conf.ts config correctly');
156
+ // For .ts files, try to compile and load as JavaScript
157
+ if (extensionName === '.ts') {
158
+ try {
159
+ // Try to load ts-node and compile the file
160
+ const { transpile } = require('typescript')
161
+ const tsContent = fs.readFileSync(configFile, 'utf8')
162
+
163
+ // Transpile TypeScript to JavaScript with ES module output
164
+ const jsContent = transpile(tsContent, {
165
+ module: 99, // ModuleKind.ESNext
166
+ target: 99, // ScriptTarget.ESNext
167
+ esModuleInterop: true,
168
+ allowSyntheticDefaultImports: true,
169
+ })
170
+
171
+ // Create a temporary JS file with .mjs extension to force ES module treatment
172
+ const tempJsFile = configFile.replace('.ts', '.temp.mjs')
173
+ fs.writeFileSync(tempJsFile, jsContent)
174
+
175
+ try {
176
+ configModule = await import(tempJsFile)
177
+ // Clean up temp file
178
+ fs.unlinkSync(tempJsFile)
179
+ } catch (err) {
180
+ // Clean up temp file even on error
181
+ if (fs.existsSync(tempJsFile)) {
182
+ fs.unlinkSync(tempJsFile)
183
+ }
184
+ throw err
185
+ }
186
+ } catch (tsError) {
187
+ // If TypeScript compilation fails, fallback to ts-node
188
+ try {
189
+ require('ts-node/register')
190
+ configModule = require(configFile)
191
+ } catch (tsNodeError) {
192
+ throw new Error(`Failed to load TypeScript config: ${tsError.message}`)
193
+ }
194
+ }
195
+ } else {
196
+ // Try ESM import first for JS files
197
+ configModule = await import(configFile)
198
+ }
199
+ } catch (importError) {
200
+ try {
201
+ // Fall back to CommonJS require for .js/.cjs files
202
+ if (extensionName !== '.ts') {
203
+ configModule = require(configFile)
204
+ } else {
205
+ throw importError
206
+ }
207
+ } catch (requireError) {
208
+ throw new Error(`Failed to load config file ${configFile}: ${importError.message}`)
209
+ }
155
210
  }
156
- }
157
211
 
158
- // .conf.js config file
159
- if (extensionName === '.js' || extensionName === '.ts' || extensionName === '.cjs') {
160
- return Config.create(require(configFile).config);
212
+ const rawConfig = configModule.config || configModule.default?.config || configModule.default || configModule
213
+
214
+ // Process helpers to extract imported classes
215
+ if (rawConfig.helpers) {
216
+ const processedHelpers = {}
217
+ for (const [helperName, helperConfig] of Object.entries(rawConfig.helpers)) {
218
+ // Check if the helper name itself is a class (ESM import)
219
+ if (typeof helperName === 'function' && helperName.prototype) {
220
+ // This is an imported class, use its constructor name
221
+ const className = helperName.name
222
+ processedHelpers[className] = {
223
+ ...helperConfig,
224
+ _helperClass: helperName,
225
+ }
226
+ } else {
227
+ processedHelpers[helperName] = helperConfig
228
+ }
229
+ }
230
+ rawConfig.helpers = processedHelpers
231
+ }
232
+
233
+ return Config.create(rawConfig)
161
234
  }
162
235
 
163
236
  // json config provided
164
237
  if (extensionName === '.json') {
165
- return Config.create(JSON.parse(fs.readFileSync(configFile, 'utf8')));
238
+ return Config.create(JSON.parse(fs.readFileSync(configFile, 'utf8')))
166
239
  }
167
240
 
168
- throw new Error(`Config file ${configFile} can't be loaded`);
241
+ throw new Error(`Config file ${configFile} can't be loaded`)
169
242
  }