11import { test , expect } from '@playwright/test'
2- import { setupInlineFixture , type Fixture , useFixture } from './fixture'
2+ import { setupInlineFixture , useFixture } from './fixture'
33import { waitForHydration , expectNoReload } from './helper'
44
55test . describe ( ( ) => {
@@ -12,7 +12,6 @@ test.describe(() => {
1212 files : {
1313 'src/root.tsx' : /* tsx */ `
1414 import { TestSyntaxErrorClient } from './client.tsx'
15- import { TestSyntaxErrorServer } from './server.tsx'
1615
1716 export function Root() {
1817 return (
@@ -22,7 +21,7 @@ test.describe(() => {
2221 </head>
2322 <body>
2423 <TestSyntaxErrorClient />
25- <TestSyntaxErrorServer / >
24+ <div data-testid="server-content">server:ok</div >
2625 </body>
2726 </html>
2827 )
@@ -43,15 +42,7 @@ test.describe(() => {
4342 >
4443 Client Count: {count}
4544 </button>
46- </div>
47- )
48- }
49- ` ,
50- 'src/server.tsx' : /* tsx */ `
51- export function TestSyntaxErrorServer() {
52- return (
53- <div data-testid="server-syntax-ready">
54- Server ready for syntax error testing
45+ <div data-testid="client-content">client:ok</div>
5546 </div>
5647 )
5748 }
@@ -60,126 +51,161 @@ test.describe(() => {
6051 } )
6152 } )
6253
63- test . describe ( 'dev' , ( ) => {
54+ test . describe ( ( ) => {
6455 const f = useFixture ( { root, mode : 'dev' } )
65- defineSyntaxErrorTests ( f )
66- } )
67- } )
6856
69- function defineSyntaxErrorTests ( f : Fixture ) {
70- test ( 'client syntax error triggers error overlay' , async ( { page } ) => {
71- await page . goto ( f . url ( ) )
72- await waitForHydration ( page )
73- await using _ = await expectNoReload ( page )
74-
75- await expect ( page . getByTestId ( 'client-syntax-ready' ) ) . toBeVisible ( )
76-
77- // Set client state to verify preservation after HMR
78- await page . getByTestId ( 'client-counter' ) . click ( )
79- await expect ( page . getByTestId ( 'client-counter' ) ) . toHaveText (
80- 'Client Count: 1' ,
81- )
82-
83- // Introduce syntax error and verify error overlay
84- const editor = f . createEditor ( 'src/client.tsx' )
85- editor . edit ( ( s ) =>
86- s . replace (
87- 'export function TestSyntaxErrorClient() {' ,
88- 'export function TestSyntaxErrorClient() { const invalid = ;' ,
89- ) ,
90- )
91- await expect ( page . locator ( 'vite-error-overlay' ) ) . toBeVisible ( )
92-
93- // Fix error and verify recovery with preserved client state
94- editor . reset ( )
95- await expect ( page . locator ( 'vite-error-overlay' ) ) . not . toBeVisible ( )
96- await expect ( page . getByTestId ( 'client-syntax-ready' ) ) . toBeVisible ( )
97- await expect ( page . getByTestId ( 'client-counter' ) ) . toHaveText (
98- 'Client Count: 1' ,
99- )
57+ test ( 'client hmr' , async ( { page } ) => {
58+ await page . goto ( f . url ( ) )
59+ await waitForHydration ( page )
60+ await using _ = await expectNoReload ( page )
61+ await expect ( page . getByTestId ( 'client-content' ) ) . toHaveText ( 'client:ok' )
62+
63+ // Set client state to verify preservation after HMR
64+ await page . getByTestId ( 'client-counter' ) . click ( )
65+ await expect ( page . getByTestId ( 'client-counter' ) ) . toHaveText (
66+ 'Client Count: 1' ,
67+ )
68+
69+ // add syntax error
70+ const editor = f . createEditor ( 'src/client.tsx' )
71+ editor . edit ( ( s ) =>
72+ s . replace (
73+ '<div data-testid="client-content">client:ok</div>' ,
74+ '<div data-testid="client-content">client:broken<</div>' ,
75+ ) ,
76+ )
77+ await expect ( page . locator ( 'vite-error-overlay' ) ) . toBeVisible ( )
78+
79+ // fix syntax error
80+ await page . waitForTimeout ( 200 )
81+ editor . edit ( ( s ) =>
82+ s . replace (
83+ '<div data-testid="client-content">client:broken<</div>' ,
84+ '<div data-testid="client-content">client:fixed</div>' ,
85+ ) ,
86+ )
87+ await expect ( page . locator ( 'vite-error-overlay' ) ) . not . toBeVisible ( )
88+ await expect ( page . getByTestId ( 'client-syntax-ready' ) ) . toBeVisible ( )
89+ await expect ( page . getByTestId ( 'client-content' ) ) . toHaveText (
90+ 'client:fixed' ,
91+ )
92+ await expect ( page . getByTestId ( 'client-counter' ) ) . toHaveText (
93+ 'Client Count: 1' ,
94+ )
95+ } )
10096 } )
10197
102- test ( 'server syntax error triggers error overlay' , async ( { page } ) => {
103- await page . goto ( f . url ( ) )
104- await waitForHydration ( page )
105- await using _ = await expectNoReload ( page )
106-
107- // Set client state to verify preservation during server HMR
108- await page . getByTestId ( 'client-counter' ) . click ( )
109- await expect ( page . getByTestId ( 'client-counter' ) ) . toHaveText (
110- 'Client Count: 1' ,
111- )
112-
113- // Introduce server syntax error and verify error overlay
114- const editor = f . createEditor ( 'src/server.tsx' )
115- editor . edit ( ( s ) =>
116- s . replace (
117- 'export function TestSyntaxErrorServer() {' ,
118- 'export function TestSyntaxErrorServer() { const invalid = ;' ,
119- ) ,
120- )
121- await expect ( page . locator ( 'vite-error-overlay' ) ) . toBeVisible ( )
122-
123- // Fix error and verify recovery with preserved client state
124- editor . reset ( )
125- await expect ( page . locator ( 'vite-error-overlay' ) ) . not . toBeVisible ( )
126- await expect ( page . getByTestId ( 'server-syntax-ready' ) ) . toBeVisible ( )
127- await expect ( page . getByTestId ( 'client-counter' ) ) . toHaveText (
128- 'Client Count: 1' ,
129- )
130- } )
98+ test . describe ( ( ) => {
99+ const f = useFixture ( { root, mode : 'dev' } )
131100
132- test ( 'initial SSR with server component syntax error shows error page' , async ( {
133- page,
134- } ) => {
135- // Introduce server syntax error and navigate to page
136- const editor = f . createEditor ( 'src/server.tsx' )
137- editor . edit ( ( s ) =>
138- s . replace (
139- 'export function TestSyntaxErrorServer() {' ,
140- 'export function TestSyntaxErrorServer() { const invalid = ;' ,
141- ) ,
142- )
143- await page . goto ( f . url ( ) )
144- await expect ( page . locator ( 'body' ) ) . toContainText (
145- 'Transform failed with 1 error' ,
146- )
147-
148- // Fix error and verify recovery
149- editor . reset ( )
150- await expect ( async ( ) => {
101+ test ( 'server hmr' , async ( { page } ) => {
151102 await page . goto ( f . url ( ) )
152- const bodyText = await page . locator ( 'body' ) . textContent ( )
153- if ( bodyText ?. includes ( 'Transform failed with 1 error' ) ) {
154- throw new Error ( 'Still seeing error page' )
155- }
156103 await waitForHydration ( page )
157- await expect ( page . getByTestId ( 'server-syntax-ready' ) ) . toBeVisible ( )
158- } ) . toPass ( { timeout : 15000 } )
104+ await using _ = await expectNoReload ( page )
105+
106+ await expect ( page . getByTestId ( 'server-content' ) ) . toHaveText ( 'server:ok' )
107+
108+ // Set client state to verify preservation during server HMR
109+ await page . getByTestId ( 'client-counter' ) . click ( )
110+ await expect ( page . getByTestId ( 'client-counter' ) ) . toHaveText (
111+ 'Client Count: 1' ,
112+ )
113+
114+ // add syntax error
115+ const editor = f . createEditor ( 'src/root.tsx' )
116+ editor . edit ( ( s ) =>
117+ s . replace (
118+ '<div data-testid="server-content">server:ok</div>' ,
119+ '<div data-testid="server-content">server:broken<</div>' ,
120+ ) ,
121+ )
122+ await expect ( page . locator ( 'vite-error-overlay' ) ) . toBeVisible ( )
123+
124+ // fix syntax error
125+ await page . waitForTimeout ( 200 )
126+ editor . edit ( ( s ) =>
127+ s . replace (
128+ '<div data-testid="server-content">server:broken<</div>' ,
129+ '<div data-testid="server-content">server:fixed</div>' ,
130+ ) ,
131+ )
132+ await expect ( page . locator ( 'vite-error-overlay' ) ) . not . toBeVisible ( )
133+ await expect ( page . getByTestId ( 'server-content' ) ) . toHaveText (
134+ 'server:fixed' ,
135+ )
136+ await expect ( page . getByTestId ( 'client-counter' ) ) . toHaveText (
137+ 'Client Count: 1' ,
138+ )
139+ } )
159140 } )
160141
161- test ( 'initial SSR with client component syntax error shows error page' , async ( {
162- page,
163- } ) => {
164- // Introduce client syntax error and navigate to page
165- const editor = f . createEditor ( 'src/client.tsx' )
166- editor . edit ( ( s ) =>
167- s . replace (
168- 'export function TestSyntaxErrorClient() {' ,
169- 'export function TestSyntaxErrorClient() { const invalid = ;' ,
170- ) ,
171- )
172- await page . goto ( f . url ( ) )
173- await expect ( page . locator ( 'body' ) ) . toContainText (
174- 'Transform failed with 1 error' ,
175- )
176-
177- // Fix error and verify recovery
178- editor . reset ( )
179- await expect ( async ( ) => {
142+ test . describe ( ( ) => {
143+ const f = useFixture ( { root, mode : 'dev' } )
144+
145+ test ( 'client ssr' , async ( { page } ) => {
146+ // add syntax error
147+ const editor = f . createEditor ( 'src/client.tsx' )
148+ editor . edit ( ( s ) =>
149+ s . replace (
150+ '<div data-testid="client-content">client:ok</div>' ,
151+ '<div data-testid="client-content">client:broken<</div>' ,
152+ ) ,
153+ )
180154 await page . goto ( f . url ( ) )
181- await waitForHydration ( page )
182- await expect ( page . getByTestId ( 'client-syntax-ready' ) ) . toBeVisible ( )
183- } ) . toPass ( )
155+ await expect ( page . locator ( 'body' ) ) . toContainText (
156+ 'Transform failed with 1 error' ,
157+ )
158+
159+ // fix syntax error
160+ await page . waitForTimeout ( 200 )
161+ editor . edit ( ( s ) =>
162+ s . replace (
163+ '<div data-testid="client-content">client:broken<</div>' ,
164+ '<div data-testid="client-content">client:fixed</div>' ,
165+ ) ,
166+ )
167+ await expect ( async ( ) => {
168+ await page . goto ( f . url ( ) )
169+ await waitForHydration ( page )
170+ await expect ( page . getByTestId ( 'client-content' ) ) . toHaveText (
171+ 'client:fixed' ,
172+ )
173+ } ) . toPass ( )
174+ } )
184175 } )
185- }
176+
177+ test . describe ( ( ) => {
178+ const f = useFixture ( { root, mode : 'dev' } )
179+
180+ test ( 'server ssr' , async ( { page } ) => {
181+ // add syntax error
182+ const editor = f . createEditor ( 'src/root.tsx' )
183+ editor . edit ( ( s ) =>
184+ s . replace (
185+ '<div data-testid="server-content">server:ok</div>' ,
186+ '<div data-testid="server-content">server:broken<</div>' ,
187+ ) ,
188+ )
189+ await page . goto ( f . url ( ) )
190+ await expect ( page . locator ( 'body' ) ) . toContainText (
191+ 'Transform failed with 1 error' ,
192+ )
193+
194+ // fix syntax error
195+ await page . waitForTimeout ( 200 )
196+ editor . edit ( ( s ) =>
197+ s . replace (
198+ '<div data-testid="server-content">server:broken<</div>' ,
199+ '<div data-testid="server-content">server:fixed</div>' ,
200+ ) ,
201+ )
202+ await expect ( async ( ) => {
203+ await page . goto ( f . url ( ) )
204+ await waitForHydration ( page )
205+ await expect ( page . getByTestId ( 'server-content' ) ) . toHaveText (
206+ 'server:fixed' ,
207+ )
208+ } ) . toPass ( )
209+ } )
210+ } )
211+ } )
0 commit comments