@@ -78,6 +78,7 @@ const checks: {
7878const screenshots : string [ ] = [ ]
7979const browserErrors : string [ ] = [ ]
8080const voiceDiagnostics : Record < string , unknown > [ ] = [ ]
81+ const signInRecoveryReceipts : Record < string , unknown > [ ] = [ ]
8182const httpErrors : { path : string ; status : number ; injected : boolean } [ ] = [ ]
8283const injectedRequests = new WeakSet < Request > ( )
8384const pendingRequests = new Set < Request > ( )
@@ -534,10 +535,89 @@ try {
534535 userId = String ( id )
535536 await seed ( )
536537 }
538+ let login : Page | null = null
539+ await checkNavigation (
540+ 'Manual refresh recovers sign-in without focus or visibility changes' ,
541+ async ( ) => {
542+ login = await openPage ( )
543+ await login . goto ( `${ base . origin } /login` )
544+ const recovery = await openPanel ( )
545+ try {
546+ const signedOutSession = recovery . waitForResponse (
547+ ( response ) => new URL ( response . url ( ) ) . pathname === '/api/auth/get-session'
548+ )
549+ await recovery . goto ( `chrome-extension://${ extensionId } /sidepanel.html` )
550+ const app = recovery . frames ( ) . find ( ( candidate ) => candidate . url ( ) . startsWith ( base . origin ) )
551+ assert ( app , 'Recovery panel must load the real app' )
552+ await app . getByRole ( 'heading' , { name : 'Sign in to Sim' , exact : true } ) . click ( )
553+ assert . equal ( await ( await signedOutSession ) . json ( ) , null )
554+ await expect
555+ . poll (
556+ ( ) =>
557+ [ ...pendingRequests ] . filter (
558+ ( request ) =>
559+ request . frame ( ) . page ( ) === recovery &&
560+ new URL ( request . url ( ) ) . pathname === '/api/auth/get-session'
561+ ) . length
562+ )
563+ . toBe ( 0 )
564+ const events = await app . evaluateHandle ( ( ) => {
565+ let focus = 0
566+ let visibility = 0
567+ const focused = ( ) => focus ++
568+ const visible = ( ) => visibility ++
569+ window . addEventListener ( 'focus' , focused )
570+ document . addEventListener ( 'visibilitychange' , visible )
571+ return {
572+ snapshot : ( ) => ( {
573+ focus,
574+ visibility,
575+ focused : document . hasFocus ( ) ,
576+ visibilityState : document . visibilityState ,
577+ } ) ,
578+ dispose : ( ) => {
579+ window . removeEventListener ( 'focus' , focused )
580+ document . removeEventListener ( 'visibilitychange' , visible )
581+ } ,
582+ }
583+ } )
584+ try {
585+ await signInAndSeed ( )
586+ const beforeRefresh = await events . evaluate ( ( observer ) => observer . snapshot ( ) )
587+ signInRecoveryReceipts . push ( { phase : 'before-refresh' , ...beforeRefresh } )
588+ assert . deepEqual ( beforeRefresh , {
589+ focus : 0 ,
590+ visibility : 0 ,
591+ focused : true ,
592+ visibilityState : 'visible' ,
593+ } )
594+ await expect (
595+ app . getByRole ( 'heading' , { name : 'Sign in to Sim' , exact : true } )
596+ ) . toBeVisible ( )
597+ await screenshot ( 'sign-in-manual-refresh' , recovery )
598+ const [ response ] = await Promise . all ( [
599+ app . waitForNavigation ( { waitUntil : 'load' } ) ,
600+ app . getByRole ( 'button' , { name : 'Refresh' , exact : true } ) . click ( ) ,
601+ ] )
602+ assert ( response , 'Refresh must return a document response' )
603+ assert . equal ( response . status ( ) , 200 )
604+ assert ( response . request ( ) . isNavigationRequest ( ) , 'Refresh must reload the app document' )
605+ await expect (
606+ app . getByRole ( 'link' , { name : 'Extension QA alpha' , exact : true } )
607+ ) . toBeVisible ( )
608+ signInRecoveryReceipts . push ( { phase : 'recovered' , documentStatus : response . status ( ) } )
609+ await screenshot ( 'sign-in-manual-recovered' , recovery )
610+ } finally {
611+ await events . evaluate ( ( observer ) => observer . dispose ( ) ) . catch ( ( ) => { } )
612+ await events . dispose ( )
613+ }
614+ } finally {
615+ await recovery . close ( )
616+ }
617+ }
618+ )
537619 await checkNavigation ( 'A real Better Auth session reaches the extension iframe' , async ( ) => {
538- const login = await openPage ( )
539- await login . goto ( `${ base . origin } /login` )
540- await signInAndSeed ( )
620+ assert ( login , 'The sign-in tab must remain open until returning to the original panel' )
541621 await login . close ( )
542622 await shell . bringToFront ( )
543623 await expect (
@@ -3343,6 +3423,7 @@ try {
33433423 screenshots,
33443424 browserErrors,
33453425 voiceDiagnostics,
3426+ signInRecoveryReceipts,
33463427 failedRequests,
33473428 pendingRequests : pendingAtFailure ,
33483429 failureState,
0 commit comments