codeceptjs 4.0.1-beta.23 → 4.0.1-beta.26
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.
- package/bin/codecept.js +1 -2
- package/lib/command/{shell.js → interactive.js} +3 -31
- package/lib/config.js +3 -2
- package/lib/container.js +17 -3
- package/lib/helper/Playwright.js +176 -232
- package/lib/helper/Puppeteer.js +33 -111
- package/lib/helper/WebDriver.js +22 -103
- package/lib/helper/extras/PlaywrightLocator.js +34 -13
- package/lib/helper/extras/PlaywrightReactVueLocator.js +52 -0
- package/lib/locator.js +31 -88
- package/lib/mocha/test.js +4 -2
- package/lib/output.js +2 -2
- package/lib/utils/typescript.js +61 -34
- package/package.json +8 -8
- package/typings/index.d.ts +1 -1
- package/typings/promiseBasedTypes.d.ts +5475 -3929
- package/typings/types.d.ts +5767 -4092
package/lib/output.js
CHANGED
|
@@ -222,12 +222,10 @@ const output = {
|
|
|
222
222
|
/**
|
|
223
223
|
* @param {Mocha.Test} test
|
|
224
224
|
*/
|
|
225
|
-
|
|
226
225
|
started(test) {
|
|
227
226
|
if (outputLevel < 1) return
|
|
228
227
|
print(` ${colors.dim.bold('Scenario()')}`)
|
|
229
228
|
},
|
|
230
|
-
|
|
231
229
|
/**
|
|
232
230
|
* @param {Mocha.Test} test
|
|
233
231
|
*/
|
|
@@ -273,10 +271,12 @@ const output = {
|
|
|
273
271
|
},
|
|
274
272
|
|
|
275
273
|
/**
|
|
274
|
+
* Prints the stats of a test run to the console.
|
|
276
275
|
* @param {number} passed
|
|
277
276
|
* @param {number} failed
|
|
278
277
|
* @param {number} skipped
|
|
279
278
|
* @param {number|string} duration
|
|
279
|
+
* @param {number} [failedHooks]
|
|
280
280
|
*/
|
|
281
281
|
result(passed, failed, skipped, duration, failedHooks = 0) {
|
|
282
282
|
let style = colors.bgGreen
|
package/lib/utils/typescript.js
CHANGED
|
@@ -4,10 +4,10 @@ import path from 'path'
|
|
|
4
4
|
/**
|
|
5
5
|
* Transpile TypeScript files to ES modules with CommonJS shim support
|
|
6
6
|
* Handles recursive transpilation of imported TypeScript files
|
|
7
|
-
*
|
|
7
|
+
*
|
|
8
8
|
* @param {string} mainFilePath - Path to the main TypeScript file to transpile
|
|
9
9
|
* @param {object} typescript - TypeScript compiler instance
|
|
10
|
-
* @returns {Promise<{tempFile: string, allTempFiles: string[]}>} - Main temp file and all temp files created
|
|
10
|
+
* @returns {Promise<{tempFile: string, allTempFiles: string[], fileMapping: any}>} - Main temp file and all temp files created
|
|
11
11
|
*/
|
|
12
12
|
export async function transpileTypeScript(mainFilePath, typescript) {
|
|
13
13
|
const { transpile } = typescript
|
|
@@ -18,7 +18,7 @@ export async function transpileTypeScript(mainFilePath, typescript) {
|
|
|
18
18
|
*/
|
|
19
19
|
const transpileTS = (filePath) => {
|
|
20
20
|
const tsContent = fs.readFileSync(filePath, 'utf8')
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
// Transpile TypeScript to JavaScript with ES module output
|
|
23
23
|
let jsContent = transpile(tsContent, {
|
|
24
24
|
module: 99, // ModuleKind.ESNext
|
|
@@ -29,16 +29,16 @@ export async function transpileTypeScript(mainFilePath, typescript) {
|
|
|
29
29
|
suppressOutputPathCheck: true,
|
|
30
30
|
skipLibCheck: true,
|
|
31
31
|
})
|
|
32
|
-
|
|
32
|
+
|
|
33
33
|
// Check if the code uses CommonJS globals
|
|
34
34
|
const usesCommonJSGlobals = /__dirname|__filename/.test(jsContent)
|
|
35
35
|
const usesRequire = /\brequire\s*\(/.test(jsContent)
|
|
36
36
|
const usesModuleExports = /\b(module\.exports|exports\.)/.test(jsContent)
|
|
37
|
-
|
|
37
|
+
|
|
38
38
|
if (usesCommonJSGlobals || usesRequire || usesModuleExports) {
|
|
39
39
|
// Inject ESM equivalents at the top of the file
|
|
40
40
|
let esmGlobals = ''
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
if (usesRequire || usesModuleExports) {
|
|
43
43
|
// IMPORTANT: Use the original .ts file path as the base for require()
|
|
44
44
|
// This ensures dynamic require() calls work with relative paths from the original file location
|
|
@@ -81,7 +81,7 @@ const exports = module.exports;
|
|
|
81
81
|
|
|
82
82
|
`
|
|
83
83
|
}
|
|
84
|
-
|
|
84
|
+
|
|
85
85
|
if (usesCommonJSGlobals) {
|
|
86
86
|
// For __dirname and __filename, also use the original file path
|
|
87
87
|
const originalFileUrl = `file://${filePath.replace(/\\/g, '/')}`
|
|
@@ -92,48 +92,48 @@ const __dirname = __dirname_fn(__filename);
|
|
|
92
92
|
|
|
93
93
|
`
|
|
94
94
|
}
|
|
95
|
-
|
|
95
|
+
|
|
96
96
|
jsContent = esmGlobals + jsContent
|
|
97
|
-
|
|
97
|
+
|
|
98
98
|
// If module.exports is used, we need to export it as default
|
|
99
99
|
if (usesModuleExports) {
|
|
100
100
|
jsContent += `\nexport default module.exports;\n`
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
|
-
|
|
103
|
+
|
|
104
104
|
return jsContent
|
|
105
105
|
}
|
|
106
|
-
|
|
106
|
+
|
|
107
107
|
// Create a map to track transpiled files
|
|
108
108
|
const transpiledFiles = new Map()
|
|
109
109
|
const baseDir = path.dirname(mainFilePath)
|
|
110
|
-
|
|
110
|
+
|
|
111
111
|
// Recursive function to transpile a file and all its TypeScript dependencies
|
|
112
112
|
const transpileFileAndDeps = (filePath) => {
|
|
113
113
|
// Already transpiled, skip
|
|
114
114
|
if (transpiledFiles.has(filePath)) {
|
|
115
115
|
return
|
|
116
116
|
}
|
|
117
|
-
|
|
117
|
+
|
|
118
118
|
// Transpile this file
|
|
119
119
|
let jsContent = transpileTS(filePath)
|
|
120
|
-
|
|
120
|
+
|
|
121
121
|
// Find all relative TypeScript imports in this file
|
|
122
122
|
const importRegex = /from\s+['"](\..+?)(?:\.ts)?['"]/g
|
|
123
123
|
let match
|
|
124
124
|
const imports = []
|
|
125
|
-
|
|
125
|
+
|
|
126
126
|
while ((match = importRegex.exec(jsContent)) !== null) {
|
|
127
127
|
imports.push(match[1])
|
|
128
128
|
}
|
|
129
|
-
|
|
129
|
+
|
|
130
130
|
// Get the base directory for this file
|
|
131
131
|
const fileBaseDir = path.dirname(filePath)
|
|
132
|
-
|
|
132
|
+
|
|
133
133
|
// Recursively transpile each imported TypeScript file
|
|
134
134
|
for (const relativeImport of imports) {
|
|
135
135
|
let importedPath = path.resolve(fileBaseDir, relativeImport)
|
|
136
|
-
|
|
136
|
+
|
|
137
137
|
// Handle .js extensions that might actually be .ts files
|
|
138
138
|
if (importedPath.endsWith('.js')) {
|
|
139
139
|
const tsVersion = importedPath.replace(/\.js$/, '.ts')
|
|
@@ -141,12 +141,12 @@ const __dirname = __dirname_fn(__filename);
|
|
|
141
141
|
importedPath = tsVersion
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
|
-
|
|
144
|
+
|
|
145
145
|
// Check for standard module extensions to determine if we should try adding .ts
|
|
146
146
|
const ext = path.extname(importedPath)
|
|
147
147
|
const standardExtensions = ['.js', '.mjs', '.cjs', '.json', '.node']
|
|
148
148
|
const hasStandardExtension = standardExtensions.includes(ext.toLowerCase())
|
|
149
|
-
|
|
149
|
+
|
|
150
150
|
// If it doesn't end with .ts and doesn't have a standard extension, try adding .ts
|
|
151
151
|
if (!importedPath.endsWith('.ts') && !hasStandardExtension) {
|
|
152
152
|
const tsPath = importedPath + '.ts'
|
|
@@ -161,20 +161,20 @@ const __dirname = __dirname_fn(__filename);
|
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
|
-
|
|
164
|
+
|
|
165
165
|
// If it's a TypeScript file, recursively transpile it and its dependencies
|
|
166
166
|
if (importedPath.endsWith('.ts') && fs.existsSync(importedPath)) {
|
|
167
167
|
transpileFileAndDeps(importedPath)
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
|
-
|
|
170
|
+
|
|
171
171
|
// After all dependencies are transpiled, rewrite imports in this file
|
|
172
172
|
jsContent = jsContent.replace(
|
|
173
173
|
/from\s+['"](\..+?)(?:\.ts)?['"]/g,
|
|
174
174
|
(match, importPath) => {
|
|
175
175
|
let resolvedPath = path.resolve(fileBaseDir, importPath)
|
|
176
176
|
const originalExt = path.extname(importPath)
|
|
177
|
-
|
|
177
|
+
|
|
178
178
|
// Handle .js extension that might be .ts
|
|
179
179
|
if (resolvedPath.endsWith('.js')) {
|
|
180
180
|
const tsVersion = resolvedPath.replace(/\.js$/, '.ts')
|
|
@@ -190,10 +190,10 @@ const __dirname = __dirname_fn(__filename);
|
|
|
190
190
|
// Keep .js extension as-is (might be a real .js file)
|
|
191
191
|
return match
|
|
192
192
|
}
|
|
193
|
-
|
|
193
|
+
|
|
194
194
|
// Try with .ts extension
|
|
195
195
|
const tsPath = resolvedPath.endsWith('.ts') ? resolvedPath : resolvedPath + '.ts'
|
|
196
|
-
|
|
196
|
+
|
|
197
197
|
// If we transpiled this file, use the temp file
|
|
198
198
|
if (transpiledFiles.has(tsPath)) {
|
|
199
199
|
const tempFile = transpiledFiles.get(tsPath)
|
|
@@ -204,7 +204,7 @@ const __dirname = __dirname_fn(__filename);
|
|
|
204
204
|
}
|
|
205
205
|
return `from '${relPath}'`
|
|
206
206
|
}
|
|
207
|
-
|
|
207
|
+
|
|
208
208
|
// If the import doesn't have a standard module extension (.js, .mjs, .cjs, .json)
|
|
209
209
|
// add .js for ESM compatibility
|
|
210
210
|
// This handles cases where:
|
|
@@ -212,32 +212,59 @@ const __dirname = __dirname_fn(__filename);
|
|
|
212
212
|
// 2. Import has a non-standard extension that's part of the name (e.g., "./abstract.helper")
|
|
213
213
|
const standardExtensions = ['.js', '.mjs', '.cjs', '.json', '.node']
|
|
214
214
|
const hasStandardExtension = standardExtensions.includes(originalExt.toLowerCase())
|
|
215
|
-
|
|
215
|
+
|
|
216
216
|
if (!hasStandardExtension) {
|
|
217
217
|
return match.replace(importPath, importPath + '.js')
|
|
218
218
|
}
|
|
219
|
-
|
|
219
|
+
|
|
220
220
|
// Otherwise, keep the import as-is
|
|
221
221
|
return match
|
|
222
222
|
}
|
|
223
223
|
)
|
|
224
|
-
|
|
224
|
+
|
|
225
225
|
// Write the transpiled file with updated imports
|
|
226
226
|
const tempFile = filePath.replace(/\.ts$/, '.temp.mjs')
|
|
227
227
|
fs.writeFileSync(tempFile, jsContent)
|
|
228
228
|
transpiledFiles.set(filePath, tempFile)
|
|
229
229
|
}
|
|
230
|
-
|
|
230
|
+
|
|
231
231
|
// Start recursive transpilation from the main file
|
|
232
232
|
transpileFileAndDeps(mainFilePath)
|
|
233
|
-
|
|
233
|
+
|
|
234
234
|
// Get the main transpiled file
|
|
235
235
|
const tempJsFile = transpiledFiles.get(mainFilePath)
|
|
236
|
-
|
|
236
|
+
|
|
237
237
|
// Store all temp files for cleanup
|
|
238
238
|
const allTempFiles = Array.from(transpiledFiles.values())
|
|
239
|
-
|
|
240
|
-
return { tempFile: tempJsFile, allTempFiles }
|
|
239
|
+
|
|
240
|
+
return { tempFile: tempJsFile, allTempFiles, fileMapping: transpiledFiles }
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Map error stack traces from temp .mjs files back to original .ts files
|
|
245
|
+
* @param {Error} error - The error object to fix
|
|
246
|
+
* @param {Map<string, string>} fileMapping - Map of original .ts files to temp .mjs files
|
|
247
|
+
* @returns {Error} - Error with fixed stack trace
|
|
248
|
+
*/
|
|
249
|
+
export function fixErrorStack(error, fileMapping) {
|
|
250
|
+
if (!error.stack || !fileMapping) return error
|
|
251
|
+
|
|
252
|
+
let stack = error.stack
|
|
253
|
+
|
|
254
|
+
// Create reverse mapping (temp.mjs -> original.ts)
|
|
255
|
+
const reverseMap = new Map()
|
|
256
|
+
for (const [tsFile, mjsFile] of fileMapping.entries()) {
|
|
257
|
+
reverseMap.set(mjsFile, tsFile)
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Replace all temp.mjs references with original .ts files
|
|
261
|
+
for (const [mjsFile, tsFile] of reverseMap.entries()) {
|
|
262
|
+
const mjsPattern = mjsFile.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
263
|
+
stack = stack.replace(new RegExp(mjsPattern, 'g'), tsFile)
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
error.stack = stack
|
|
267
|
+
return error
|
|
241
268
|
}
|
|
242
269
|
|
|
243
270
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeceptjs",
|
|
3
|
-
"version": "4.0.1-beta.
|
|
3
|
+
"version": "4.0.1-beta.26",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Supercharged End 2 End Testing Framework for NodeJS",
|
|
6
6
|
"keywords": [
|
|
@@ -88,8 +88,8 @@
|
|
|
88
88
|
"@codeceptjs/configure": "1.0.6",
|
|
89
89
|
"@codeceptjs/helper": "2.0.4",
|
|
90
90
|
"@cucumber/cucumber-expressions": "18",
|
|
91
|
-
"@cucumber/gherkin": "37.0.
|
|
92
|
-
"@cucumber/messages": "31.
|
|
91
|
+
"@cucumber/gherkin": "37.0.1",
|
|
92
|
+
"@cucumber/messages": "31.1.0",
|
|
93
93
|
"@xmldom/xmldom": "0.9.8",
|
|
94
94
|
"acorn": "8.15.0",
|
|
95
95
|
"ai": "^5.0.60",
|
|
@@ -138,15 +138,15 @@
|
|
|
138
138
|
"@codeceptjs/expect-helper": "^1.0.2",
|
|
139
139
|
"@codeceptjs/mock-request": "0.3.1",
|
|
140
140
|
"@eslint/eslintrc": "3.3.1",
|
|
141
|
-
"@eslint/js": "9.
|
|
141
|
+
"@eslint/js": "9.39.2",
|
|
142
142
|
"@faker-js/faker": "9.8.0",
|
|
143
|
-
"@inquirer/testing": "^
|
|
143
|
+
"@inquirer/testing": "^3.0.3",
|
|
144
144
|
"@pollyjs/adapter-puppeteer": "6.0.6",
|
|
145
145
|
"@pollyjs/core": "6.0.6",
|
|
146
146
|
"@testomatio/reporter": "^2.3.1",
|
|
147
147
|
"@types/chai": "5.2.3",
|
|
148
148
|
"@types/inquirer": "9.0.9",
|
|
149
|
-
"@types/node": "^
|
|
149
|
+
"@types/node": "^25.0.3",
|
|
150
150
|
"@wdio/sauce-service": "9.12.5",
|
|
151
151
|
"@wdio/selenium-standalone-service": "8.15.0",
|
|
152
152
|
"@wdio/utils": "9.21.0",
|
|
@@ -186,9 +186,9 @@
|
|
|
186
186
|
"tsx": "^4.19.2",
|
|
187
187
|
"typedoc": "0.28.15",
|
|
188
188
|
"typedoc-plugin-markdown": "4.9.0",
|
|
189
|
-
"typescript": "5.
|
|
189
|
+
"typescript": "5.9.3",
|
|
190
190
|
"wdio-docker-service": "3.2.1",
|
|
191
|
-
"webdriverio": "9.
|
|
191
|
+
"webdriverio": "9.23.0",
|
|
192
192
|
"xml2js": "0.6.2",
|
|
193
193
|
"xpath": "0.0.34"
|
|
194
194
|
},
|
package/typings/index.d.ts
CHANGED
|
@@ -519,7 +519,7 @@ declare namespace CodeceptJS {
|
|
|
519
519
|
retry(retries?: number): HookConfig
|
|
520
520
|
}
|
|
521
521
|
|
|
522
|
-
function addStep(step: string, fn: Function): Promise<void>
|
|
522
|
+
function addStep(step: string | RegExp, fn: Function): Promise<void>
|
|
523
523
|
}
|
|
524
524
|
|
|
525
525
|
type TryTo = <T>(fn: () => Promise<T> | T) => Promise<T | false>
|