mirror of
https://github.com/microsoft/playwright.git
synced 2024-11-24 06:49:04 +03:00
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.har = %%-js-context-option-har-%%
|
||||
|
||||
## property: TestOptions.hasTouch = %%-context-option-hastouch-%%
|
||||
|
||||
## property: TestOptions.headless = %%-browser-option-headless-%%
|
||||
|
@ -141,6 +141,7 @@ export const test = _baseTest.extend<TestFixtures, WorkerFixtures>({
|
||||
deviceScaleFactor: [ undefined, { option: true } ],
|
||||
extraHTTPHeaders: [ undefined, { option: true } ],
|
||||
geolocation: [ undefined, { option: true } ],
|
||||
har: [undefined, { option: true }],
|
||||
hasTouch: [ undefined, { option: true } ],
|
||||
httpCredentials: [ undefined, { option: true } ],
|
||||
ignoreHTTPSErrors: [ undefined, { option: true } ],
|
||||
@ -168,6 +169,7 @@ export const test = _baseTest.extend<TestFixtures, WorkerFixtures>({
|
||||
colorScheme,
|
||||
deviceScaleFactor,
|
||||
extraHTTPHeaders,
|
||||
har,
|
||||
hasTouch,
|
||||
geolocation,
|
||||
httpCredentials,
|
||||
@ -199,6 +201,8 @@ export const test = _baseTest.extend<TestFixtures, WorkerFixtures>({
|
||||
options.extraHTTPHeaders = extraHTTPHeaders;
|
||||
if (geolocation !== undefined)
|
||||
options.geolocation = geolocation;
|
||||
if (har !== undefined)
|
||||
options.har = har;
|
||||
if (hasTouch !== undefined)
|
||||
options.hasTouch = hasTouch;
|
||||
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 ColorScheme = Exclude<BrowserContextOptions['colorScheme'], undefined>;
|
||||
type ExtraHTTPHeaders = Exclude<BrowserContextOptions['extraHTTPHeaders'], undefined>;
|
||||
type HAROptions = Exclude<BrowserContextOptions['har'], undefined>;
|
||||
type Proxy = Exclude<BrowserContextOptions['proxy'], undefined>;
|
||||
type StorageState = Exclude<BrowserContextOptions['storageState'], undefined>;
|
||||
type ServiceWorkerPolicy = Exclude<BrowserContextOptions['serviceWorkers'], undefined>;
|
||||
@ -2699,6 +2700,14 @@ export interface PlaywrightTestOptions {
|
||||
*/
|
||||
extraHTTPHeaders: ExtraHTTPHeaders | 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.
|
||||
*/
|
||||
|
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(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 lines = output.split('\n');
|
||||
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.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([{
|
||||
name: 'video',
|
||||
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.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 ColorScheme = Exclude<BrowserContextOptions['colorScheme'], undefined>;
|
||||
type ExtraHTTPHeaders = Exclude<BrowserContextOptions['extraHTTPHeaders'], undefined>;
|
||||
type HAROptions = Exclude<BrowserContextOptions['har'], undefined>;
|
||||
type Proxy = Exclude<BrowserContextOptions['proxy'], undefined>;
|
||||
type StorageState = Exclude<BrowserContextOptions['storageState'], undefined>;
|
||||
type ServiceWorkerPolicy = Exclude<BrowserContextOptions['serviceWorkers'], undefined>;
|
||||
@ -215,6 +216,7 @@ export interface PlaywrightTestOptions {
|
||||
deviceScaleFactor: number | undefined;
|
||||
extraHTTPHeaders: ExtraHTTPHeaders | undefined;
|
||||
geolocation: Geolocation | undefined;
|
||||
har: HAROptions | undefined;
|
||||
hasTouch: boolean | undefined;
|
||||
httpCredentials: HTTPCredentials | undefined;
|
||||
ignoreHTTPSErrors: boolean | undefined;
|
||||
|
Loading…
Reference in New Issue
Block a user