diff --git a/lib/listener/globalTimeout.js b/lib/listener/globalTimeout.js index 7acd9c78e..e569aacc8 100644 --- a/lib/listener/globalTimeout.js +++ b/lib/listener/globalTimeout.js @@ -122,7 +122,7 @@ export default function () { if (typeof timeout !== 'number') return if (!store.timeouts) { - debug('step', step.toCode().trim(), 'timeout disabled') + debug('step', (step.code || (typeof step.toCode === 'function' ? step.toCode() : step.name)).trim(), 'timeout disabled') return } @@ -130,7 +130,7 @@ export default function () { debug('Previous steps timed out, setting timeout to 0.01s') step.setTimeout(0.01, TIMEOUT_ORDER.testOrSuite) } else { - debug(`Setting timeout ${timeout}ms for step ${step.toCode().trim()}`) + debug(`Setting timeout ${timeout}ms for step ${(step.code || (typeof step.toCode === 'function' ? step.toCode() : step.name)).trim()}`) step.setTimeout(timeout, TIMEOUT_ORDER.testOrSuite) } }) @@ -158,17 +158,17 @@ export default function () { event.dispatcher.on(event.step.finished, step => { if (!store.timeouts) { - debug('step', step.toCode().trim(), 'timeout disabled') + debug('step', (step.code || (typeof step.toCode === 'function' ? step.toCode() : step.name)).trim(), 'timeout disabled') return } if (typeof timeout === 'number') debug('Timeout', timeout) - debug(`step ${step.toCode().trim()}:${step.status} duration`, step.duration) + debug(`step ${(step.code || (typeof step.toCode === 'function' ? step.toCode() : step.name)).trim()}:${step.status} duration`, step.duration) if (typeof timeout === 'number' && !Number.isNaN(timeout)) timeout -= step.duration if (typeof timeout === 'number' && timeout <= 0 && recorder.isRunning()) { - debug(`step ${step.toCode().trim()} timed out`) + debug(`step ${(step.code || (typeof step.toCode === 'function' ? step.toCode() : step.name)).trim()} timed out`) recorder.throw(new TestTimeoutError(currentTimeout)) } }) diff --git a/lib/step/base.js b/lib/step/base.js index 1000c048e..b2ab35381 100644 --- a/lib/step/base.js +++ b/lib/step/base.js @@ -228,6 +228,7 @@ class Step { startTime: step.startTime, endTime: step.endTime, parent, + code: step.toCode(), } } diff --git a/lib/workers.js b/lib/workers.js index 0ed3a71b3..0d231a29f 100644 --- a/lib/workers.js +++ b/lib/workers.js @@ -626,18 +626,22 @@ class Workers extends EventEmitter { break case event.suite.before: this.emit(event.suite.before, deserializeSuite(message.data)) + event.dispatcher.emit(event.suite.before, deserializeSuite(message.data)) break case event.test.before: this.emit(event.test.before, deserializeTest(message.data)) + event.dispatcher.emit(event.test.before, deserializeTest(message.data)) break case event.test.started: this.emit(event.test.started, deserializeTest(message.data)) + event.dispatcher.emit(event.test.started, deserializeTest(message.data)) break case event.test.failed: // For hook failures, emit immediately as there won't be a test.finished event // Regular test failures are handled via test.finished to support retries if (message.data?.hookName) { this.emit(event.test.failed, deserializeTest(message.data)) + event.dispatcher.emit(event.test.failed, deserializeTest(message.data)) } // Otherwise skip - we'll emit based on finished state break @@ -646,6 +650,7 @@ class Workers extends EventEmitter { break case event.test.skipped: this.emit(event.test.skipped, deserializeTest(message.data)) + event.dispatcher.emit(event.test.skipped, deserializeTest(message.data)) break case event.test.finished: // Handle different types of test completion properly @@ -669,34 +674,44 @@ class Workers extends EventEmitter { // For tests without UID, emit immediately if (isFailed) { this.emit(event.test.failed, deserializeTest(data)) + event.dispatcher.emit(event.test.failed, deserializeTest(data)) } else { this.emit(event.test.passed, deserializeTest(data)) + event.dispatcher.emit(event.test.passed, deserializeTest(data)) } } this.emit(event.test.finished, deserializeTest(data)) + event.dispatcher.emit(event.test.finished, deserializeTest(data)) } break case event.test.after: this.emit(event.test.after, deserializeTest(message.data)) + event.dispatcher.emit(event.test.after, deserializeTest(message.data)) break case event.step.finished: this.emit(event.step.finished, message.data) + event.dispatcher.emit(event.step.finished, message.data) break case event.step.started: this.emit(event.step.started, message.data) + event.dispatcher.emit(event.step.started, message.data) break case event.step.passed: this.emit(event.step.passed, message.data) + event.dispatcher.emit(event.step.passed, message.data) break case event.step.failed: this.emit(event.step.failed, message.data, message.data.error) + event.dispatcher.emit(event.step.failed, message.data, message.data.error) break case event.hook.failed: // Hook failures are already reported as test failures by the worker // Just emit the hook.failed event for listeners this.emit(event.hook.failed, message.data) + event.dispatcher.emit(event.hook.failed, message.data) break + } }) @@ -759,16 +774,20 @@ class Workers extends EventEmitter { for (const state of states) { if (state.isFailed) { this.emit(event.test.failed, deserializeTest(state.data)) + event.dispatcher.emit(event.test.failed, deserializeTest(state.data)) } else { this.emit(event.test.passed, deserializeTest(state.data)) + event.dispatcher.emit(event.test.passed, deserializeTest(state.data)) } } } else { // For non-retries (like step failures), emit only the final state if (lastState.isFailed) { this.emit(event.test.failed, deserializeTest(lastState.data)) + event.dispatcher.emit(event.test.failed, deserializeTest(lastState.data)) } else { this.emit(event.test.passed, deserializeTest(lastState.data)) + event.dispatcher.emit(event.test.passed, deserializeTest(lastState.data)) } } }