@@ -7,11 +7,14 @@ import { getInjectedArguments } from './inject.js'
77import { fireHook } from './hooks.js'
88
99const injectHook = function ( inject , suite ) {
10- try {
11- inject ( )
12- } catch ( err ) {
13- recorder . throw ( err )
14- }
10+ // Run the hook body inside recorder queue to ensure async parts complete before returning
11+ recorder . add ( 'run hook' , async ( ) => {
12+ try {
13+ await inject ( )
14+ } catch ( err ) {
15+ throw err
16+ }
17+ } )
1518 recorder . catch ( err => {
1619 suiteTestFailedHookError ( suite , err )
1720 throw err
@@ -56,6 +59,8 @@ function test(test) {
5659 const doneFn = makeDoneCallableOnce ( done )
5760 // Ensure recorder is running so any steps added inside test function are executed
5861 recorder . startUnlessRunning ( )
62+ // Fire started event immediately so listeners are notified regardless of recorder queue
63+ event . emit ( event . test . started , test )
5964 recorder . errHandler ( err => {
6065 recorder . session . start ( 'teardown' )
6166 recorder . cleanAsyncErr ( )
@@ -76,30 +81,21 @@ function test(test) {
7681 event . emit ( event . test . finished , test )
7782 recorder . add ( ( ) => doneFn ( err ) )
7883 } )
79- // Schedule the test execution inside recorder to ensure any external recorder.add
80- // calls happen after this and steps added within testFn are executed before finishing
81- recorder . add ( 'execute test function' , async ( ) => {
82- try {
83- const args = await getInjectedArguments ( testFn , test )
84- event . emit ( event . test . started , test )
85- if ( isAsyncFunction ( testFn ) ) {
86- await testFn . call ( test , args )
87- } else {
88- testFn . call ( test , args )
89- }
90- // After testFn schedules its own steps, enqueue passed/finished
91- recorder . add ( 'fire test.passed' , ( ) => {
92- event . emit ( event . test . passed , test )
93- event . emit ( event . test . finished , test )
94- } )
95- } catch ( err ) {
96- recorder . throw ( err )
97- } finally {
98- // Finish test after queued tasks
99- recorder . add ( 'finish test' , doneFn )
100- recorder . catch ( )
101- }
84+
85+ // Wrap test execution in a session so any recorder.add calls inside the test are executed before finishing
86+ recorder . add ( 'start test session' , ( ) => recorder . session . start ( 'test' ) )
87+ recorder . add ( 'execute test' , async ( ) => {
88+ const args = await getInjectedArguments ( testFn , test )
89+ const res = testFn . call ( test , args )
90+ if ( isAsyncFunction ( testFn ) ) await res
91+ } )
92+ recorder . add ( 'restore test session' , ( ) => recorder . session . restore ( 'test' ) )
93+ recorder . add ( 'fire test.passed' , ( ) => {
94+ event . emit ( event . test . passed , test )
95+ event . emit ( event . test . finished , test )
10296 } )
97+ recorder . add ( 'finish test' , doneFn )
98+ recorder . catch ( )
10399 }
104100 return test
105101}
0 commit comments