codeceptjs 3.7.5-beta.4 → 3.7.5-beta.6
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/lib/plugin/failedTestsTracker.js +119 -15
- package/package.json +1 -1
|
@@ -16,14 +16,14 @@ const defaultConfig = {
|
|
|
16
16
|
* Failed Tests Tracker Plugin for CodeceptJS
|
|
17
17
|
*
|
|
18
18
|
* Tracks failed tests and saves them to a file for later re-execution.
|
|
19
|
-
*
|
|
19
|
+
*
|
|
20
20
|
* ## Configuration
|
|
21
21
|
*
|
|
22
22
|
* ```js
|
|
23
23
|
* "plugins": {
|
|
24
24
|
* "failedTestsTracker": {
|
|
25
25
|
* "enabled": true,
|
|
26
|
-
* "outputFile": "
|
|
26
|
+
* "outputFile": "failed-tests.json",
|
|
27
27
|
* "clearOnSuccess": true,
|
|
28
28
|
* "includeStackTrace": true,
|
|
29
29
|
* "includeMetadata": true
|
|
@@ -39,15 +39,25 @@ module.exports = function (config) {
|
|
|
39
39
|
let allTestsPassed = true
|
|
40
40
|
let workerFailedTests = new Map() // Track failed tests from workers
|
|
41
41
|
|
|
42
|
-
// Track test failures - only
|
|
42
|
+
// Track test failures - only when not using workers
|
|
43
43
|
event.dispatcher.on(event.test.failed, test => {
|
|
44
|
-
//
|
|
44
|
+
// Skip if main process is using workers (will collect from consolidated results)
|
|
45
45
|
if (store.hasWorkers) {
|
|
46
46
|
return
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
// Skip if we're in a worker thread (CodeceptJS uses worker_threads)
|
|
50
|
+
try {
|
|
51
|
+
const { isMainThread } = require('worker_threads')
|
|
52
|
+
if (!isMainThread) {
|
|
53
|
+
return
|
|
54
|
+
}
|
|
55
|
+
} catch (e) {
|
|
56
|
+
// worker_threads not available, assume main thread
|
|
57
|
+
}
|
|
58
|
+
|
|
49
59
|
allTestsPassed = false
|
|
50
|
-
|
|
60
|
+
|
|
51
61
|
const failedTest = {
|
|
52
62
|
title: test.title,
|
|
53
63
|
fullTitle: test.fullTitle(),
|
|
@@ -95,35 +105,35 @@ module.exports = function (config) {
|
|
|
95
105
|
output.print(`Failed Tests Tracker: Recorded failed test - ${test.title}`)
|
|
96
106
|
})
|
|
97
107
|
|
|
98
|
-
//
|
|
108
|
+
// Handle test completion and save failed tests
|
|
99
109
|
event.dispatcher.on(event.all.result, (result) => {
|
|
100
110
|
// Respect CodeceptJS output directory like other plugins
|
|
101
111
|
const outputDir = global.output_dir || './output'
|
|
102
|
-
const outputPath = path.isAbsolute(options.outputFile)
|
|
103
|
-
? options.outputFile
|
|
112
|
+
const outputPath = path.isAbsolute(options.outputFile)
|
|
113
|
+
? options.outputFile
|
|
104
114
|
: path.resolve(outputDir, options.outputFile)
|
|
105
115
|
let allFailedTests = [...failedTests]
|
|
106
116
|
|
|
107
117
|
// In worker mode, collect failed tests from consolidated result
|
|
108
118
|
if (store.hasWorkers && result && result.tests) {
|
|
109
119
|
const workerFailedTests = result.tests.filter(test => test.state === 'failed' || test.err)
|
|
110
|
-
|
|
120
|
+
|
|
111
121
|
// Use a Set to track unique test identifiers to prevent duplicates
|
|
112
122
|
const existingTestIds = new Set(allFailedTests.map(test => test.uid || `${test.file}:${test.title}`))
|
|
113
|
-
|
|
123
|
+
|
|
114
124
|
workerFailedTests.forEach(test => {
|
|
115
125
|
// Create unique identifier for deduplication
|
|
116
126
|
const testId = test.uid || `${test.file || 'unknown'}:${test.title}`
|
|
117
|
-
|
|
127
|
+
|
|
118
128
|
// Skip if we already have this test
|
|
119
129
|
if (existingTestIds.has(testId)) {
|
|
120
130
|
return
|
|
121
131
|
}
|
|
122
|
-
|
|
132
|
+
|
|
123
133
|
const failedTest = {
|
|
124
134
|
title: test.title,
|
|
125
135
|
fullTitle: test.fullTitle || test.title,
|
|
126
|
-
file: test.file ||
|
|
136
|
+
file: test.file || 'unknown',
|
|
127
137
|
uid: test.uid,
|
|
128
138
|
timestamp: new Date().toISOString(),
|
|
129
139
|
}
|
|
@@ -166,6 +176,8 @@ module.exports = function (config) {
|
|
|
166
176
|
allFailedTests.push(failedTest)
|
|
167
177
|
existingTestIds.add(testId)
|
|
168
178
|
})
|
|
179
|
+
|
|
180
|
+
output.print(`Failed Tests Tracker: Collected ${workerFailedTests.length} failed tests from workers`)
|
|
169
181
|
}
|
|
170
182
|
|
|
171
183
|
if (allFailedTests.length === 0) {
|
|
@@ -212,7 +224,99 @@ module.exports = function (config) {
|
|
|
212
224
|
|
|
213
225
|
// Handle worker mode - listen to workers.result event for consolidated results
|
|
214
226
|
event.dispatcher.on(event.workers.result, (result) => {
|
|
215
|
-
//
|
|
216
|
-
|
|
227
|
+
// Respect CodeceptJS output directory like other plugins
|
|
228
|
+
const outputDir = global.output_dir || './output'
|
|
229
|
+
const outputPath = path.isAbsolute(options.outputFile)
|
|
230
|
+
? options.outputFile
|
|
231
|
+
: path.resolve(outputDir, options.outputFile)
|
|
232
|
+
|
|
233
|
+
let allFailedTests = []
|
|
234
|
+
|
|
235
|
+
// In worker mode, collect failed tests from consolidated result
|
|
236
|
+
if (result && result.tests) {
|
|
237
|
+
const workerFailedTests = result.tests.filter(test => test.state === 'failed' || test.err)
|
|
238
|
+
console.log('DEBUG: Found', workerFailedTests.length, 'failed tests in worker results')
|
|
239
|
+
|
|
240
|
+
workerFailedTests.forEach(test => {
|
|
241
|
+
const failedTest = {
|
|
242
|
+
title: test.title,
|
|
243
|
+
fullTitle: test.fullTitle || test.title,
|
|
244
|
+
file: test.file || 'unknown',
|
|
245
|
+
uid: test.uid,
|
|
246
|
+
timestamp: new Date().toISOString(),
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Add parent suite information
|
|
250
|
+
if (test.parent) {
|
|
251
|
+
failedTest.suite = test.parent.title
|
|
252
|
+
failedTest.suiteFile = test.parent.file
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Add error information if available
|
|
256
|
+
if (test.err && options.includeStackTrace) {
|
|
257
|
+
failedTest.error = {
|
|
258
|
+
message: test.err.message || 'Test failed',
|
|
259
|
+
stack: test.err.stack || '',
|
|
260
|
+
name: test.err.name || 'Error',
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Add metadata if available
|
|
265
|
+
if (options.includeMetadata) {
|
|
266
|
+
failedTest.metadata = {
|
|
267
|
+
tags: test.tags || [],
|
|
268
|
+
meta: test.meta || {},
|
|
269
|
+
opts: test.opts || {},
|
|
270
|
+
duration: test.duration || 0,
|
|
271
|
+
retries: test.retries || 0,
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Add BDD/Gherkin information if available
|
|
276
|
+
if (test.parent && test.parent.feature) {
|
|
277
|
+
failedTest.bdd = {
|
|
278
|
+
feature: test.parent.feature.name || test.parent.title,
|
|
279
|
+
scenario: test.title,
|
|
280
|
+
featureFile: test.parent.file,
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
allFailedTests.push(failedTest)
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
output.print(`Failed Tests Tracker: Collected ${workerFailedTests.length} failed tests from workers`)
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
if (allFailedTests.length === 0) {
|
|
291
|
+
if (options.clearOnSuccess && fs.existsSync(outputPath)) {
|
|
292
|
+
try {
|
|
293
|
+
fs.unlinkSync(outputPath)
|
|
294
|
+
output.print(`Failed Tests Tracker: Cleared previous failed tests file (all tests passed)`)
|
|
295
|
+
} catch (error) {
|
|
296
|
+
output.print(`Failed Tests Tracker: Could not clear failed tests file: ${error.message}`)
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// Save failed tests to file
|
|
303
|
+
try {
|
|
304
|
+
const failedTestsData = {
|
|
305
|
+
timestamp: new Date().toISOString(),
|
|
306
|
+
totalFailed: allFailedTests.length,
|
|
307
|
+
tests: allFailedTests,
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Ensure output directory exists
|
|
311
|
+
const dir = path.dirname(outputPath)
|
|
312
|
+
if (!fs.existsSync(dir)) {
|
|
313
|
+
fs.mkdirSync(dir, { recursive: true })
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
fs.writeFileSync(outputPath, JSON.stringify(failedTestsData, null, 2))
|
|
317
|
+
output.print(`Failed Tests Tracker: Saved ${allFailedTests.length} failed tests to ${outputPath}`)
|
|
318
|
+
} catch (error) {
|
|
319
|
+
output.print(`Failed Tests Tracker: Failed to save failed tests: ${error.message}`)
|
|
320
|
+
}
|
|
217
321
|
})
|
|
218
322
|
}
|