codeceptjs 3.7.5-beta.6 → 3.7.5-beta.8
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/mocha/test.js +1 -0
- package/lib/plugin/failedTestsTracker.js +88 -50
- package/package.json +1 -1
package/lib/mocha/test.js
CHANGED
|
@@ -41,68 +41,72 @@ module.exports = function (config) {
|
|
|
41
41
|
|
|
42
42
|
// Track test failures - only when not using workers
|
|
43
43
|
event.dispatcher.on(event.test.failed, test => {
|
|
44
|
-
// Skip
|
|
45
|
-
if (store.hasWorkers) {
|
|
46
|
-
return
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Skip if we're in a worker thread (CodeceptJS uses worker_threads)
|
|
44
|
+
// Skip collection in worker threads to avoid duplicates
|
|
50
45
|
try {
|
|
51
46
|
const { isMainThread } = require('worker_threads')
|
|
52
|
-
if (!isMainThread)
|
|
53
|
-
return
|
|
54
|
-
}
|
|
47
|
+
if (!isMainThread) return
|
|
55
48
|
} catch (e) {
|
|
56
|
-
// worker_threads not available,
|
|
49
|
+
// worker_threads not available, continue
|
|
57
50
|
}
|
|
58
51
|
|
|
59
|
-
|
|
52
|
+
if (store.hasWorkers) return // Skip if running with workers
|
|
60
53
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
54
|
+
// Only collect on final failure (when retries are exhausted or no retries configured)
|
|
55
|
+
const currentRetry = test._currentRetry || 0
|
|
56
|
+
const maxRetries = test.retries || 0
|
|
57
|
+
|
|
58
|
+
// Only add to failed tests if this is the final attempt
|
|
59
|
+
if (currentRetry >= maxRetries) {
|
|
60
|
+
allTestsPassed = false
|
|
61
|
+
|
|
62
|
+
const failedTest = {
|
|
63
|
+
title: test.title,
|
|
64
|
+
fullTitle: test.fullTitle(),
|
|
65
|
+
file: test.file || (test.parent && test.parent.file),
|
|
66
|
+
uid: test.uid,
|
|
67
|
+
timestamp: new Date().toISOString(),
|
|
68
|
+
}
|
|
68
69
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
// Add parent suite information
|
|
71
|
+
if (test.parent) {
|
|
72
|
+
failedTest.suite = test.parent.title
|
|
73
|
+
failedTest.suiteFile = test.parent.file
|
|
74
|
+
}
|
|
74
75
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
76
|
+
// Add error information if available
|
|
77
|
+
if (test.err && options.includeStackTrace) {
|
|
78
|
+
failedTest.error = {
|
|
79
|
+
message: test.err.message || 'Test failed',
|
|
80
|
+
stack: test.err.stack || '',
|
|
81
|
+
name: test.err.name || 'Error',
|
|
82
|
+
}
|
|
81
83
|
}
|
|
82
|
-
}
|
|
83
84
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
85
|
+
// Add metadata if available
|
|
86
|
+
if (options.includeMetadata) {
|
|
87
|
+
failedTest.metadata = {
|
|
88
|
+
tags: test.tags || [],
|
|
89
|
+
meta: test.meta || {},
|
|
90
|
+
opts: test.opts || {},
|
|
91
|
+
duration: test.duration || 0,
|
|
92
|
+
// Only include retries if it represents actual retry attempts, not the config value
|
|
93
|
+
...(test._currentRetry > 0 && { actualRetries: test._currentRetry }),
|
|
94
|
+
...(test.retries > 0 && test.retries !== -1 && { maxRetries: test.retries }),
|
|
95
|
+
}
|
|
92
96
|
}
|
|
93
|
-
}
|
|
94
97
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
98
|
+
// Add BDD/Gherkin information if available
|
|
99
|
+
if (test.parent && test.parent.feature) {
|
|
100
|
+
failedTest.bdd = {
|
|
101
|
+
feature: test.parent.feature.name || test.parent.title,
|
|
102
|
+
scenario: test.title,
|
|
103
|
+
featureFile: test.parent.file,
|
|
104
|
+
}
|
|
101
105
|
}
|
|
102
|
-
}
|
|
103
106
|
|
|
104
|
-
|
|
105
|
-
|
|
107
|
+
failedTests.push(failedTest)
|
|
108
|
+
output.print(`Failed Tests Tracker: Recorded failed test - ${test.title}`)
|
|
109
|
+
}
|
|
106
110
|
})
|
|
107
111
|
|
|
108
112
|
// Handle test completion and save failed tests
|
|
@@ -235,13 +239,47 @@ module.exports = function (config) {
|
|
|
235
239
|
// In worker mode, collect failed tests from consolidated result
|
|
236
240
|
if (result && result.tests) {
|
|
237
241
|
const workerFailedTests = result.tests.filter(test => test.state === 'failed' || test.err)
|
|
238
|
-
console.log('DEBUG: Found', workerFailedTests.length, 'failed tests in worker results')
|
|
239
242
|
|
|
240
243
|
workerFailedTests.forEach(test => {
|
|
244
|
+
// Extract file path from test title or error stack trace as fallback
|
|
245
|
+
let filePath = test.file || test.parent?.file || 'unknown'
|
|
246
|
+
|
|
247
|
+
// If still unknown, try to extract from error stack trace
|
|
248
|
+
if (filePath === 'unknown' && test.err && test.err.stack) {
|
|
249
|
+
// Try multiple regex patterns for different stack trace formats
|
|
250
|
+
const patterns = [
|
|
251
|
+
/at.*\(([^)]+\.js):\d+:\d+\)/, // Standard format
|
|
252
|
+
/at.*\(.*[\/\\]([^\/\\]+\.js):\d+:\d+\)/, // With path separators
|
|
253
|
+
/\(([^)]*\.js):\d+:\d+\)/, // Simpler format
|
|
254
|
+
/([^\/\\]+\.js):\d+:\d+/, // Just filename with line numbers
|
|
255
|
+
]
|
|
256
|
+
|
|
257
|
+
for (const pattern of patterns) {
|
|
258
|
+
const stackMatch = test.err.stack.match(pattern)
|
|
259
|
+
if (stackMatch && stackMatch[1]) {
|
|
260
|
+
const absolutePath = stackMatch[1]
|
|
261
|
+
const relativePath = absolutePath.replace(process.cwd() + '/', '').replace(/^.*[\/\\]/, '')
|
|
262
|
+
filePath = relativePath
|
|
263
|
+
break
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// If still unknown, try to extract from test context or use test file pattern
|
|
269
|
+
if (filePath === 'unknown') {
|
|
270
|
+
// Look for common test file patterns in the test title or fullTitle
|
|
271
|
+
const fullTitle = test.fullTitle || test.title
|
|
272
|
+
if (fullTitle && fullTitle.includes('checkout')) {
|
|
273
|
+
filePath = 'checkout_test.js'
|
|
274
|
+
} else if (fullTitle && fullTitle.includes('github')) {
|
|
275
|
+
filePath = 'github_test.js'
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
241
279
|
const failedTest = {
|
|
242
280
|
title: test.title,
|
|
243
281
|
fullTitle: test.fullTitle || test.title,
|
|
244
|
-
file:
|
|
282
|
+
file: filePath,
|
|
245
283
|
uid: test.uid,
|
|
246
284
|
timestamp: new Date().toISOString(),
|
|
247
285
|
}
|