docs
This commit is contained in:
parent
e26bd2a0c0
commit
da0ad1ef75
|
|
@ -1511,8 +1511,25 @@ Whether to emulate network being offline for the browser context.
|
|||
- `localStorage` <[Array]<[Object]>>
|
||||
- `name` <[string]>
|
||||
- `value` <[string]>
|
||||
- `indexedDB` <[Array]<[Object]>>
|
||||
- `name` <[string]>
|
||||
- `version` <[int]>
|
||||
- `stores` <[Array]<[Object]>>
|
||||
- `name` <[string]>
|
||||
- `keyPath` ?<[string]>
|
||||
- `keyPathArray` ?<[Array]<[string]>>
|
||||
- `autoIncrement` <[boolean]>
|
||||
- `indexes` <[Array]<[Object]>>
|
||||
- `name` <[string]>
|
||||
- `keyPath` ?<[string]>
|
||||
- `keyPathArray` ?<[Array]<[string]>>
|
||||
- `unique` <[boolean]>
|
||||
- `multiEntry` <[boolean]>
|
||||
- `records` <[Array]<[Object]>>
|
||||
- `key` ?<[string]>
|
||||
- `value` <[string]>
|
||||
|
||||
Returns storage state for this browser context, contains current cookies and local storage snapshot.
|
||||
Returns storage state for this browser context, contains current cookies, local storage snapshot and IndexedDB snapshot.
|
||||
|
||||
## async method: BrowserContext.storageState
|
||||
* since: v1.8
|
||||
|
|
|
|||
|
|
@ -265,7 +265,22 @@ Specify environment variables that will be visible to the browser. Defaults to `
|
|||
- `name` <[string]>
|
||||
- `value` <[string]>
|
||||
- `indexedDB` ?<[Array]<[Object]>>
|
||||
- `name` <[string]> TODO: document more
|
||||
- `name` <[string]>
|
||||
- `version` <[int]>
|
||||
- `stores` <[Array]<[Object]>>
|
||||
- `name` <[string]>
|
||||
- `keyPath` ?<[string]>
|
||||
- `keyPathArray` ?<[Array]<[string]>>
|
||||
- `autoIncrement` <[boolean]>
|
||||
- `indexes` <[Array]<[Object]>>
|
||||
- `name` <[string]>
|
||||
- `keyPath` ?<[string]>
|
||||
- `keyPathArray` ?<[Array]<[string]>>
|
||||
- `unique` <[boolean]>
|
||||
- `multiEntry` <[boolean]>
|
||||
- `records` <[Array]<[Object]>>
|
||||
- `key` ?<[string]>
|
||||
- `value` <[string]>
|
||||
|
||||
Learn more about [storage state and auth](../auth.md).
|
||||
|
||||
|
|
|
|||
|
|
@ -325,7 +325,7 @@ pwsh bin/Debug/netX/playwright.ps1 codegen --timezone="Europe/Rome" --geolocatio
|
|||
|
||||
### Preserve authenticated state
|
||||
|
||||
Run `codegen` with `--save-storage` to save [cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies) and [localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) at the end of the session. This is useful to separately record an authentication step and reuse it later when recording more tests.
|
||||
Run `codegen` with `--save-storage` to save [cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies), [localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) and [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) data at the end of the session. This is useful to separately record an authentication step and reuse it later when recording more tests.
|
||||
|
||||
```bash js
|
||||
npx playwright codegen github.com/microsoft/playwright --save-storage=auth.json
|
||||
|
|
@ -375,7 +375,7 @@ Make sure you only use the `auth.json` locally as it contains sensitive informat
|
|||
|
||||
#### Load authenticated state
|
||||
|
||||
Run with `--load-storage` to consume the previously loaded storage from the `auth.json`. This way, all [cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies) and [localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) will be restored, bringing most web apps to the authenticated state without the need to login again. This means you can continue generating tests from the logged in state.
|
||||
Run with `--load-storage` to consume the previously loaded storage from the `auth.json`. This way, all [cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies), [localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) and [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) data will be restored, bringing most web apps to the authenticated state without the need to login again. This means you can continue generating tests from the logged in state.
|
||||
|
||||
```bash js
|
||||
npx playwright codegen --load-storage=auth.json github.com/microsoft/playwright
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ scheme.IndexedDBDatabase = tObject({
|
|||
scheme.OriginStorage = tObject({
|
||||
origin: tString,
|
||||
localStorage: tArray(tType('NameValue')),
|
||||
indexedDB: tOptional(tArray(tType('IndexedDBDatabase'))),
|
||||
indexedDB: tArray(tType('IndexedDBDatabase')),
|
||||
});
|
||||
scheme.SerializedError = tObject({
|
||||
error: tOptional(tObject({
|
||||
|
|
|
|||
|
|
@ -515,20 +515,16 @@ export abstract class BrowserContext extends SdkObject {
|
|||
const originsToSave = new Set(this._origins);
|
||||
|
||||
async function _collectStorageScript() {
|
||||
async function _collectDatabase(dbInfo: IDBDatabaseInfo) {
|
||||
if (!dbInfo.name)
|
||||
return;
|
||||
|
||||
let db: IDBDatabase;
|
||||
try {
|
||||
db = await new Promise((resolve, reject) => {
|
||||
const request = indexedDB.open(dbInfo.name!);
|
||||
request.onerror = reject;
|
||||
request.onsuccess = () => resolve(request.result);
|
||||
});
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
const idbResult = await Promise.all((await indexedDB.databases()).map(async dbInfo => {
|
||||
if (!dbInfo.name)
|
||||
throw new Error('Database name is empty');
|
||||
|
||||
const db = await new Promise<IDBDatabase>((resolve, reject) => {
|
||||
const request = indexedDB.open(dbInfo.name!);
|
||||
request.onerror = reject;
|
||||
request.onsuccess = () => resolve(request.result);
|
||||
});
|
||||
|
||||
const transaction = db.transaction(db.objectStoreNames, 'readonly');
|
||||
const stores = await Promise.all([...db.objectStoreNames].map(async storeName => {
|
||||
|
|
@ -540,22 +536,19 @@ export abstract class BrowserContext extends SdkObject {
|
|||
});
|
||||
|
||||
const records = await Promise.all(keys.map(async key => {
|
||||
const record = await new Promise<any[]>((resolve, reject) => {
|
||||
const record = await new Promise<any>((resolve, reject) => {
|
||||
const request = objectStore.get(key);
|
||||
request.addEventListener('success', () => resolve(request.result));
|
||||
request.addEventListener('error', reject);
|
||||
});
|
||||
|
||||
if (!record)
|
||||
return;
|
||||
|
||||
return {
|
||||
key: objectStore.keyPath === null ? key.toString() : undefined,
|
||||
value: record
|
||||
};
|
||||
}));
|
||||
|
||||
const indexes = await Promise.all([...objectStore.indexNames].map(async indexName => {
|
||||
const indexes = [...objectStore.indexNames].map(indexName => {
|
||||
const index = objectStore.index(indexName);
|
||||
return {
|
||||
name: index.name,
|
||||
|
|
@ -564,7 +557,7 @@ export abstract class BrowserContext extends SdkObject {
|
|||
multiEntry: index.multiEntry,
|
||||
unique: index.unique,
|
||||
};
|
||||
}));
|
||||
});
|
||||
|
||||
return {
|
||||
name: storeName,
|
||||
|
|
@ -581,13 +574,11 @@ export abstract class BrowserContext extends SdkObject {
|
|||
version: dbInfo.version,
|
||||
stores,
|
||||
};
|
||||
}
|
||||
|
||||
const idbResult = await Promise.all((await indexedDB.databases()).map(_collectDatabase).filter(Boolean));
|
||||
}));
|
||||
|
||||
return {
|
||||
localStorage: Object.keys(localStorage).map(name => ({ name, value: localStorage.getItem(name) })),
|
||||
indexedDB: idbResult.length ? idbResult : undefined,
|
||||
indexedDB: idbResult,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -607,8 +598,7 @@ export abstract class BrowserContext extends SdkObject {
|
|||
continue;
|
||||
try {
|
||||
const storage = await page.mainFrame().nonStallingEvaluateInExistingContext(`(${_collectStorageScript.toString()})()`, 'utility');
|
||||
if (storage.indexedDB?.length)
|
||||
serializeRecords(storage.indexedDB);
|
||||
serializeRecords(storage.indexedDB);
|
||||
if (storage.localStorage.length || storage.indexedDB?.length)
|
||||
result.origins.push({ origin, localStorage: storage.localStorage, indexedDB: storage.indexedDB } as channels.OriginStorage);
|
||||
originsToSave.delete(origin);
|
||||
|
|
@ -629,9 +619,8 @@ export abstract class BrowserContext extends SdkObject {
|
|||
const frame = page.mainFrame();
|
||||
await frame.goto(internalMetadata, origin);
|
||||
const storage = await frame.evaluateExpression(`(${_collectStorageScript.toString()})()`, { world: 'utility' });
|
||||
if (storage.indexedDB?.length)
|
||||
serializeRecords(storage.indexedDB);
|
||||
if (storage.localStorage.length || storage.indexedDB?.length)
|
||||
serializeRecords(storage.indexedDB);
|
||||
if (storage.localStorage.length || storage.indexedDB.length)
|
||||
result.origins.push({ origin, localStorage: storage.localStorage, indexedDB: storage.indexedDB } as channels.OriginStorage);
|
||||
}
|
||||
await page.close(internalMetadata);
|
||||
|
|
@ -707,7 +696,7 @@ export abstract class BrowserContext extends SdkObject {
|
|||
for (const { name, value } of (originState.localStorage || []))
|
||||
localStorage.setItem(name, value);
|
||||
|
||||
await Promise.all((originState.indexedDB || []).map(async dbInfo => {
|
||||
await Promise.all(originState.indexedDB.map(async dbInfo => {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
const openRequest = indexedDB.open(dbInfo.name, dbInfo.version);
|
||||
openRequest.addEventListener('upgradeneeded', () => {
|
||||
|
|
|
|||
103
packages/playwright-core/types/types.d.ts
vendored
103
packages/playwright-core/types/types.d.ts
vendored
|
|
@ -9260,7 +9260,8 @@ export interface BrowserContext {
|
|||
setOffline(offline: boolean): Promise<void>;
|
||||
|
||||
/**
|
||||
* Returns storage state for this browser context, contains current cookies and local storage snapshot.
|
||||
* Returns storage state for this browser context, contains current cookies, local storage snapshot and IndexedDB
|
||||
* snapshot.
|
||||
* @param options
|
||||
*/
|
||||
storageState(options?: {
|
||||
|
|
@ -9301,6 +9302,40 @@ export interface BrowserContext {
|
|||
|
||||
value: string;
|
||||
}>;
|
||||
|
||||
indexedDB: Array<{
|
||||
name: string;
|
||||
|
||||
version: number;
|
||||
|
||||
stores: Array<{
|
||||
name: string;
|
||||
|
||||
keyPath?: string;
|
||||
|
||||
keyPathArray?: Array<string>;
|
||||
|
||||
autoIncrement: boolean;
|
||||
|
||||
indexes: Array<{
|
||||
name: string;
|
||||
|
||||
keyPath?: string;
|
||||
|
||||
keyPathArray?: Array<string>;
|
||||
|
||||
unique: boolean;
|
||||
|
||||
multiEntry: boolean;
|
||||
}>;
|
||||
|
||||
records: Array<{
|
||||
key?: string;
|
||||
|
||||
value: string;
|
||||
}>;
|
||||
}>;
|
||||
}>;
|
||||
}>;
|
||||
}>;
|
||||
|
||||
|
|
@ -10062,10 +10097,37 @@ export interface Browser {
|
|||
}>;
|
||||
|
||||
indexedDB?: Array<{
|
||||
/**
|
||||
* TODO: document more
|
||||
*/
|
||||
name: string;
|
||||
|
||||
version: number;
|
||||
|
||||
stores: Array<{
|
||||
name: string;
|
||||
|
||||
keyPath?: string;
|
||||
|
||||
keyPathArray?: Array<string>;
|
||||
|
||||
autoIncrement: boolean;
|
||||
|
||||
indexes: Array<{
|
||||
name: string;
|
||||
|
||||
keyPath?: string;
|
||||
|
||||
keyPathArray?: Array<string>;
|
||||
|
||||
unique: boolean;
|
||||
|
||||
multiEntry: boolean;
|
||||
}>;
|
||||
|
||||
records: Array<{
|
||||
key?: string;
|
||||
|
||||
value: string;
|
||||
}>;
|
||||
}>;
|
||||
}>;
|
||||
}>;
|
||||
};
|
||||
|
|
@ -22236,10 +22298,37 @@ export interface BrowserContextOptions {
|
|||
}>;
|
||||
|
||||
indexedDB?: Array<{
|
||||
/**
|
||||
* TODO: document more
|
||||
*/
|
||||
name: string;
|
||||
|
||||
version: number;
|
||||
|
||||
stores: Array<{
|
||||
name: string;
|
||||
|
||||
keyPath?: string;
|
||||
|
||||
keyPathArray?: Array<string>;
|
||||
|
||||
autoIncrement: boolean;
|
||||
|
||||
indexes: Array<{
|
||||
name: string;
|
||||
|
||||
keyPath?: string;
|
||||
|
||||
keyPathArray?: Array<string>;
|
||||
|
||||
unique: boolean;
|
||||
|
||||
multiEntry: boolean;
|
||||
}>;
|
||||
|
||||
records: Array<{
|
||||
key?: string;
|
||||
|
||||
value: string;
|
||||
}>;
|
||||
}>;
|
||||
}>;
|
||||
}>;
|
||||
};
|
||||
|
|
|
|||
2
packages/protocol/src/channels.d.ts
vendored
2
packages/protocol/src/channels.d.ts
vendored
|
|
@ -296,7 +296,7 @@ export type IndexedDBDatabase = {
|
|||
export type OriginStorage = {
|
||||
origin: string,
|
||||
localStorage: NameValue[],
|
||||
indexedDB?: IndexedDBDatabase[],
|
||||
indexedDB: IndexedDBDatabase[],
|
||||
};
|
||||
|
||||
export type SerializedError = {
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ OriginStorage:
|
|||
type: array
|
||||
items: NameValue
|
||||
indexedDB:
|
||||
type: array?
|
||||
type: array
|
||||
items: IndexedDBDatabase
|
||||
|
||||
SerializedError:
|
||||
|
|
|
|||
Loading…
Reference in a new issue