@@ -7,11 +7,14 @@ import { getInjectedArguments } from './inject.js'
7
7
import { fireHook } from './hooks.js'
8
8
9
9
const 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
+ } )
15
18
recorder . catch ( err => {
16
19
suiteTestFailedHookError ( suite , err )
17
20
throw err
@@ -56,6 +59,8 @@ function test(test) {
56
59
const doneFn = makeDoneCallableOnce ( done )
57
60
// Ensure recorder is running so any steps added inside test function are executed
58
61
recorder . startUnlessRunning ( )
62
+ // Fire started event immediately so listeners are notified regardless of recorder queue
63
+ event . emit ( event . test . started , test )
59
64
recorder . errHandler ( err => {
60
65
recorder . session . start ( 'teardown' )
61
66
recorder . cleanAsyncErr ( )
@@ -76,30 +81,21 @@ function test(test) {
76
81
event . emit ( event . test . finished , test )
77
82
recorder . add ( ( ) => doneFn ( err ) )
78
83
} )
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 )
102
96
} )
97
+ recorder . add ( 'finish test' , doneFn )
98
+ recorder . catch ( )
103
99
}
104
100
return test
105
101
}
0 commit comments