fix: allow opt out from `IndexedDB` in storagestate (#34650)
This commit is contained in:
parent
8d751cfe50
commit
902e83fe87
|
@ -909,3 +909,9 @@ Returns storage state for this request context, contains current cookies and loc
|
||||||
|
|
||||||
### option: APIRequestContext.storageState.path = %%-storagestate-option-path-%%
|
### option: APIRequestContext.storageState.path = %%-storagestate-option-path-%%
|
||||||
* since: v1.16
|
* since: v1.16
|
||||||
|
|
||||||
|
### option: APIRequestContext.storageState.indexedDB
|
||||||
|
* since: v1.51
|
||||||
|
- `indexedDB` ?<boolean>
|
||||||
|
|
||||||
|
Defaults to `true`. Set to `false` to omit IndexedDB from snapshot.
|
||||||
|
|
|
@ -1545,6 +1545,12 @@ IndexedDBs with typed arrays are currently not supported.
|
||||||
### option: BrowserContext.storageState.path = %%-storagestate-option-path-%%
|
### option: BrowserContext.storageState.path = %%-storagestate-option-path-%%
|
||||||
* since: v1.8
|
* since: v1.8
|
||||||
|
|
||||||
|
### option: BrowserContext.storageState.indexedDB
|
||||||
|
* since: v1.51
|
||||||
|
- `indexedDB` ?<boolean>
|
||||||
|
|
||||||
|
Defaults to `true`. Set to `false` to omit IndexedDB from snapshot.
|
||||||
|
|
||||||
## property: BrowserContext.tracing
|
## property: BrowserContext.tracing
|
||||||
* since: v1.12
|
* since: v1.12
|
||||||
- type: <[Tracing]>
|
- type: <[Tracing]>
|
||||||
|
|
|
@ -425,8 +425,8 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel>
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async storageState(options: { path?: string } = {}): Promise<StorageState> {
|
async storageState(options: { path?: string, indexedDB?: boolean } = {}): Promise<StorageState> {
|
||||||
const state = await this._channel.storageState();
|
const state = await this._channel.storageState({ indexedDB: options.indexedDB });
|
||||||
if (options.path) {
|
if (options.path) {
|
||||||
await mkdirIfNeeded(options.path);
|
await mkdirIfNeeded(options.path);
|
||||||
await fs.promises.writeFile(options.path, JSON.stringify(state, undefined, 2), 'utf8');
|
await fs.promises.writeFile(options.path, JSON.stringify(state, undefined, 2), 'utf8');
|
||||||
|
|
|
@ -260,8 +260,8 @@ export class APIRequestContext extends ChannelOwner<channels.APIRequestContextCh
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async storageState(options: { path?: string } = {}): Promise<StorageState> {
|
async storageState(options: { path?: string, indexedDB?: boolean } = {}): Promise<StorageState> {
|
||||||
const state = await this._channel.storageState();
|
const state = await this._channel.storageState({ indexedDB: options.indexedDB });
|
||||||
if (options.path) {
|
if (options.path) {
|
||||||
await mkdirIfNeeded(options.path);
|
await mkdirIfNeeded(options.path);
|
||||||
await fs.promises.writeFile(options.path, JSON.stringify(state, undefined, 2), 'utf8');
|
await fs.promises.writeFile(options.path, JSON.stringify(state, undefined, 2), 'utf8');
|
||||||
|
|
|
@ -234,7 +234,9 @@ scheme.APIRequestContextFetchLogParams = tObject({
|
||||||
scheme.APIRequestContextFetchLogResult = tObject({
|
scheme.APIRequestContextFetchLogResult = tObject({
|
||||||
log: tArray(tString),
|
log: tArray(tString),
|
||||||
});
|
});
|
||||||
scheme.APIRequestContextStorageStateParams = tOptional(tObject({}));
|
scheme.APIRequestContextStorageStateParams = tObject({
|
||||||
|
indexedDB: tOptional(tBoolean),
|
||||||
|
});
|
||||||
scheme.APIRequestContextStorageStateResult = tObject({
|
scheme.APIRequestContextStorageStateResult = tObject({
|
||||||
cookies: tArray(tType('NetworkCookie')),
|
cookies: tArray(tType('NetworkCookie')),
|
||||||
origins: tArray(tType('OriginStorage')),
|
origins: tArray(tType('OriginStorage')),
|
||||||
|
@ -992,7 +994,9 @@ scheme.BrowserContextSetOfflineParams = tObject({
|
||||||
offline: tBoolean,
|
offline: tBoolean,
|
||||||
});
|
});
|
||||||
scheme.BrowserContextSetOfflineResult = tOptional(tObject({}));
|
scheme.BrowserContextSetOfflineResult = tOptional(tObject({}));
|
||||||
scheme.BrowserContextStorageStateParams = tOptional(tObject({}));
|
scheme.BrowserContextStorageStateParams = tObject({
|
||||||
|
indexedDB: tOptional(tBoolean),
|
||||||
|
});
|
||||||
scheme.BrowserContextStorageStateResult = tObject({
|
scheme.BrowserContextStorageStateResult = tObject({
|
||||||
cookies: tArray(tType('NetworkCookie')),
|
cookies: tArray(tType('NetworkCookie')),
|
||||||
origins: tArray(tType('OriginStorage')),
|
origins: tArray(tType('OriginStorage')),
|
||||||
|
|
|
@ -508,14 +508,14 @@ export abstract class BrowserContext extends SdkObject {
|
||||||
this._origins.add(origin);
|
this._origins.add(origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
async storageState(): Promise<channels.BrowserContextStorageStateResult> {
|
async storageState(indexedDB = true): Promise<channels.BrowserContextStorageStateResult> {
|
||||||
const result: channels.BrowserContextStorageStateResult = {
|
const result: channels.BrowserContextStorageStateResult = {
|
||||||
cookies: await this.cookies(),
|
cookies: await this.cookies(),
|
||||||
origins: []
|
origins: []
|
||||||
};
|
};
|
||||||
const originsToSave = new Set(this._origins);
|
const originsToSave = new Set(this._origins);
|
||||||
|
|
||||||
const collectScript = `(${storageScript.collect})((${utilityScriptSerializers.source})(), ${this._browser.options.name === 'firefox'})`;
|
const collectScript = `(${storageScript.collect})((${utilityScriptSerializers.source})(), ${this._browser.options.name === 'firefox'}, ${indexedDB})`;
|
||||||
|
|
||||||
// First try collecting storage stage from existing pages.
|
// First try collecting storage stage from existing pages.
|
||||||
for (const page of this.pages()) {
|
for (const page of this.pages()) {
|
||||||
|
|
|
@ -291,7 +291,7 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channel
|
||||||
}
|
}
|
||||||
|
|
||||||
async storageState(params: channels.BrowserContextStorageStateParams, metadata: CallMetadata): Promise<channels.BrowserContextStorageStateResult> {
|
async storageState(params: channels.BrowserContextStorageStateParams, metadata: CallMetadata): Promise<channels.BrowserContextStorageStateResult> {
|
||||||
return await this._context.storageState();
|
return await this._context.storageState(params.indexedDB);
|
||||||
}
|
}
|
||||||
|
|
||||||
async close(params: channels.BrowserContextCloseParams, metadata: CallMetadata): Promise<void> {
|
async close(params: channels.BrowserContextCloseParams, metadata: CallMetadata): Promise<void> {
|
||||||
|
|
|
@ -194,8 +194,8 @@ export class APIRequestContextDispatcher extends Dispatcher<APIRequestContext, c
|
||||||
this.adopt(tracing);
|
this.adopt(tracing);
|
||||||
}
|
}
|
||||||
|
|
||||||
async storageState(): Promise<channels.APIRequestContextStorageStateResult> {
|
async storageState(params: channels.APIRequestContextStorageStateParams): Promise<channels.APIRequestContextStorageStateResult> {
|
||||||
return this._object.storageState();
|
return this._object.storageState(params.indexedDB);
|
||||||
}
|
}
|
||||||
|
|
||||||
async dispose(params: channels.APIRequestContextDisposeParams, metadata: CallMetadata): Promise<void> {
|
async dispose(params: channels.APIRequestContextDisposeParams, metadata: CallMetadata): Promise<void> {
|
||||||
|
|
|
@ -133,7 +133,7 @@ export abstract class APIRequestContext extends SdkObject {
|
||||||
abstract _defaultOptions(): FetchRequestOptions;
|
abstract _defaultOptions(): FetchRequestOptions;
|
||||||
abstract _addCookies(cookies: channels.NetworkCookie[]): Promise<void>;
|
abstract _addCookies(cookies: channels.NetworkCookie[]): Promise<void>;
|
||||||
abstract _cookies(url: URL): Promise<channels.NetworkCookie[]>;
|
abstract _cookies(url: URL): Promise<channels.NetworkCookie[]>;
|
||||||
abstract storageState(): Promise<channels.APIRequestContextStorageStateResult>;
|
abstract storageState(indexedDB?: boolean): Promise<channels.APIRequestContextStorageStateResult>;
|
||||||
|
|
||||||
private _storeResponseBody(body: Buffer): string {
|
private _storeResponseBody(body: Buffer): string {
|
||||||
const uid = createGuid();
|
const uid = createGuid();
|
||||||
|
@ -618,8 +618,8 @@ export class BrowserContextAPIRequestContext extends APIRequestContext {
|
||||||
return await this._context.cookies(url.toString());
|
return await this._context.cookies(url.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
override async storageState(): Promise<channels.APIRequestContextStorageStateResult> {
|
override async storageState(indexedDB?: boolean): Promise<channels.APIRequestContextStorageStateResult> {
|
||||||
return this._context.storageState();
|
return this._context.storageState(indexedDB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -684,10 +684,10 @@ export class GlobalAPIRequestContext extends APIRequestContext {
|
||||||
return this._cookieStore.cookies(url);
|
return this._cookieStore.cookies(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
override async storageState(): Promise<channels.APIRequestContextStorageStateResult> {
|
override async storageState(indexedDB = true): Promise<channels.APIRequestContextStorageStateResult> {
|
||||||
return {
|
return {
|
||||||
cookies: this._cookieStore.allCookies(),
|
cookies: this._cookieStore.allCookies(),
|
||||||
origins: this._origins || []
|
origins: (this._origins || []).map(origin => ({ ...origin, indexedDB: indexedDB ? origin.indexedDB : [] })),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,8 @@ import type { source } from './isomorphic/utilityScriptSerializers';
|
||||||
|
|
||||||
export type Storage = Omit<channels.OriginStorage, 'origin'>;
|
export type Storage = Omit<channels.OriginStorage, 'origin'>;
|
||||||
|
|
||||||
export async function collect(serializers: ReturnType<typeof source>, isFirefox: boolean): Promise<Storage> {
|
export async function collect(serializers: ReturnType<typeof source>, isFirefox: boolean, recordIndexedDB: boolean): Promise<Storage> {
|
||||||
const idbResult = await Promise.all((await indexedDB.databases()).map(async dbInfo => {
|
async function collectDB(dbInfo: IDBDatabaseInfo) {
|
||||||
if (!dbInfo.name)
|
if (!dbInfo.name)
|
||||||
throw new Error('Database name is empty');
|
throw new Error('Database name is empty');
|
||||||
if (!dbInfo.version)
|
if (!dbInfo.version)
|
||||||
|
@ -119,13 +119,13 @@ export async function collect(serializers: ReturnType<typeof source>, isFirefox:
|
||||||
version: dbInfo.version,
|
version: dbInfo.version,
|
||||||
stores,
|
stores,
|
||||||
};
|
};
|
||||||
})).catch(e => {
|
}
|
||||||
throw new Error('Unable to serialize IndexedDB: ' + e.message);
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
localStorage: Object.keys(localStorage).map(name => ({ name, value: localStorage.getItem(name)! })),
|
localStorage: Object.keys(localStorage).map(name => ({ name, value: localStorage.getItem(name)! })),
|
||||||
indexedDB: idbResult,
|
indexedDB: recordIndexedDB ? await Promise.all((await indexedDB.databases()).map(collectDB)).catch(e => {
|
||||||
|
throw new Error('Unable to serialize IndexedDB: ' + e.message);
|
||||||
|
}) : [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9274,6 +9274,11 @@ export interface BrowserContext {
|
||||||
* @param options
|
* @param options
|
||||||
*/
|
*/
|
||||||
storageState(options?: {
|
storageState(options?: {
|
||||||
|
/**
|
||||||
|
* Defaults to `true`. Set to `false` to omit IndexedDB from snapshot.
|
||||||
|
*/
|
||||||
|
indexedDB?: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The file path to save the storage state to. If
|
* The file path to save the storage state to. If
|
||||||
* [`path`](https://playwright.dev/docs/api/class-browsercontext#browser-context-storage-state-option-path) is a
|
* [`path`](https://playwright.dev/docs/api/class-browsercontext#browser-context-storage-state-option-path) is a
|
||||||
|
@ -18534,6 +18539,11 @@ export interface APIRequestContext {
|
||||||
* @param options
|
* @param options
|
||||||
*/
|
*/
|
||||||
storageState(options?: {
|
storageState(options?: {
|
||||||
|
/**
|
||||||
|
* Defaults to `true`. Set to `false` to omit IndexedDB from snapshot.
|
||||||
|
*/
|
||||||
|
indexedDB?: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The file path to save the storage state to. If
|
* The file path to save the storage state to. If
|
||||||
* [`path`](https://playwright.dev/docs/api/class-apirequestcontext#api-request-context-storage-state-option-path) is
|
* [`path`](https://playwright.dev/docs/api/class-apirequestcontext#api-request-context-storage-state-option-path) is
|
||||||
|
|
|
@ -346,7 +346,7 @@ export interface APIRequestContextChannel extends APIRequestContextEventTarget,
|
||||||
fetch(params: APIRequestContextFetchParams, metadata?: CallMetadata): Promise<APIRequestContextFetchResult>;
|
fetch(params: APIRequestContextFetchParams, metadata?: CallMetadata): Promise<APIRequestContextFetchResult>;
|
||||||
fetchResponseBody(params: APIRequestContextFetchResponseBodyParams, metadata?: CallMetadata): Promise<APIRequestContextFetchResponseBodyResult>;
|
fetchResponseBody(params: APIRequestContextFetchResponseBodyParams, metadata?: CallMetadata): Promise<APIRequestContextFetchResponseBodyResult>;
|
||||||
fetchLog(params: APIRequestContextFetchLogParams, metadata?: CallMetadata): Promise<APIRequestContextFetchLogResult>;
|
fetchLog(params: APIRequestContextFetchLogParams, metadata?: CallMetadata): Promise<APIRequestContextFetchLogResult>;
|
||||||
storageState(params?: APIRequestContextStorageStateParams, metadata?: CallMetadata): Promise<APIRequestContextStorageStateResult>;
|
storageState(params: APIRequestContextStorageStateParams, metadata?: CallMetadata): Promise<APIRequestContextStorageStateResult>;
|
||||||
disposeAPIResponse(params: APIRequestContextDisposeAPIResponseParams, metadata?: CallMetadata): Promise<APIRequestContextDisposeAPIResponseResult>;
|
disposeAPIResponse(params: APIRequestContextDisposeAPIResponseParams, metadata?: CallMetadata): Promise<APIRequestContextDisposeAPIResponseResult>;
|
||||||
dispose(params: APIRequestContextDisposeParams, metadata?: CallMetadata): Promise<APIRequestContextDisposeResult>;
|
dispose(params: APIRequestContextDisposeParams, metadata?: CallMetadata): Promise<APIRequestContextDisposeResult>;
|
||||||
}
|
}
|
||||||
|
@ -402,8 +402,12 @@ export type APIRequestContextFetchLogOptions = {
|
||||||
export type APIRequestContextFetchLogResult = {
|
export type APIRequestContextFetchLogResult = {
|
||||||
log: string[],
|
log: string[],
|
||||||
};
|
};
|
||||||
export type APIRequestContextStorageStateParams = {};
|
export type APIRequestContextStorageStateParams = {
|
||||||
export type APIRequestContextStorageStateOptions = {};
|
indexedDB?: boolean,
|
||||||
|
};
|
||||||
|
export type APIRequestContextStorageStateOptions = {
|
||||||
|
indexedDB?: boolean,
|
||||||
|
};
|
||||||
export type APIRequestContextStorageStateResult = {
|
export type APIRequestContextStorageStateResult = {
|
||||||
cookies: NetworkCookie[],
|
cookies: NetworkCookie[],
|
||||||
origins: OriginStorage[],
|
origins: OriginStorage[],
|
||||||
|
@ -1564,7 +1568,7 @@ export interface BrowserContextChannel extends BrowserContextEventTarget, EventT
|
||||||
setNetworkInterceptionPatterns(params: BrowserContextSetNetworkInterceptionPatternsParams, metadata?: CallMetadata): Promise<BrowserContextSetNetworkInterceptionPatternsResult>;
|
setNetworkInterceptionPatterns(params: BrowserContextSetNetworkInterceptionPatternsParams, metadata?: CallMetadata): Promise<BrowserContextSetNetworkInterceptionPatternsResult>;
|
||||||
setWebSocketInterceptionPatterns(params: BrowserContextSetWebSocketInterceptionPatternsParams, metadata?: CallMetadata): Promise<BrowserContextSetWebSocketInterceptionPatternsResult>;
|
setWebSocketInterceptionPatterns(params: BrowserContextSetWebSocketInterceptionPatternsParams, metadata?: CallMetadata): Promise<BrowserContextSetWebSocketInterceptionPatternsResult>;
|
||||||
setOffline(params: BrowserContextSetOfflineParams, metadata?: CallMetadata): Promise<BrowserContextSetOfflineResult>;
|
setOffline(params: BrowserContextSetOfflineParams, metadata?: CallMetadata): Promise<BrowserContextSetOfflineResult>;
|
||||||
storageState(params?: BrowserContextStorageStateParams, metadata?: CallMetadata): Promise<BrowserContextStorageStateResult>;
|
storageState(params: BrowserContextStorageStateParams, metadata?: CallMetadata): Promise<BrowserContextStorageStateResult>;
|
||||||
pause(params?: BrowserContextPauseParams, metadata?: CallMetadata): Promise<BrowserContextPauseResult>;
|
pause(params?: BrowserContextPauseParams, metadata?: CallMetadata): Promise<BrowserContextPauseResult>;
|
||||||
enableRecorder(params: BrowserContextEnableRecorderParams, metadata?: CallMetadata): Promise<BrowserContextEnableRecorderResult>;
|
enableRecorder(params: BrowserContextEnableRecorderParams, metadata?: CallMetadata): Promise<BrowserContextEnableRecorderResult>;
|
||||||
newCDPSession(params: BrowserContextNewCDPSessionParams, metadata?: CallMetadata): Promise<BrowserContextNewCDPSessionResult>;
|
newCDPSession(params: BrowserContextNewCDPSessionParams, metadata?: CallMetadata): Promise<BrowserContextNewCDPSessionResult>;
|
||||||
|
@ -1797,8 +1801,12 @@ export type BrowserContextSetOfflineOptions = {
|
||||||
|
|
||||||
};
|
};
|
||||||
export type BrowserContextSetOfflineResult = void;
|
export type BrowserContextSetOfflineResult = void;
|
||||||
export type BrowserContextStorageStateParams = {};
|
export type BrowserContextStorageStateParams = {
|
||||||
export type BrowserContextStorageStateOptions = {};
|
indexedDB?: boolean,
|
||||||
|
};
|
||||||
|
export type BrowserContextStorageStateOptions = {
|
||||||
|
indexedDB?: boolean,
|
||||||
|
};
|
||||||
export type BrowserContextStorageStateResult = {
|
export type BrowserContextStorageStateResult = {
|
||||||
cookies: NetworkCookie[],
|
cookies: NetworkCookie[],
|
||||||
origins: OriginStorage[],
|
origins: OriginStorage[],
|
||||||
|
|
|
@ -376,6 +376,8 @@ APIRequestContext:
|
||||||
items: string
|
items: string
|
||||||
|
|
||||||
storageState:
|
storageState:
|
||||||
|
parameters:
|
||||||
|
indexedDB: boolean?
|
||||||
returns:
|
returns:
|
||||||
cookies:
|
cookies:
|
||||||
type: array
|
type: array
|
||||||
|
@ -1234,6 +1236,8 @@ BrowserContext:
|
||||||
offline: boolean
|
offline: boolean
|
||||||
|
|
||||||
storageState:
|
storageState:
|
||||||
|
parameters:
|
||||||
|
indexedDB: boolean?
|
||||||
returns:
|
returns:
|
||||||
cookies:
|
cookies:
|
||||||
type: array
|
type: array
|
||||||
|
|
|
@ -447,4 +447,6 @@ it('should support IndexedDB', async ({ page, server, contextFactory }) => {
|
||||||
- listitem:
|
- listitem:
|
||||||
- text: /Pet the cat/
|
- text: /Pet the cat/
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
expect(await context.storageState({ indexedDB: false })).toEqual({ cookies: [], origins: [] });
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue