From 625273c2c0c7a3407c4b3648793b04a2c0e5055d Mon Sep 17 00:00:00 2001 From: Simon Knott Date: Tue, 4 Feb 2025 08:36:05 +0100 Subject: [PATCH] make key optional --- .../playwright-core/src/protocol/validator.ts | 4 +- .../src/server/browserContext.ts | 13 ++-- packages/protocol/src/channels.d.ts | 4 +- packages/protocol/src/protocol.yml | 4 +- .../browsercontext-storage-state.spec.ts | 61 ++++++++++++++++++- 5 files changed, 74 insertions(+), 12 deletions(-) diff --git a/packages/playwright-core/src/protocol/validator.ts b/packages/playwright-core/src/protocol/validator.ts index 00b10cccd5..7fee80e9f4 100644 --- a/packages/playwright-core/src/protocol/validator.ts +++ b/packages/playwright-core/src/protocol/validator.ts @@ -148,9 +148,9 @@ scheme.IndexedDBDatabase = tObject({ stores: tArray(tObject({ name: tString, autoIncrement: tBoolean, - keyPath: tArray(tString), + keyPath: tOptional(tArray(tString)), records: tArray(tObject({ - key: tString, + key: tOptional(tString), value: tString, })), indexes: tArray(tObject({ diff --git a/packages/playwright-core/src/server/browserContext.ts b/packages/playwright-core/src/server/browserContext.ts index 7fb32db72c..addb503cfb 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.toString(), + key: objectStore.keyPath === null ? key.toString() : undefined, value: JSON.stringify(record) }; })); @@ -569,7 +569,7 @@ export abstract class BrowserContext extends SdkObject { records: records.filter(Boolean), indexes, autoIncrement: objectStore.autoIncrement, - keyPath: Array.isArray(objectStore.keyPath) ? objectStore.keyPath : [objectStore.keyPath], + keyPath: objectStore.keyPath === null ? undefined : (Array.isArray(objectStore.keyPath) ? objectStore.keyPath : [objectStore.keyPath]), }; })); @@ -685,7 +685,7 @@ export abstract class BrowserContext extends SdkObject { localStorage.setItem(name, value); await Promise.all((originState.indexedDB || []).map(async dbInfo => { - await new Promise((resolve, reject) => { + await new Promise((resolve, reject) => { const openRequest = indexedDB.open(dbInfo.name, dbInfo.version); openRequest.addEventListener('upgradeneeded', () => { const db = openRequest.result; @@ -698,7 +698,7 @@ export abstract class BrowserContext extends SdkObject { openRequest.addEventListener('success', async () => { const db = openRequest.result; const transaction = db.transaction(db.objectStoreNames, 'readwrite'); - Promise.all(dbInfo.stores.flatMap(store => { + await 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( @@ -708,7 +708,10 @@ export abstract class BrowserContext extends SdkObject { request.addEventListener('success', resolve); request.addEventListener('error', reject); })); - })).then(resolve, reject); + })); + transaction.commit(); + transaction.addEventListener('complete', () => resolve()); + transaction.addEventListener('error', () => reject(transaction.error)); }); }); })); diff --git a/packages/protocol/src/channels.d.ts b/packages/protocol/src/channels.d.ts index bfec4dac0e..a05b4d37e7 100644 --- a/packages/protocol/src/channels.d.ts +++ b/packages/protocol/src/channels.d.ts @@ -277,9 +277,9 @@ export type IndexedDBDatabase = { stores: { name: string, autoIncrement: boolean, - keyPath: string[], + keyPath?: string[], records: { - key: string, + key?: string, value: string, }[], indexes: { diff --git a/packages/protocol/src/protocol.yml b/packages/protocol/src/protocol.yml index b189d7d144..ca92d2474e 100644 --- a/packages/protocol/src/protocol.yml +++ b/packages/protocol/src/protocol.yml @@ -235,14 +235,14 @@ IndexedDBDatabase: name: string autoIncrement: boolean keyPath: - type: array + type: array? items: string records: type: array items: type: object properties: - key: string + key: string? value: string indexes: type: array diff --git a/tests/library/browsercontext-storage-state.spec.ts b/tests/library/browsercontext-storage-state.spec.ts index 146c6035b8..8588ca2a28 100644 --- a/tests/library/browsercontext-storage-state.spec.ts +++ b/tests/library/browsercontext-storage-state.spec.ts @@ -340,7 +340,6 @@ it('should support IndexedDB', async ({ page, contextFactory }) => { keyPath: ['taskTitle'], records: [ { - key: 'Pet the cat', value: JSON.stringify({ taskTitle: 'Pet the cat', hours: '1', @@ -408,3 +407,63 @@ it('should support IndexedDB', async ({ page, contextFactory }) => { - text: /Pet the cat/ `); }); + +it('indexedDb firebase acceptance test', async ({ page, contextFactory }) => { + await page.goto('https://fir-ui-demo-84a6c.firebaseapp.com/'); + await page.getByText('Continue as guest').click(); + await expect(page.locator('#user-info')).toMatchAriaSnapshot(` + - text: New User + `); + await page.close(); + const storageState = await page.context().storageState(); + expect(storageState).toEqual({ + 'cookies': [], + 'origins': [ + { + 'indexedDB': [ + { + 'name': 'firebase-heartbeat-database', + 'stores': [ + { + 'autoIncrement': false, + 'indexes': [], + 'name': 'firebase-heartbeat-store', + 'records': [], + }, + ], + 'version': 1, + }, + { + 'name': 'firebaseLocalStorageDb', + 'stores': [ + { + 'autoIncrement': false, + 'indexes': [], + 'keyPath': [ + 'fbase_key', + ], + 'name': 'firebaseLocalStorage', + 'records': [ + { + 'value': expect.any(String), + }, + ], + }, + ], + 'version': 1, + }, + ], + 'localStorage': [], + 'origin': 'https://fir-ui-demo-84a6c.firebaseapp.com', + }, + ], + }); + + const recreatedContext = await contextFactory({ storageState }); + const recreatedPage = await recreatedContext.newPage(); + await recreatedPage.goto('https://fir-ui-demo-84a6c.firebaseapp.com/'); + expect(await recreatedContext.storageState()).toEqual(storageState); + await expect(recreatedPage.locator('body')).toMatchAriaSnapshot(` + - text: New User + `); +});