recreate idb

This commit is contained in:
Simon Knott 2025-02-03 12:50:49 +01:00
parent e596207f99
commit a8ad8eff37
No known key found for this signature in database
GPG key ID: 8CEDC00028084AEC
5 changed files with 44 additions and 6 deletions

View file

@ -144,6 +144,7 @@ scheme.NameValue = tObject({
}); });
scheme.IndexedDBDatabase = tObject({ scheme.IndexedDBDatabase = tObject({
name: tString, name: tString,
version: tNumber,
stores: tArray(tObject({ stores: tArray(tObject({
name: tString, name: tString,
autoIncrement: tBoolean, autoIncrement: tBoolean,

View file

@ -549,7 +549,7 @@ export abstract class BrowserContext extends SdkObject {
return; return;
return { return {
key, key: key.toString(),
value: JSON.stringify(record) value: JSON.stringify(record)
}; };
})); }));
@ -679,11 +679,42 @@ export abstract class BrowserContext extends SdkObject {
for (const originState of state.origins) { for (const originState of state.origins) {
const frame = page.mainFrame(); const frame = page.mainFrame();
await frame.goto(metadata, originState.origin); await frame.goto(metadata, originState.origin);
await frame.evaluateExpression(`
originState => { async function _restoreStorageState(originState: channels.OriginStorage) {
for (const { name, value } of (originState.localStorage || [])) for (const { name, value } of (originState.localStorage || []))
localStorage.setItem(name, value); localStorage.setItem(name, value);
}`, { isFunction: true, world: 'utility' }, originState);
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); await page.close(internalMetadata);
} }

View file

@ -273,6 +273,7 @@ export type NameValue = {
export type IndexedDBDatabase = { export type IndexedDBDatabase = {
name: string, name: string,
version: number,
stores: { stores: {
name: string, name: string,
autoIncrement: boolean, autoIncrement: boolean,

View file

@ -226,6 +226,7 @@ IndexedDBDatabase:
type: object type: object
properties: properties:
name: string name: string
version: number
stores: stores:
type: array type: array
items: items:

View file

@ -332,6 +332,7 @@ it('should support IndexedDB', async ({ page, contextFactory }) => {
indexedDB: [ indexedDB: [
{ {
name: 'toDoList', name: 'toDoList',
version: 4,
stores: [ stores: [
{ {
name: 'toDoList', name: 'toDoList',
@ -395,4 +396,7 @@ it('should support IndexedDB', async ({ page, contextFactory }) => {
] ]
} }
]); ]);
const context = await contextFactory({ storageState });
expect(await context.storageState()).toEqual(storageState);
}); });