@@ -100,9 +100,6 @@ function makeRenderer() {
100100 return {
101101 /** A page script that never yields; Chromium stops it on `Runtime.terminateExecution`. */
102102 busyScript : null as PromiseWithResolvers < void > | null ,
103- gotoStarted : Promise . withResolvers < void > ( ) ,
104- /** Rejecting these stands in for Playwright's goto timeout while the script runs. */
105- stalledGotos : [ ] as Array < ( cause : Error ) => void > ,
106103 } ;
107104}
108105
@@ -229,14 +226,8 @@ function makeContext(onClose?: (context: BrowserContext) => void, initialUrl = "
229226 viewport = size ;
230227 } ) ,
231228 goto : vi . fn ( async ( next : string , _options ?: { timeout ?: number } ) => {
232- const busyScript = renderer . busyScript ;
233- renderer . gotoStarted . resolve ( ) ;
234- if ( busyScript ) {
235- await new Promise < void > ( ( resolve , reject ) => {
236- renderer . stalledGotos . push ( reject ) ;
237- void busyScript . promise . then ( resolve ) ;
238- } ) ;
239- }
229+ // A same-site goto commits only once the page's script stops.
230+ await renderer . busyScript ?. promise ;
240231 url = next ;
241232 events . emit ( "load" ) ;
242233 const pending = initialNavigation ;
@@ -979,31 +970,21 @@ it.live.each(["load", "none"] as const)(
979970 sessions . flatMap ( ( session ) => session . send . mock . calls . map ( ( [ method ] ) => method ) ) ,
980971 ) . not . toContain ( "Runtime.terminateExecution" ) ;
981972 renderer . busyScript = Promise . withResolvers < void > ( ) ;
982- renderer . gotoStarted = Promise . withResolvers < void > ( ) ;
983973
984- const navigation = yield * broker
974+ const navigated = yield * broker
985975 . invoke < PreviewAutomationStatus > ( {
986976 scope,
987977 tabId,
988978 operation : "navigate" ,
989979 input : { url : "http://localhost:5173/next" , readiness, timeoutMs : 200 } ,
990980 } )
991- . pipe ( Effect . exit , Effect . forkScoped ) ;
992- yield * Effect . promise ( ( ) => renderer . gotoStarted . promise ) ;
993- for ( const timeOut of renderer . stalledGotos . splice ( 0 ) ) {
994- timeOut (
995- Object . assign ( new Error ( "page.goto: Timeout 200ms exceeded." ) , {
996- name : "TimeoutError" ,
997- } ) ,
998- ) ;
999- }
1000- const navigated = yield * Fiber . join ( navigation ) ;
981+ . pipe ( Effect . exit ) ;
1001982 const waited = yield * broker
1002983 . invoke ( {
1003984 scope,
1004985 tabId,
1005986 operation : "waitFor" ,
1006- input : { urlIncludes : "/next" , timeoutMs : 100 } ,
987+ input : { urlIncludes : "/next" , timeoutMs : 1_000 } ,
1007988 } )
1008989 . pipe ( Effect . exit ) ;
1009990 const status = yield * broker . invoke < PreviewAutomationStatus > ( {
@@ -1015,10 +996,9 @@ it.live.each(["load", "none"] as const)(
1015996
1016997 expect ( status . url ) . toBe ( "http://localhost:5173/next" ) ;
1017998 expect ( navigated ) . toMatchObject ( { _tag : "Success" } ) ;
1018- // Waiting on the busy script spends half the navigation's own budget, not all of it .
999+ // A cross-site goto can leave a hung page by itself, so the probe takes none of its budget .
10191000 const [ , gotoOptions ] = contexts [ 0 ] ! . page . goto . mock . calls . at ( - 1 ) ! ;
1020- expect ( gotoOptions ?. timeout ) . toBeLessThan ( 200 ) ;
1021- expect ( gotoOptions ?. timeout ) . toBeGreaterThan ( 1 ) ;
1001+ expect ( gotoOptions ?. timeout ) . toBe ( 200 ) ;
10221002 expect ( waited ) . toMatchObject ( { _tag : "Success" } ) ;
10231003 } ) ,
10241004 ) . pipe ( Effect . provide ( layer ) ) ,
0 commit comments