diff --git a/src/protocol/channels.ts b/src/protocol/channels.ts index 9b948044d9..eac8166c44 100644 --- a/src/protocol/channels.ts +++ b/src/protocol/channels.ts @@ -272,6 +272,10 @@ export type BrowserTypeLaunchPersistentContextParams = { height: number, }, }, + recordHar?: { + omitContent?: boolean, + path: string, + }, }; export type BrowserTypeLaunchPersistentContextOptions = { executablePath?: string, @@ -337,6 +341,10 @@ export type BrowserTypeLaunchPersistentContextOptions = { height: number, }, }, + recordHar?: { + omitContent?: boolean, + path: string, + }, }; export type BrowserTypeLaunchPersistentContextResult = { context: BrowserContextChannel, diff --git a/src/protocol/protocol.yml b/src/protocol/protocol.yml index 318b79e053..4d86793d35 100644 --- a/src/protocol/protocol.yml +++ b/src/protocol/protocol.yml @@ -325,6 +325,11 @@ BrowserType: properties: width: number height: number + recordHar: + type: object? + properties: + omitContent: boolean? + path: string returns: context: BrowserContext diff --git a/src/protocol/validator.ts b/src/protocol/validator.ts index 5b0d3236ff..a6c46450ef 100644 --- a/src/protocol/validator.ts +++ b/src/protocol/validator.ts @@ -190,6 +190,10 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme { height: tNumber, })), })), + recordHar: tOptional(tObject({ + omitContent: tOptional(tBoolean), + path: tString, + })), }); scheme.BrowserCloseParams = tOptional(tObject({})); scheme.BrowserNewContextParams = tObject({ diff --git a/test/har.spec.ts b/test/har.spec.ts index 51da994c38..522e8fee2f 100644 --- a/test/har.spec.ts +++ b/test/har.spec.ts @@ -46,6 +46,11 @@ builder.pageWithHar.init(async ({ contextFactory, testInfo }, run) => { const { expect, it } = builder.build(); +it('should throw without path', async ({ browser }) => { + const error = await browser.newContext({ recordHar: {} as any }).catch(e => e); + expect(error.message).toContain('recordHar.path: expected string, got undefined'); +}); + it('should have version and creator', async ({ pageWithHar, server }) => { const { page } = pageWithHar; await page.goto(server.EMPTY_PAGE); @@ -78,6 +83,20 @@ it('should have pages', async ({ pageWithHar, server }) => { expect(pageEntry.pageTimings.onLoad).toBeGreaterThan(0); }); +it('should have pages in persistent context', async ({ launchPersistent, testInfo }) => { + const harPath = testInfo.outputPath('test.har'); + const { context, page } = await launchPersistent({ recordHar: { path: harPath } }); + await page.goto('data:text/html,Hello'); + // For data: load comes before domcontentloaded... + await page.waitForLoadState('domcontentloaded'); + await context.close(); + const log = JSON.parse(fs.readFileSync(harPath).toString())['log']; + expect(log.pages.length).toBe(1); + const pageEntry = log.pages[0]; + expect(pageEntry.id).toBe('page_0'); + expect(pageEntry.title).toBe('Hello'); +}); + it('should include request', async ({ pageWithHar, server }) => { const { page } = pageWithHar; await page.goto(server.EMPTY_PAGE);