From e17e0e40f858b2a2b22c8f2d0d45eb494a8c1258 Mon Sep 17 00:00:00 2001 From: NoamGaash Date: Tue, 28 Feb 2023 01:27:38 +0200 Subject: [PATCH] feat(routeFromHAR): add arguments (#21223) --- docs/src/api/class-browsercontext.md | 12 ++++++++++++ docs/src/api/class-page.md | 10 ++++++++++ .../src/client/browserContext.ts | 10 +++++----- packages/playwright-core/src/client/page.ts | 2 +- packages/playwright-core/types/types.d.ts | 18 ++++++++++++++++++ tests/library/browsercontext-har.spec.ts | 17 +++++++++++++++++ 6 files changed, 63 insertions(+), 6 deletions(-) diff --git a/docs/src/api/class-browsercontext.md b/docs/src/api/class-browsercontext.md index 3bf24d9456..13d0676427 100644 --- a/docs/src/api/class-browsercontext.md +++ b/docs/src/api/class-browsercontext.md @@ -1124,6 +1124,18 @@ If specified, updates the given HAR with the actual network information instead A glob pattern, regular expression or predicate to match the request URL. Only requests with URL matching the pattern will be served from the HAR file. If not specified, all requests are served from the HAR file. +### option: BrowserContext.routeFromHAR.mode +* since: v1.32 +- `mode` <[HarMode]<"full"|"minimal">> + +When set to `minimal`, only record information necessary for routing from HAR. This omits sizes, timing, page, cookies, security and other types of HAR information that are not used when replaying from HAR. Defaults to `minimal`. + +### option: BrowserContext.routeFromHAR.content +* since: v1.32 +- `content` <[HarContentPolicy]<"omit"|"embed"|"attach">> + +Optional setting to control resource content management. If `omit` is specified, content is not persisted. If `attach` is specified, resources are persisted as separate files or entries in the ZIP archive. If `embed` is specified, content is stored inline the HAR file + ## method: BrowserContext.serviceWorkers * since: v1.11 * langs: js, python diff --git a/docs/src/api/class-page.md b/docs/src/api/class-page.md index f75c6f13d1..fce271e693 100644 --- a/docs/src/api/class-page.md +++ b/docs/src/api/class-page.md @@ -3272,6 +3272,16 @@ If specified, updates the given HAR with the actual network information instead A glob pattern, regular expression or predicate to match the request URL. Only requests with URL matching the pattern will be served from the HAR file. If not specified, all requests are served from the HAR file. +### option: Page.routeFromHAR.mode +* since: v1.32 +- `mode` <[HarMode]<"full"|"minimal">> +When set to `minimal`, only record information necessary for routing from HAR. This omits sizes, timing, page, cookies, security and other types of HAR information that are not used when replaying from HAR. Defaults to `full`. + +### option: Page.routeFromHAR.url +* since: v1.32 +- `content` <[HarContentPolicy]<"omit"|"embed"|"attach">> +Optional setting to control resource content management. If `omit` is specified, content is not persisted. If `attach` is specified, resources are persisted as separate files or entries in the ZIP archive. If `embed` is specified, content is stored inline the HAR file + ## async method: Page.screenshot * since: v1.8 - returns: <[Buffer]> diff --git a/packages/playwright-core/src/client/browserContext.ts b/packages/playwright-core/src/client/browserContext.ts index 4fad02d749..95bcc42c2e 100644 --- a/packages/playwright-core/src/client/browserContext.ts +++ b/packages/playwright-core/src/client/browserContext.ts @@ -265,20 +265,20 @@ export class BrowserContext extends ChannelOwner await this._updateInterceptionPatterns(); } - async _recordIntoHAR(har: string, page: Page | null, options: { url?: string | RegExp, notFound?: 'abort' | 'fallback', update?: boolean } = {}): Promise { + async _recordIntoHAR(har: string, page: Page | null, options: { url?: string | RegExp, notFound?: 'abort' | 'fallback', update?: boolean, content?: 'omit' | 'attach' | 'embed' | undefined, mode?: 'minimal' | 'full'} = {}): Promise { const { harId } = await this._channel.harStart({ page: page?._channel, options: prepareRecordHarOptions({ path: har, - content: 'attach', - mode: 'minimal', + content: options.content ?? 'attach', + mode: options.mode ?? 'minimal', urlFilter: options.url })! }); - this._harRecorders.set(harId, { path: har, content: 'attach' }); + this._harRecorders.set(harId, { path: har, content: options.content ?? 'attach' }); } - async routeFromHAR(har: string, options: { url?: string | RegExp, notFound?: 'abort' | 'fallback', update?: boolean } = {}): Promise { + async routeFromHAR(har: string, options: { url?: string | RegExp, notFound?: 'abort' | 'fallback', update?: boolean, content?: 'omit' | 'attach' | 'embed' | undefined, mode?: 'minimal' | 'full' } = {}): Promise { if (options.update) { await this._recordIntoHAR(har, null, options); return; diff --git a/packages/playwright-core/src/client/page.ts b/packages/playwright-core/src/client/page.ts index 8001bf059c..12c8387a67 100644 --- a/packages/playwright-core/src/client/page.ts +++ b/packages/playwright-core/src/client/page.ts @@ -460,7 +460,7 @@ export class Page extends ChannelOwner implements api.Page await this._updateInterceptionPatterns(); } - async routeFromHAR(har: string, options: { url?: string | RegExp, notFound?: 'abort' | 'fallback', update?: boolean } = {}): Promise { + async routeFromHAR(har: string, options: { url?: string | RegExp, notFound?: 'abort' | 'fallback', update?: boolean, content?: 'omit' | 'attach' | 'embed' | undefined, mode?: 'minimal' | 'full'} = {}): Promise { if (options.update) { await this._browserContext._recordIntoHAR(har, this, options); return; diff --git a/packages/playwright-core/types/types.d.ts b/packages/playwright-core/types/types.d.ts index 11b5c56352..d1d5846dad 100644 --- a/packages/playwright-core/types/types.d.ts +++ b/packages/playwright-core/types/types.d.ts @@ -3556,6 +3556,10 @@ export interface Page { * @param options */ routeFromHAR(har: string, options?: { + content?: "omit"|"embed"|"attach"; + + mode?: "full"|"minimal"; + /** * - If set to 'abort' any request not found in the HAR file will be aborted. * - If set to 'fallback' missing requests will be sent to the network. @@ -8057,6 +8061,20 @@ export interface BrowserContext { * @param options */ routeFromHAR(har: string, options?: { + /** + * Optional setting to control resource content management. If `omit` is specified, content is not persisted. If + * `attach` is specified, resources are persisted as separate files or entries in the ZIP archive. If `embed` is + * specified, content is stored inline the HAR file + */ + content?: "omit"|"embed"|"attach"; + + /** + * When set to `minimal`, only record information necessary for routing from HAR. This omits sizes, timing, page, + * cookies, security and other types of HAR information that are not used when replaying from HAR. Defaults to + * `minimal`. + */ + mode?: "full"|"minimal"; + /** * - If set to 'abort' any request not found in the HAR file will be aborted. * - If set to 'fallback' falls through to the next route handler in the handler chain. diff --git a/tests/library/browsercontext-har.spec.ts b/tests/library/browsercontext-har.spec.ts index 32e8611993..39998b6944 100644 --- a/tests/library/browsercontext-har.spec.ts +++ b/tests/library/browsercontext-har.spec.ts @@ -371,6 +371,23 @@ it('should update har.zip for page', async ({ contextFactory, server }, testInfo await expect(page2.locator('body')).toHaveCSS('background-color', 'rgb(255, 192, 203)'); }); + +it('should update har.zip for page with different options', async ({ contextFactory, server }, testInfo) => { + const harPath = testInfo.outputPath('har.zip'); + const context1 = await contextFactory(); + const page1 = await context1.newPage(); + await page1.routeFromHAR(harPath, { 'update': true, 'content': 'embed', 'mode': 'full' }); + await page1.goto(server.PREFIX + '/one-style.html'); + await context1.close(); + + const context2 = await contextFactory(); + const page2 = await context2.newPage(); + await page2.routeFromHAR(harPath, { notFound: 'abort' }); + await page2.goto(server.PREFIX + '/one-style.html'); + expect(await page2.content()).toContain('hello, world!'); + await expect(page2.locator('body')).toHaveCSS('background-color', 'rgb(255, 192, 203)'); +}); + it('should update extracted har.zip for page', async ({ contextFactory, server }, testInfo) => { const harPath = testInfo.outputPath('har.har'); const context1 = await contextFactory();