From e9276b571da15eaa4f1e47d1dd521e4009a3a80e Mon Sep 17 00:00:00 2001 From: Simon Knott Date: Tue, 4 Feb 2025 09:45:48 +0100 Subject: [PATCH] keyPath string/array matters --- .../playwright-core/src/protocol/validator.ts | 4 +-- .../src/server/browserContext.ts | 9 +++---- packages/protocol/src/channels.d.ts | 4 +-- packages/protocol/src/protocol.yml | 8 ++---- .../browsercontext-storage-state.spec.ts | 26 +++++++------------ 5 files changed, 20 insertions(+), 31 deletions(-) diff --git a/packages/playwright-core/src/protocol/validator.ts b/packages/playwright-core/src/protocol/validator.ts index 7fee80e9f4..e6d8ccd18e 100644 --- a/packages/playwright-core/src/protocol/validator.ts +++ b/packages/playwright-core/src/protocol/validator.ts @@ -148,14 +148,14 @@ scheme.IndexedDBDatabase = tObject({ stores: tArray(tObject({ name: tString, autoIncrement: tBoolean, - keyPath: tOptional(tArray(tString)), + keyPath: tOptional(tString), records: tArray(tObject({ key: tOptional(tString), value: tString, })), indexes: tArray(tObject({ name: tString, - keyPath: tArray(tString), + keyPath: tString, multiEntry: tBoolean, unique: tBoolean, })), diff --git a/packages/playwright-core/src/server/browserContext.ts b/packages/playwright-core/src/server/browserContext.ts index addb503cfb..e376460df4 100644 --- a/packages/playwright-core/src/server/browserContext.ts +++ b/packages/playwright-core/src/server/browserContext.ts @@ -558,7 +558,7 @@ export abstract class BrowserContext extends SdkObject { const index = objectStore.index(indexName); return { name: index.name, - keyPath: Array.isArray(index.keyPath) ? index.keyPath : [index.keyPath], + keyPath: JSON.stringify(index.keyPath), multiEntry: index.multiEntry, unique: index.unique, }; @@ -569,7 +569,7 @@ export abstract class BrowserContext extends SdkObject { records: records.filter(Boolean), indexes, autoIncrement: objectStore.autoIncrement, - keyPath: objectStore.keyPath === null ? undefined : (Array.isArray(objectStore.keyPath) ? objectStore.keyPath : [objectStore.keyPath]), + keyPath: objectStore.keyPath === null ? undefined : JSON.stringify(objectStore.keyPath), }; })); @@ -690,9 +690,9 @@ export abstract class BrowserContext extends SdkObject { 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 }); + const objectStore = db.createObjectStore(store.name, { autoIncrement: store.autoIncrement, keyPath: store.keyPath ? JSON.parse(store.keyPath) : undefined }); for (const index of store.indexes) - objectStore.createIndex(index.name, index.keyPath, { unique: index.unique, multiEntry: index.multiEntry }); + objectStore.createIndex(index.name, JSON.parse(index.keyPath), { unique: index.unique, multiEntry: index.multiEntry }); } }); openRequest.addEventListener('success', async () => { @@ -709,7 +709,6 @@ export abstract class BrowserContext extends SdkObject { request.addEventListener('error', 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 a05b4d37e7..600e64cb97 100644 --- a/packages/protocol/src/channels.d.ts +++ b/packages/protocol/src/channels.d.ts @@ -277,14 +277,14 @@ export type IndexedDBDatabase = { stores: { name: string, autoIncrement: boolean, - keyPath?: string[], + keyPath?: string, records: { key?: string, value: string, }[], indexes: { name: string, - keyPath: string[], + keyPath: string, multiEntry: boolean, unique: boolean, }[], diff --git a/packages/protocol/src/protocol.yml b/packages/protocol/src/protocol.yml index ca92d2474e..29ea1bb4c3 100644 --- a/packages/protocol/src/protocol.yml +++ b/packages/protocol/src/protocol.yml @@ -234,9 +234,7 @@ IndexedDBDatabase: properties: name: string autoIncrement: boolean - keyPath: - type: array? - items: string + keyPath: string? # JSON of string | string[] records: type: array items: @@ -250,9 +248,7 @@ IndexedDBDatabase: type: object properties: name: string - keyPath: - type: array - items: string + keyPath: string # JSON of string | string[] multiEntry: boolean unique: boolean diff --git a/tests/library/browsercontext-storage-state.spec.ts b/tests/library/browsercontext-storage-state.spec.ts index 8588ca2a28..eb3c9d9f7f 100644 --- a/tests/library/browsercontext-storage-state.spec.ts +++ b/tests/library/browsercontext-storage-state.spec.ts @@ -337,7 +337,7 @@ it('should support IndexedDB', async ({ page, contextFactory }) => { { name: 'toDoList', autoIncrement: false, - keyPath: ['taskTitle'], + keyPath: '"taskTitle"', records: [ { value: JSON.stringify({ @@ -354,37 +354,37 @@ it('should support IndexedDB', async ({ page, contextFactory }) => { indexes: [ { 'name': 'day', - 'keyPath': ['day'], + 'keyPath': '"day"', 'multiEntry': false, 'unique': false, }, { 'name': 'hours', - 'keyPath': ['hours'], + 'keyPath': '"hours"', 'multiEntry': false, 'unique': false, }, { 'name': 'minutes', - 'keyPath': ['minutes'], + 'keyPath': '"minutes"', 'multiEntry': false, 'unique': false, }, { 'name': 'month', - 'keyPath': ['month'], + 'keyPath': '"month"', 'multiEntry': false, 'unique': false, }, { 'name': 'notified', - 'keyPath': ['notified'], + 'keyPath': '"notified"', 'multiEntry': false, 'unique': false, }, { 'name': 'year', - 'keyPath': ['year'], + 'keyPath': '"year"', 'multiEntry': false, 'unique': false, }, @@ -411,9 +411,7 @@ it('should support IndexedDB', async ({ page, contextFactory }) => { 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 expect(page.getByRole('button', { name: 'Sign Out' })).toBeVisible(); await page.close(); const storageState = await page.context().storageState(); expect(storageState).toEqual({ @@ -439,9 +437,7 @@ it('indexedDb firebase acceptance test', async ({ page, contextFactory }) => { { 'autoIncrement': false, 'indexes': [], - 'keyPath': [ - 'fbase_key', - ], + 'keyPath': '"fbase_key"', 'name': 'firebaseLocalStorage', 'records': [ { @@ -462,8 +458,6 @@ it('indexedDb firebase acceptance test', async ({ page, contextFactory }) => { const recreatedContext = await contextFactory({ storageState }); const recreatedPage = await recreatedContext.newPage(); await recreatedPage.goto('https://fir-ui-demo-84a6c.firebaseapp.com/'); + await expect(recreatedPage.getByRole('button', { name: 'Sign Out' })).toBeVisible(); expect(await recreatedContext.storageState()).toEqual(storageState); - await expect(recreatedPage.locator('body')).toMatchAriaSnapshot(` - - text: New User - `); });