feature(har): add testOptions.har (#14991)
Can now be used with `test.use({ har })`.
Also added more tests for latest har features.
This commit is contained in:
parent
c3bbf8963d
commit
5397394653
|
|
@ -129,6 +129,8 @@ Options used to create the context, as passed to [`method: Browser.newContext`].
|
||||||
|
|
||||||
## property: TestOptions.geolocation = %%-context-option-geolocation-%%
|
## property: TestOptions.geolocation = %%-context-option-geolocation-%%
|
||||||
|
|
||||||
|
## property: TestOptions.har = %%-js-context-option-har-%%
|
||||||
|
|
||||||
## property: TestOptions.hasTouch = %%-context-option-hastouch-%%
|
## property: TestOptions.hasTouch = %%-context-option-hastouch-%%
|
||||||
|
|
||||||
## property: TestOptions.headless = %%-browser-option-headless-%%
|
## property: TestOptions.headless = %%-browser-option-headless-%%
|
||||||
|
|
|
||||||
|
|
@ -141,6 +141,7 @@ export const test = _baseTest.extend<TestFixtures, WorkerFixtures>({
|
||||||
deviceScaleFactor: [ undefined, { option: true } ],
|
deviceScaleFactor: [ undefined, { option: true } ],
|
||||||
extraHTTPHeaders: [ undefined, { option: true } ],
|
extraHTTPHeaders: [ undefined, { option: true } ],
|
||||||
geolocation: [ undefined, { option: true } ],
|
geolocation: [ undefined, { option: true } ],
|
||||||
|
har: [undefined, { option: true }],
|
||||||
hasTouch: [ undefined, { option: true } ],
|
hasTouch: [ undefined, { option: true } ],
|
||||||
httpCredentials: [ undefined, { option: true } ],
|
httpCredentials: [ undefined, { option: true } ],
|
||||||
ignoreHTTPSErrors: [ undefined, { option: true } ],
|
ignoreHTTPSErrors: [ undefined, { option: true } ],
|
||||||
|
|
@ -168,6 +169,7 @@ export const test = _baseTest.extend<TestFixtures, WorkerFixtures>({
|
||||||
colorScheme,
|
colorScheme,
|
||||||
deviceScaleFactor,
|
deviceScaleFactor,
|
||||||
extraHTTPHeaders,
|
extraHTTPHeaders,
|
||||||
|
har,
|
||||||
hasTouch,
|
hasTouch,
|
||||||
geolocation,
|
geolocation,
|
||||||
httpCredentials,
|
httpCredentials,
|
||||||
|
|
@ -199,6 +201,8 @@ export const test = _baseTest.extend<TestFixtures, WorkerFixtures>({
|
||||||
options.extraHTTPHeaders = extraHTTPHeaders;
|
options.extraHTTPHeaders = extraHTTPHeaders;
|
||||||
if (geolocation !== undefined)
|
if (geolocation !== undefined)
|
||||||
options.geolocation = geolocation;
|
options.geolocation = geolocation;
|
||||||
|
if (har !== undefined)
|
||||||
|
options.har = har;
|
||||||
if (hasTouch !== undefined)
|
if (hasTouch !== undefined)
|
||||||
options.hasTouch = hasTouch;
|
options.hasTouch = hasTouch;
|
||||||
if (httpCredentials !== undefined)
|
if (httpCredentials !== undefined)
|
||||||
|
|
|
||||||
9
packages/playwright-test/types/test.d.ts
vendored
9
packages/playwright-test/types/test.d.ts
vendored
|
|
@ -2492,6 +2492,7 @@ type BrowserName = 'chromium' | 'firefox' | 'webkit';
|
||||||
type BrowserChannel = Exclude<LaunchOptions['channel'], undefined>;
|
type BrowserChannel = Exclude<LaunchOptions['channel'], undefined>;
|
||||||
type ColorScheme = Exclude<BrowserContextOptions['colorScheme'], undefined>;
|
type ColorScheme = Exclude<BrowserContextOptions['colorScheme'], undefined>;
|
||||||
type ExtraHTTPHeaders = Exclude<BrowserContextOptions['extraHTTPHeaders'], undefined>;
|
type ExtraHTTPHeaders = Exclude<BrowserContextOptions['extraHTTPHeaders'], undefined>;
|
||||||
|
type HAROptions = Exclude<BrowserContextOptions['har'], undefined>;
|
||||||
type Proxy = Exclude<BrowserContextOptions['proxy'], undefined>;
|
type Proxy = Exclude<BrowserContextOptions['proxy'], undefined>;
|
||||||
type StorageState = Exclude<BrowserContextOptions['storageState'], undefined>;
|
type StorageState = Exclude<BrowserContextOptions['storageState'], undefined>;
|
||||||
type ServiceWorkerPolicy = Exclude<BrowserContextOptions['serviceWorkers'], undefined>;
|
type ServiceWorkerPolicy = Exclude<BrowserContextOptions['serviceWorkers'], undefined>;
|
||||||
|
|
@ -2699,6 +2700,14 @@ export interface PlaywrightTestOptions {
|
||||||
*/
|
*/
|
||||||
extraHTTPHeaders: ExtraHTTPHeaders | undefined;
|
extraHTTPHeaders: ExtraHTTPHeaders | undefined;
|
||||||
geolocation: Geolocation | undefined;
|
geolocation: Geolocation | undefined;
|
||||||
|
/**
|
||||||
|
* If specified the network requests that are made in the context will be served from the HAR file.
|
||||||
|
*
|
||||||
|
* > NOTE: Playwright will not serve requests intercepted by Service Worker from the HAR file. See
|
||||||
|
* [this](https://github.com/microsoft/playwright/issues/1090) issue. We recommend disabling Service Workers when using
|
||||||
|
* request interception. Via `await context.addInitScript(() => delete window.navigator.serviceWorker);`
|
||||||
|
*/
|
||||||
|
har: HAROptions | undefined;
|
||||||
/**
|
/**
|
||||||
* Specifies if viewport supports touch events. Defaults to false.
|
* Specifies if viewport supports touch events. Defaults to false.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
1
tests/assets/har-sha1-main-response.txt
Normal file
1
tests/assets/har-sha1-main-response.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Hello, world
|
||||||
96
tests/assets/har-sha1.har
Normal file
96
tests/assets/har-sha1.har
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
{
|
||||||
|
"log": {
|
||||||
|
"version": "1.2",
|
||||||
|
"creator": {
|
||||||
|
"name": "Playwright",
|
||||||
|
"version": "1.23.0-next"
|
||||||
|
},
|
||||||
|
"browser": {
|
||||||
|
"name": "chromium",
|
||||||
|
"version": "103.0.5060.33"
|
||||||
|
},
|
||||||
|
"pages": [
|
||||||
|
{
|
||||||
|
"startedDateTime": "2022-06-10T04:27:32.125Z",
|
||||||
|
"id": "page@b17b177f1c2e66459db3dcbe44636ffd",
|
||||||
|
"title": "Hey",
|
||||||
|
"pageTimings": {
|
||||||
|
"onContentLoad": 70,
|
||||||
|
"onLoad": 70
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"entries": [
|
||||||
|
{
|
||||||
|
"_requestref": "request@ee2a0dc164935fcd4d9432d37b245f3c",
|
||||||
|
"_frameref": "frame@c7467fc0f1f86f09fc3b0d727a3862ea",
|
||||||
|
"_monotonicTime": 270572145.898,
|
||||||
|
"startedDateTime": "2022-06-10T04:27:32.146Z",
|
||||||
|
"time": 8.286,
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"url": "http://no.playwright/",
|
||||||
|
"httpVersion": "HTTP/1.1",
|
||||||
|
"cookies": [],
|
||||||
|
"headers": [
|
||||||
|
{
|
||||||
|
"name": "Accept",
|
||||||
|
"value": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Upgrade-Insecure-Requests",
|
||||||
|
"value": "1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "User-Agent",
|
||||||
|
"value": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.33 Safari/537.36"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"queryString": [],
|
||||||
|
"headersSize": 326,
|
||||||
|
"bodySize": 0
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
"status": 200,
|
||||||
|
"statusText": "OK",
|
||||||
|
"httpVersion": "HTTP/1.1",
|
||||||
|
"cookies": [],
|
||||||
|
"headers": [
|
||||||
|
{
|
||||||
|
"name": "content-length",
|
||||||
|
"value": "12"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "content-type",
|
||||||
|
"value": "text/html"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"content": {
|
||||||
|
"size": 12,
|
||||||
|
"mimeType": "text/html",
|
||||||
|
"compression": 0,
|
||||||
|
"_sha1": "har-sha1-main-response.txt"
|
||||||
|
},
|
||||||
|
"headersSize": 64,
|
||||||
|
"bodySize": 71,
|
||||||
|
"redirectURL": "",
|
||||||
|
"_transferSize": 71
|
||||||
|
},
|
||||||
|
"cache": {
|
||||||
|
"beforeRequest": null,
|
||||||
|
"afterRequest": null
|
||||||
|
},
|
||||||
|
"timings": {
|
||||||
|
"dns": -1,
|
||||||
|
"connect": -1,
|
||||||
|
"ssl": -1,
|
||||||
|
"send": 0,
|
||||||
|
"wait": 8.286,
|
||||||
|
"receive": -1
|
||||||
|
},
|
||||||
|
"pageref": "page@b17b177f1c2e66459db3dcbe44636ffd",
|
||||||
|
"_securityDetails": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -166,3 +166,29 @@ it('should reload redirected navigation', async ({ contextFactory, isAndroid, as
|
||||||
expect(response.request().url()).toBe('https://www.theverge.com/');
|
expect(response.request().url()).toBe('https://www.theverge.com/');
|
||||||
expect(await page.evaluate(() => location.href)).toBe('https://www.theverge.com/');
|
expect(await page.evaluate(() => location.href)).toBe('https://www.theverge.com/');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should fulfill from har with content in a file', async ({ contextFactory, isAndroid, asset }) => {
|
||||||
|
it.fixme(isAndroid);
|
||||||
|
|
||||||
|
const path = asset('har-sha1.har');
|
||||||
|
const context = await contextFactory({ har: { path } });
|
||||||
|
const page = await context.newPage();
|
||||||
|
await page.goto('http://no.playwright/');
|
||||||
|
expect(await page.content()).toBe('<html><head></head><body>Hello, world</body></html>');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should round-trip har.zip', async ({ contextFactory, isAndroid, server }, testInfo) => {
|
||||||
|
it.fixme(isAndroid);
|
||||||
|
|
||||||
|
const harPath = testInfo.outputPath('har.zip');
|
||||||
|
const context1 = await contextFactory({ recordHar: { path: harPath } });
|
||||||
|
const page1 = await context1.newPage();
|
||||||
|
await page1.goto(server.PREFIX + '/one-style.html');
|
||||||
|
await context1.close();
|
||||||
|
|
||||||
|
const context2 = await contextFactory({ har: { path: harPath, fallback: 'abort' } });
|
||||||
|
const page2 = await context2.newPage();
|
||||||
|
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)');
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ export class VideoPlayer {
|
||||||
const output = spawnSync(ffmpeg, ['-i', fileName, '-r', '25', `${fileName}-%03d.png`]).stderr.toString();
|
const output = spawnSync(ffmpeg, ['-i', fileName, '-r', '25', `${fileName}-%03d.png`]).stderr.toString();
|
||||||
const lines = output.split('\n');
|
const lines = output.split('\n');
|
||||||
const streamLine = lines.find(l => l.trim().startsWith('Stream #0:0'));
|
const streamLine = lines.find(l => l.trim().startsWith('Stream #0:0'));
|
||||||
const resolutionMatch = streamLine.match(/, (\d+)x(\d+),/);
|
const resolutionMatch = streamLine!.match(/, (\d+)x(\d+),/);
|
||||||
this.videoWidth = parseInt(resolutionMatch![1], 10);
|
this.videoWidth = parseInt(resolutionMatch![1], 10);
|
||||||
this.videoHeight = parseInt(resolutionMatch![2], 10);
|
this.videoHeight = parseInt(resolutionMatch![2], 10);
|
||||||
}
|
}
|
||||||
|
|
@ -526,7 +526,7 @@ test('should work with video: on-first-retry', async ({ runInlineTest }, testInf
|
||||||
expect(result.report.suites[0].specs[1].tests[0].results[1].attachments).toEqual([{
|
expect(result.report.suites[0].specs[1].tests[0].results[1].attachments).toEqual([{
|
||||||
name: 'video',
|
name: 'video',
|
||||||
contentType: 'video/webm',
|
contentType: 'video/webm',
|
||||||
path: path.join(dirRetry, videoFailRetry),
|
path: path.join(dirRetry, videoFailRetry!),
|
||||||
}]);
|
}]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -602,3 +602,18 @@ test('should pass fixture defaults to tests', async ({ runInlineTest }) => {
|
||||||
expect(result.exitCode).toBe(0);
|
expect(result.exitCode).toBe(0);
|
||||||
expect(result.passed).toBe(1);
|
expect(result.passed).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should support har option', async ({ runInlineTest, asset }) => {
|
||||||
|
const result = await runInlineTest({
|
||||||
|
'a.test.ts': `
|
||||||
|
const { test } = pwt;
|
||||||
|
test.use({ har: { path: ${JSON.stringify(asset('har-fulfill.har'))} }});
|
||||||
|
test('pass', async ({ page }) => {
|
||||||
|
await page.goto('http://no.playwright/');
|
||||||
|
expect(await page.evaluate('window.value')).toBe('foo');
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
}, { workers: 1 });
|
||||||
|
expect(result.exitCode).toBe(0);
|
||||||
|
expect(result.passed).toBe(1);
|
||||||
|
});
|
||||||
|
|
|
||||||
2
utils/generate_types/overrides-test.d.ts
vendored
2
utils/generate_types/overrides-test.d.ts
vendored
|
|
@ -173,6 +173,7 @@ type BrowserName = 'chromium' | 'firefox' | 'webkit';
|
||||||
type BrowserChannel = Exclude<LaunchOptions['channel'], undefined>;
|
type BrowserChannel = Exclude<LaunchOptions['channel'], undefined>;
|
||||||
type ColorScheme = Exclude<BrowserContextOptions['colorScheme'], undefined>;
|
type ColorScheme = Exclude<BrowserContextOptions['colorScheme'], undefined>;
|
||||||
type ExtraHTTPHeaders = Exclude<BrowserContextOptions['extraHTTPHeaders'], undefined>;
|
type ExtraHTTPHeaders = Exclude<BrowserContextOptions['extraHTTPHeaders'], undefined>;
|
||||||
|
type HAROptions = Exclude<BrowserContextOptions['har'], undefined>;
|
||||||
type Proxy = Exclude<BrowserContextOptions['proxy'], undefined>;
|
type Proxy = Exclude<BrowserContextOptions['proxy'], undefined>;
|
||||||
type StorageState = Exclude<BrowserContextOptions['storageState'], undefined>;
|
type StorageState = Exclude<BrowserContextOptions['storageState'], undefined>;
|
||||||
type ServiceWorkerPolicy = Exclude<BrowserContextOptions['serviceWorkers'], undefined>;
|
type ServiceWorkerPolicy = Exclude<BrowserContextOptions['serviceWorkers'], undefined>;
|
||||||
|
|
@ -215,6 +216,7 @@ export interface PlaywrightTestOptions {
|
||||||
deviceScaleFactor: number | undefined;
|
deviceScaleFactor: number | undefined;
|
||||||
extraHTTPHeaders: ExtraHTTPHeaders | undefined;
|
extraHTTPHeaders: ExtraHTTPHeaders | undefined;
|
||||||
geolocation: Geolocation | undefined;
|
geolocation: Geolocation | undefined;
|
||||||
|
har: HAROptions | undefined;
|
||||||
hasTouch: boolean | undefined;
|
hasTouch: boolean | undefined;
|
||||||
httpCredentials: HTTPCredentials | undefined;
|
httpCredentials: HTTPCredentials | undefined;
|
||||||
ignoreHTTPSErrors: boolean | undefined;
|
ignoreHTTPSErrors: boolean | undefined;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue