codeceptjs 4.0.2-beta.4 → 4.0.2-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/command/workers/runTests.js +21 -1
- package/lib/workers.js +37 -1
- package/package.json +1 -1
|
@@ -19,6 +19,18 @@ const stderr = ''
|
|
|
19
19
|
|
|
20
20
|
const { options, tests, testRoot, workerIndex, poolMode } = workerData
|
|
21
21
|
|
|
22
|
+
// Global error handlers to prevent worker from hanging
|
|
23
|
+
process.on('uncaughtException', (err) => {
|
|
24
|
+
console.error(`[Worker ${workerIndex}] Uncaught exception:`, err.message)
|
|
25
|
+
console.error(err.stack)
|
|
26
|
+
process.exit(1)
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
process.on('unhandledRejection', (reason, promise) => {
|
|
30
|
+
console.error(`[Worker ${workerIndex}] Unhandled rejection:`, reason)
|
|
31
|
+
process.exit(1)
|
|
32
|
+
})
|
|
33
|
+
|
|
22
34
|
// hide worker output
|
|
23
35
|
// In pool mode, only suppress output if debug is NOT enabled
|
|
24
36
|
// In regular mode, hide result output but allow step output in verbose/debug
|
|
@@ -144,6 +156,7 @@ async function runTests() {
|
|
|
144
156
|
try {
|
|
145
157
|
await codecept.bootstrap()
|
|
146
158
|
} catch (err) {
|
|
159
|
+
console.error(`[Worker ${workerIndex}] Bootstrap error:`, err.message)
|
|
147
160
|
throw new Error(`Error while running bootstrap file :${err}`)
|
|
148
161
|
}
|
|
149
162
|
listenToParentThread()
|
|
@@ -151,8 +164,15 @@ async function runTests() {
|
|
|
151
164
|
disablePause()
|
|
152
165
|
try {
|
|
153
166
|
await codecept.run()
|
|
167
|
+
} catch (err) {
|
|
168
|
+
console.error(`[Worker ${workerIndex}] Runtime error:`, err.message)
|
|
169
|
+
throw err
|
|
154
170
|
} finally {
|
|
155
|
-
|
|
171
|
+
try {
|
|
172
|
+
await codecept.teardown()
|
|
173
|
+
} catch (err) {
|
|
174
|
+
console.error(`[Worker ${workerIndex}] Teardown error:`, err.message)
|
|
175
|
+
}
|
|
156
176
|
}
|
|
157
177
|
}
|
|
158
178
|
|
package/lib/workers.js
CHANGED
|
@@ -542,8 +542,32 @@ class Workers extends EventEmitter {
|
|
|
542
542
|
if (this.isPoolMode) {
|
|
543
543
|
this.activeWorkers.set(worker, { available: true, workerIndex: null })
|
|
544
544
|
}
|
|
545
|
+
|
|
546
|
+
// Track last activity time to detect hanging workers
|
|
547
|
+
let lastActivity = Date.now()
|
|
548
|
+
let currentTest = null
|
|
549
|
+
const workerTimeout = 300000 // 5 minutes
|
|
550
|
+
|
|
551
|
+
const timeoutChecker = setInterval(() => {
|
|
552
|
+
const elapsed = Date.now() - lastActivity
|
|
553
|
+
if (elapsed > workerTimeout) {
|
|
554
|
+
console.error(`[Main] Worker appears to be hanging (no activity for ${Math.floor(elapsed/1000)}s). Terminating...`)
|
|
555
|
+
if (currentTest) {
|
|
556
|
+
console.error(`[Main] Last test: ${currentTest}`)
|
|
557
|
+
}
|
|
558
|
+
clearInterval(timeoutChecker)
|
|
559
|
+
worker.terminate()
|
|
560
|
+
}
|
|
561
|
+
}, 30000) // Check every 30 seconds
|
|
545
562
|
|
|
546
563
|
worker.on('message', message => {
|
|
564
|
+
lastActivity = Date.now() // Update activity timestamp
|
|
565
|
+
|
|
566
|
+
// Track current test
|
|
567
|
+
if (message.event === event.test.started && message.data) {
|
|
568
|
+
currentTest = message.data.title || message.data.fullTitle
|
|
569
|
+
}
|
|
570
|
+
|
|
547
571
|
output.process(message.workerIndex)
|
|
548
572
|
|
|
549
573
|
// Handle test requests for pool mode
|
|
@@ -660,11 +684,23 @@ class Workers extends EventEmitter {
|
|
|
660
684
|
})
|
|
661
685
|
|
|
662
686
|
worker.on('error', err => {
|
|
687
|
+
console.error(`[Main] Worker error:`, err.message || err)
|
|
688
|
+
if (currentTest) {
|
|
689
|
+
console.error(`[Main] Failed during test: ${currentTest}`)
|
|
690
|
+
}
|
|
663
691
|
this.errors.push(err)
|
|
664
692
|
})
|
|
665
693
|
|
|
666
|
-
worker.on('exit', () => {
|
|
694
|
+
worker.on('exit', (code) => {
|
|
695
|
+
clearInterval(timeoutChecker)
|
|
667
696
|
this.closedWorkers += 1
|
|
697
|
+
|
|
698
|
+
if (code !== 0) {
|
|
699
|
+
console.error(`[Main] Worker exited with code ${code}`)
|
|
700
|
+
if (currentTest) {
|
|
701
|
+
console.error(`[Main] Last test running: ${currentTest}`)
|
|
702
|
+
}
|
|
703
|
+
}
|
|
668
704
|
|
|
669
705
|
if (this.isPoolMode) {
|
|
670
706
|
// Pool mode: finish when all workers have exited and no more tests
|