Skip to content

Commit e26bd2a

Browse files
committed
use proper ser/de
1 parent 3dddfd1 commit e26bd2a

File tree

2 files changed

+33
-9
lines changed

2 files changed

+33
-9
lines changed

packages/playwright-core/src/server/browserContext.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import type { Artifact } from './artifact';
4343
import { Clock } from './clock';
4444
import type { ClientCertificatesProxy } from './socksClientCertificatesInterceptor';
4545
import { RecorderApp } from './recorder/recorderApp';
46+
import * as utilitySerializers from './isomorphic/utilityScriptSerializers';
4647

4748
export 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);

tests/library/browsercontext-storage-state.spec.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -341,13 +341,16 @@ it('should support IndexedDB', async ({ page, contextFactory }) => {
341341
records: [
342342
{
343343
value: JSON.stringify({
344-
taskTitle: 'Pet the cat',
345-
hours: '1',
346-
minutes: '1',
347-
day: '01',
348-
month: 'January',
349-
year: '2025',
350-
notified: 'no',
344+
o: [
345+
{ k: 'taskTitle', v: 'Pet the cat' },
346+
{ k: 'hours', v: '1' },
347+
{ k: 'minutes', v: '1' },
348+
{ k: 'day', v: '01' },
349+
{ k: 'month', v: 'January' },
350+
{ k: 'year', v: '2025' },
351+
{ k: 'notified', v: 'no' }
352+
],
353+
id: 1
351354
}),
352355
},
353356
],

0 commit comments

Comments
 (0)