@@ -581,16 +581,24 @@ test.describe('workspace transport baseline', () => {
581581 event . session_id === String ( session . id ) && event . kind === 'tool_started'
582582 ) ) . toBe ( true ) ;
583583 let lastReloadStatus : string | null = null ;
584- await expect . poll ( async ( ) => {
585- lastReloadStatus = await page
586- . locator ( `.agent-pane-card[data-session-id="${ session . id } "]` )
587- . first ( )
588- . getAttribute ( 'data-session-status' ) ;
589- return lastReloadStatus === 'running' || lastReloadStatus === 'background' ;
590- } , {
591- timeout : 20000 ,
592- message : `session status after reload: ${ lastReloadStatus ?? 'null' } ` ,
593- } ) . toBe ( true ) ;
584+ try {
585+ await expect . poll ( async ( ) => {
586+ lastReloadStatus = await page
587+ . locator ( `.agent-pane-card[data-session-id="${ session . id } "]` )
588+ . first ( )
589+ . getAttribute ( 'data-session-status' ) ;
590+ return lastReloadStatus === 'running' || lastReloadStatus === 'background' ;
591+ } , {
592+ timeout : 20000 ,
593+ message : `session status after reload: ${ lastReloadStatus ?? 'null' } ` ,
594+ } ) . toBe ( true ) ;
595+ } catch {
596+ const debug = await readWorkspaceReloadDebug ( page , workspace . workspaceId , ids ) ;
597+ throw new Error ( [
598+ `session status after reload: ${ lastReloadStatus ?? 'null' } ` ,
599+ JSON . stringify ( debug ) ,
600+ ] . join ( '\n' ) ) ;
601+ }
594602
595603 await page . goto ( 'about:blank' ) ;
596604 await page . waitForTimeout ( 2200 ) ;
@@ -954,16 +962,24 @@ test.describe('workspace transport baseline', () => {
954962 await waitForWorkspaceTopbar ( page ) ;
955963 await waitForBackendSocket ( page ) ;
956964 let resumedStatus : string | null = null ;
957- await expect . poll ( async ( ) => {
958- resumedStatus = await page
959- . locator ( `.agent-pane-card[data-session-id="${ session . id } "]` )
960- . first ( )
961- . getAttribute ( 'data-session-status' ) ;
962- return resumedStatus === 'running' || resumedStatus === 'background' ;
963- } , {
964- timeout : 5000 ,
965- message : `resumed session status after reload: ${ resumedStatus ?? 'null' } ` ,
966- } ) . toBe ( true ) ;
965+ try {
966+ await expect . poll ( async ( ) => {
967+ resumedStatus = await page
968+ . locator ( `.agent-pane-card[data-session-id="${ session . id } "]` )
969+ . first ( )
970+ . getAttribute ( 'data-session-status' ) ;
971+ return resumedStatus === 'running' || resumedStatus === 'background' ;
972+ } , {
973+ timeout : 5000 ,
974+ message : `resumed session status after reload: ${ resumedStatus ?? 'null' } ` ,
975+ } ) . toBe ( true ) ;
976+ } catch {
977+ const debug = await readWorkspaceReloadDebug ( page , workspace . workspaceId , ids ) ;
978+ throw new Error ( [
979+ `resumed session status after reload: ${ resumedStatus ?? 'null' } ` ,
980+ JSON . stringify ( debug ) ,
981+ ] . join ( '\n' ) ) ;
982+ }
967983 } finally {
968984 if ( workspace && ! page . isClosed ( ) ) {
969985 await closeWorkspaceBestEffort ( page , workspace . workspaceId , ids ) ;
@@ -1725,6 +1741,56 @@ async function waitForLifecycleReplayEntry(
17251741 . toBe ( true ) ;
17261742}
17271743
1744+ async function readWorkspaceReloadDebug (
1745+ page : Page ,
1746+ workspaceId : string ,
1747+ ids : { deviceId : string ; clientId : string } ,
1748+ ) {
1749+ const [ cards , focusState , runtime ] = await Promise . all ( [
1750+ page . locator ( '.agent-pane-card' ) . evaluateAll ( ( nodes ) => nodes . map ( ( node ) => ( {
1751+ sessionId : node . getAttribute ( 'data-session-id' ) ,
1752+ status : node . getAttribute ( 'data-session-status' ) ,
1753+ title : node . querySelector ( '.agent-pane-title' ) ?. textContent ?. trim ( ) ?? null ,
1754+ } ) ) ) ,
1755+ page . evaluate ( ( ) => ( {
1756+ visibilityState : document . visibilityState ,
1757+ hasFocus : document . hasFocus ( ) ,
1758+ } ) ) ,
1759+ invokeRpc < {
1760+ snapshot : {
1761+ sessions : Array < { id : number } > ;
1762+ view_state : {
1763+ active_session_id : string ;
1764+ active_pane_id : string ;
1765+ } ;
1766+ } ;
1767+ controller : {
1768+ controller_device_id ?: string | null ;
1769+ controller_client_id ?: string | null ;
1770+ fencing_token ?: number ;
1771+ } ;
1772+ lifecycle_events ?: Array < { session_id : string ; kind : string ; data ?: string } > ;
1773+ } > ( page , 'workspace_runtime_attach' , {
1774+ workspaceId,
1775+ deviceId : ids . deviceId ,
1776+ clientId : ids . clientId ,
1777+ } ) ,
1778+ ] ) ;
1779+
1780+ return {
1781+ url : page . url ( ) ,
1782+ focusState,
1783+ cards,
1784+ snapshot : {
1785+ sessionIds : runtime . snapshot . sessions . map ( ( session ) => session . id ) ,
1786+ activeSessionId : runtime . snapshot . view_state . active_session_id ,
1787+ activePaneId : runtime . snapshot . view_state . active_pane_id ,
1788+ } ,
1789+ controller : runtime . controller ,
1790+ lifecycleTail : ( runtime . lifecycle_events ?? [ ] ) . slice ( - 6 ) ,
1791+ } ;
1792+ }
1793+
17281794async function countWsEvents (
17291795 page : Page ,
17301796 eventName : string ,
0 commit comments