@@ -4,34 +4,74 @@ import { mount } from "@/mount";
4
4
import makeRouter from "../../../src/router" ;
5
5
import { mockEndpoint , mockEndpointDynamic } from "../../utils" ;
6
6
import { mockServer } from "../../mock-server" ;
7
- import { App } from "vue" ;
7
+ import { App , nextTick } from "vue" ;
8
+
9
+ // Utility function to wait for Vue's reactivity system to settle
10
+ async function waitForVue ( ) {
11
+ // Wait for Vue's nextTick to ensure reactive updates are complete
12
+ await nextTick ( ) ;
13
+ // Additional wait for any pending async operations
14
+ await new Promise ( ( resolve ) => setTimeout ( resolve , 0 ) ) ;
15
+ }
8
16
9
17
function makeDriver ( ) {
10
- let app : App < Element > ;
18
+ let app : App < Element > | null = null ;
11
19
const driver = < Driver > {
12
20
async goTo ( path ) {
13
21
const router = makeRouter ( ) ;
22
+
23
+ // First, clean up any existing app to prevent race conditions
24
+ if ( app ) {
25
+ try {
26
+ app . unmount ( ) ;
27
+ await waitForVue ( ) ;
28
+ } catch {
29
+ // Ignore unmount errors
30
+ }
31
+ }
32
+
14
33
try {
15
34
await router . push ( path ) ;
16
35
} catch ( error ) {
17
36
// Ignore redirection error.
18
37
if ( error instanceof Error && error . message . includes ( "Redirected when going from" ) ) {
19
- return ;
38
+ // Still need to continue with mounting even after redirect
39
+ } else {
40
+ throw error ;
20
41
}
21
-
22
- throw error ;
23
42
}
24
43
44
+ // Clean and prepare DOM
25
45
document . body . innerHTML = '<div id="app"></div><div id="modalDisplay"></div>' ;
46
+
47
+ // Mount the Vue app
26
48
app = mount ( { router } ) ;
49
+
50
+ // Wait for Vue to fully initialize and mount
51
+ await waitForVue ( ) ;
52
+
53
+ // Wait for router to be ready and any initial navigation to complete
54
+ await router . isReady ( ) ;
55
+
56
+ // Additional wait for component mounting and initial renders
57
+ await waitForVue ( ) ;
27
58
} ,
28
59
mockEndpoint,
29
60
mockEndpointDynamic : mockEndpointDynamic ,
30
61
setUp ( factory ) {
31
62
return factory ( { driver : this } ) ;
32
63
} ,
33
- disposeApp ( ) {
34
- app . unmount ( ) ;
64
+ async disposeApp ( ) {
65
+ if ( app ) {
66
+ try {
67
+ app . unmount ( ) ;
68
+ await waitForVue ( ) ;
69
+ } catch ( error ) {
70
+ // Ignore unmount errors
71
+ console . warn ( "Error during app disposal:" , error ) ;
72
+ }
73
+ app = null ;
74
+ }
35
75
} ,
36
76
} ;
37
77
return driver ;
@@ -44,11 +84,17 @@ const test = itVitest.extend<{ driver: Driver }>({
44
84
mockServer . resetHandlers ( ) ;
45
85
46
86
const driver = makeDriver ( ) ;
47
- //run the test
48
- await use ( driver ) ;
49
87
50
- //unmount the app after the test runs
51
- driver . disposeApp ( ) ;
88
+ try {
89
+ //run the test
90
+ await use ( driver ) ;
91
+ } finally {
92
+ //unmount the app after the test runs (even if test fails)
93
+ await driver . disposeApp ( ) ;
94
+
95
+ // Additional cleanup: wait for any pending Vue operations
96
+ await waitForVue ( ) ;
97
+ }
52
98
} ,
53
99
} ) ;
54
100
0 commit comments