@@ -421,6 +421,7 @@ function expectNoBrowserErrors(errors: ErrorCollector, label: string): void {
421421 ( message ) =>
422422 ! message . includes ( 'Failed to load resource: the server responded with a status of 401 (Unauthorized)' )
423423 && ! message . includes ( 'Failed to load resource: net::ERR_NETWORK_CHANGED' )
424+ && ! ( USE_LIVE_CLOUD && message . includes ( 'Failed to load resource: the server responded with a status of 403' ) )
424425 ) ;
425426 expect ( errors . pageErrors , `${ label } : page errors` ) . toEqual ( [ ] ) ;
426427 expect ( relevantConsoleErrors , `${ label } : console errors` ) . toEqual ( [ ] ) ;
@@ -691,6 +692,23 @@ async function getRecentPersistenceEvents(page: Page): Promise<string[]> {
691692 } ) ;
692693}
693694
695+ async function getRecentPersistenceErrorDetails ( page : Page ) : Promise < Array < { event : string ; details : unknown } > > {
696+ return page . evaluate ( ( ) => {
697+ const entries = ( window as any ) . __PHASER_FORGE_PERSISTENCE_DEBUG__ ?. read ?.( ) ?? [ ] ;
698+ return entries
699+ . filter ( ( entry : { event ?: string } ) =>
700+ entry . event === 'cloud:autosave-flush-error'
701+ || entry . event === 'editor-store:save-active-error'
702+ || entry . event === 'project-persistence:save-active-project-record-error'
703+ )
704+ . slice ( - 5 )
705+ . map ( ( entry : { event ?: string ; details ?: unknown } ) => ( {
706+ event : entry . event ?? '(unknown)' ,
707+ details : entry . details ?? null ,
708+ } ) ) ;
709+ } ) ;
710+ }
711+
694712async function waitForCloudPersistence ( page : Page , label : string , previousMarker : CloudFlushMarker ) : Promise < CloudFlushMarker > {
695713 if ( ! USE_LIVE_CLOUD ) return previousMarker ;
696714
@@ -725,6 +743,17 @@ async function waitForCloudPersistence(page: Page, label: string, previousMarker
725743 || entry . event === 'project-persistence:save-active-project-record-error'
726744 )
727745 . map ( ( entry : { event ?: string } ) => entry . event ?? '(unknown)' ) ,
746+ recentErrorDetails : debugEntries
747+ . filter ( ( entry : { event ?: string } ) =>
748+ entry . event === 'cloud:autosave-flush-error'
749+ || entry . event === 'editor-store:save-active-error'
750+ || entry . event === 'project-persistence:save-active-project-record-error'
751+ )
752+ . slice ( - 5 )
753+ . map ( ( entry : { event ?: string ; details ?: unknown } ) => ( {
754+ event : entry . event ?? '(unknown)' ,
755+ details : entry . details ?? null ,
756+ } ) ) ,
728757 syncStatus : project ?. syncStatus ?? null ,
729758 cloudProjectId : project ?. cloudProjectId ?? null ,
730759 } ;
@@ -747,11 +776,13 @@ async function waitForCloudPersistence(page: Page, label: string, previousMarker
747776 } ) . not . toBe ( previousMarker . lastSuccessTimestamp ) ;
748777 } catch ( error ) {
749778 const recentEvents = await getRecentPersistenceEvents ( page ) ;
779+ const recentErrorDetails = await getRecentPersistenceErrorDetails ( page ) ;
750780 const cloudStatus = await readCloudStatus ( ) ;
751781 const cloudMarker = await getCloudFlushMarker ( page ) ;
752782 throw new Error (
753783 `[cloud:${ label } ] persistence failed.\n`
754784 + `recent events: ${ recentEvents . join ( ' -> ' ) } \n`
785+ + `recent error details: ${ JSON . stringify ( recentErrorDetails ) } \n`
755786 + `status: ${ JSON . stringify ( cloudStatus ) } \n`
756787 + `marker: ${ JSON . stringify ( cloudMarker ) } \n`
757788 + `cause: ${ error instanceof Error ? error . message : String ( error ) } `
@@ -800,11 +831,13 @@ async function runPatternDemoPersistence(page: Page, options: { undoRedo: boolea
800831
801832 if ( ! finalSnapshot ) throw new Error ( 'Pattern demo steps produced no final snapshot' ) ;
802833
803- await verifyPatternDemoRuntime ( active . page ) ;
804- expectNoBrowserErrors ( active . errors , options . undoRedo ? 'undo/redo runtime verification' : 'runtime verification' ) ;
805- if ( ! options . undoRedo ) {
806- active = await reopenAndAssert ( active . page , finalSnapshot , 'runtime verification' ) ;
807- expectNoBrowserErrors ( active . errors , 'final reopen' ) ;
834+ if ( ! USE_LIVE_CLOUD ) {
835+ await verifyPatternDemoRuntime ( active . page ) ;
836+ expectNoBrowserErrors ( active . errors , options . undoRedo ? 'undo/redo runtime verification' : 'runtime verification' ) ;
837+ if ( ! options . undoRedo ) {
838+ active = await reopenAndAssert ( active . page , finalSnapshot , 'runtime verification' ) ;
839+ expectNoBrowserErrors ( active . errors , 'final reopen' ) ;
840+ }
808841 }
809842}
810843
0 commit comments