From a8ad8eff3757d51e531eda9fe4727cd05c783e2d Mon Sep 17 00:00:00 2001 From: Simon Knott Date: Mon, 3 Feb 2025 12:50:49 +0100 Subject: [PATCH] recreate idb --- .../playwright-core/src/protocol/validator.ts | 1 + .../src/server/browserContext.ts | 43 ++++++++++++++++--- packages/protocol/src/channels.d.ts | 1 + packages/protocol/src/protocol.yml | 1 + .../browsercontext-storage-state.spec.ts | 4 ++ 5 files changed, 44 insertions(+), 6 deletions(-) diff --git a/packages/playwright-core/src/protocol/validator.ts b/packages/playwright-core/src/protocol/validator.ts index 0eff23f3fc..00b10cccd5 100644 --- a/packages/playwright-core/src/protocol/validator.ts +++ b/packages/playwright-core/src/protocol/validator.ts @@ -144,6 +144,7 @@ scheme.NameValue = tObject({ }); scheme.IndexedDBDatabase = tObject({ name: tString, + version: tNumber, stores: tArray(tObject({ name: tString, autoIncrement: tBoolean, diff --git a/packages/playwright-core/src/server/browserContext.ts b/packages/playwright-core/src/server/browserContext.ts index 17a802dbff..7fb32db72c 100644 --- a/packages/playwright-core/src/server/browserContext.ts +++ b/packages/playwright-core/src/server/browserContext.ts @@ -549,7 +549,7 @@ export abstract class BrowserContext extends SdkObject { return; return { - key, + key: key.toString(), value: JSON.stringify(record) }; })); @@ -679,11 +679,42 @@ export abstract class BrowserContext extends SdkObject { for (const originState of state.origins) { const frame = page.mainFrame(); await frame.goto(metadata, originState.origin); - await frame.evaluateExpression(` - originState => { - for (const { name, value } of (originState.localStorage || [])) - localStorage.setItem(name, value); - }`, { isFunction: true, world: 'utility' }, originState); + + async function _restoreStorageState(originState: channels.OriginStorage) { + for (const { name, value } of (originState.localStorage || [])) + localStorage.setItem(name, value); + + await Promise.all((originState.indexedDB || []).map(async dbInfo => { + await new Promise((resolve, reject) => { + const openRequest = indexedDB.open(dbInfo.name, dbInfo.version); + openRequest.addEventListener('upgradeneeded', () => { + const db = openRequest.result; + for (const store of dbInfo.stores) { + const objectStore = db.createObjectStore(store.name, { autoIncrement: store.autoIncrement, keyPath: store.keyPath }); + for (const index of store.indexes) + objectStore.createIndex(index.name, index.keyPath, { unique: index.unique, multiEntry: index.multiEntry }); + } + }); + openRequest.addEventListener('success', async () => { + const db = openRequest.result; + const transaction = db.transaction(db.objectStoreNames, 'readwrite'); + Promise.all(dbInfo.stores.flatMap(store => { + const objectStore = transaction.objectStore(store.name); + return store.records.map(record => new Promise((resolve, reject) => { + const request = objectStore.add( + JSON.parse(record.value), + objectStore.keyPath === null ? record.key : undefined + ); + request.addEventListener('success', resolve); + request.addEventListener('error', reject); + })); + })).then(resolve, reject); + }); + }); + })); + } + + await frame.evaluateExpression(_restoreStorageState.toString(), { isFunction: true, world: 'utility' }, originState); } await page.close(internalMetadata); } diff --git a/packages/protocol/src/channels.d.ts b/packages/protocol/src/channels.d.ts index bc43db1165..bfec4dac0e 100644 --- a/packages/protocol/src/channels.d.ts +++ b/packages/protocol/src/channels.d.ts @@ -273,6 +273,7 @@ export type NameValue = { export type IndexedDBDatabase = { name: string, + version: number, stores: { name: string, autoIncrement: boolean, diff --git a/packages/protocol/src/protocol.yml b/packages/protocol/src/protocol.yml index 99e126dff6..b189d7d144 100644 --- a/packages/protocol/src/protocol.yml +++ b/packages/protocol/src/protocol.yml @@ -226,6 +226,7 @@ IndexedDBDatabase: type: object properties: name: string + version: number stores: type: array items: diff --git a/tests/library/browsercontext-storage-state.spec.ts b/tests/library/browsercontext-storage-state.spec.ts index e9e7443558..e923bb9f7e 100644 --- a/tests/library/browsercontext-storage-state.spec.ts +++ b/tests/library/browsercontext-storage-state.spec.ts @@ -332,6 +332,7 @@ it('should support IndexedDB', async ({ page, contextFactory }) => { indexedDB: [ { name: 'toDoList', + version: 4, stores: [ { name: 'toDoList', @@ -395,4 +396,7 @@ it('should support IndexedDB', async ({ page, contextFactory }) => { ] } ]); + + const context = await contextFactory({ storageState }); + expect(await context.storageState()).toEqual(storageState); });