@@ -43,6 +43,7 @@ import type { Artifact } from './artifact';
4343import { Clock } from './clock' ;
4444import type { ClientCertificatesProxy } from './socksClientCertificatesInterceptor' ;
4545import { RecorderApp } from './recorder/recorderApp' ;
46+ import * as utilitySerializers from './isomorphic/utilityScriptSerializers' ;
4647
4748export abstract class BrowserContext extends SdkObject {
4849 static Events = {
@@ -550,7 +551,7 @@ export abstract class BrowserContext extends SdkObject {
550551
551552 return {
552553 key : objectStore . keyPath === null ? key . toString ( ) : undefined ,
553- value : JSON . stringify ( record )
554+ value : record
554555 } ;
555556 } ) ) ;
556557
@@ -590,13 +591,24 @@ export abstract class BrowserContext extends SdkObject {
590591 } ;
591592 }
592593
594+ function serializeRecords ( indexedDBs : channels . IndexedDBDatabase [ ] ) {
595+ for ( const db of indexedDBs ) {
596+ for ( const store of db . stores ) {
597+ for ( const record of store . records )
598+ record . value = JSON . stringify ( utilitySerializers . serializeAsCallArgument ( record . value , v => ( { fallThrough : v } ) ) ) ;
599+ }
600+ }
601+ }
602+
593603 // First try collecting storage stage from existing pages.
594604 for ( const page of this . pages ( ) ) {
595605 const origin = page . mainFrame ( ) . origin ( ) ;
596606 if ( ! origin || ! originsToSave . has ( origin ) )
597607 continue ;
598608 try {
599609 const storage = await page . mainFrame ( ) . nonStallingEvaluateInExistingContext ( `(${ _collectStorageScript . toString ( ) } )()` , 'utility' ) ;
610+ if ( storage . indexedDB ?. length )
611+ serializeRecords ( storage . indexedDB ) ;
600612 if ( storage . localStorage . length || storage . indexedDB ?. length )
601613 result . origins . push ( { origin, localStorage : storage . localStorage , indexedDB : storage . indexedDB } as channels . OriginStorage ) ;
602614 originsToSave . delete ( origin ) ;
@@ -617,6 +629,8 @@ export abstract class BrowserContext extends SdkObject {
617629 const frame = page . mainFrame ( ) ;
618630 await frame . goto ( internalMetadata , origin ) ;
619631 const storage = await frame . evaluateExpression ( `(${ _collectStorageScript . toString ( ) } )()` , { world : 'utility' } ) ;
632+ if ( storage . indexedDB ?. length )
633+ serializeRecords ( storage . indexedDB ) ;
620634 if ( storage . localStorage . length || storage . indexedDB ?. length )
621635 result . origins . push ( { origin, localStorage : storage . localStorage , indexedDB : storage . indexedDB } as channels . OriginStorage ) ;
622636 }
@@ -682,6 +696,13 @@ export abstract class BrowserContext extends SdkObject {
682696 const frame = page . mainFrame ( ) ;
683697 await frame . goto ( metadata , originState . origin ) ;
684698
699+ for ( const dbInfo of ( originState . indexedDB || [ ] ) ) {
700+ for ( const store of dbInfo . stores ) {
701+ for ( const record of store . records )
702+ record . value = utilitySerializers . parseEvaluationResultValue ( JSON . parse ( record . value ) ) ;
703+ }
704+ }
705+
685706 async function _restoreStorageState ( originState : channels . OriginStorage ) {
686707 for ( const { name, value } of ( originState . localStorage || [ ] ) )
687708 localStorage . setItem ( name , value ) ;
@@ -704,7 +725,7 @@ export abstract class BrowserContext extends SdkObject {
704725 const objectStore = transaction . objectStore ( store . name ) ;
705726 return store . records . map ( record => new Promise ( ( resolve , reject ) => {
706727 const request = objectStore . add (
707- JSON . parse ( record . value ) , // TODO: use better serialization
728+ record . value as any , // protocol says string, but this got deserialized above
708729 objectStore . keyPath === null ? record . key : undefined
709730 ) ;
710731 request . addEventListener ( 'success' , resolve ) ;
0 commit comments