mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-13 17:14:02 +03:00
test(har): add more har tests (#14997)
This commit is contained in:
parent
aaafb77036
commit
883e4d449a
@ -194,44 +194,34 @@ class HarBackend {
|
||||
const harLog = this._harFile.log;
|
||||
const visited = new Set<HAREntry>();
|
||||
while (true) {
|
||||
const entries = harLog.entries.filter(entry => entry.request.url === url && entry.request.method === method);
|
||||
const entries: HAREntry[] = [];
|
||||
for (const candidate of harLog.entries) {
|
||||
if (candidate.request.url !== url || candidate.request.method !== method)
|
||||
continue;
|
||||
if (method === 'POST' && postData && candidate.request.postData) {
|
||||
const buffer = await this._loadContent(candidate.request.postData);
|
||||
if (!buffer.equals(postData))
|
||||
continue;
|
||||
}
|
||||
entries.push(candidate);
|
||||
}
|
||||
|
||||
if (!entries.length)
|
||||
return;
|
||||
|
||||
let entry: HAREntry | undefined;
|
||||
let entry = entries[0];
|
||||
|
||||
// Disambiguate using headers - then one with most matching headers wins.
|
||||
if (entries.length > 1) {
|
||||
// Disambiguating requests
|
||||
|
||||
// 1. Disambiguate using postData - this covers GraphQL
|
||||
if (!entry && postData) {
|
||||
for (const candidate of entries) {
|
||||
if (!candidate.request.postData)
|
||||
continue;
|
||||
const buffer = await this._loadContent(candidate.request.postData);
|
||||
if (buffer.equals(postData)) {
|
||||
entry = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const list: { candidate: HAREntry, matchingHeaders: number }[] = [];
|
||||
for (const candidate of entries) {
|
||||
const matchingHeaders = countMatchingHeaders(candidate.request.headers, headers);
|
||||
list.push({ candidate, matchingHeaders });
|
||||
}
|
||||
|
||||
// Last. Disambiguate using headers - then one with most matching headers wins.
|
||||
if (!entry) {
|
||||
const list: { candidate: HAREntry, matchingHeaders: number }[] = [];
|
||||
for (const candidate of entries) {
|
||||
const matchingHeaders = countMatchingHeaders(candidate.request.headers, headers);
|
||||
list.push({ candidate, matchingHeaders });
|
||||
}
|
||||
list.sort((a, b) => b.matchingHeaders - a.matchingHeaders);
|
||||
entry = list[0].candidate;
|
||||
}
|
||||
|
||||
} else {
|
||||
entry = entries[0];
|
||||
list.sort((a, b) => b.matchingHeaders - a.matchingHeaders);
|
||||
entry = list[0].candidate;
|
||||
}
|
||||
|
||||
|
||||
if (visited.has(entry))
|
||||
throw new Error(`Found redirect cycle for ${url}`);
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
import { browserTest as it, expect } from '../config/browserTest';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import extractZip from '../../packages/playwright-core/bundles/zip/node_modules/extract-zip';
|
||||
|
||||
it('should fulfill from har, matching the method and following redirects', async ({ contextFactory, isAndroid, asset }) => {
|
||||
it.fixme(isAndroid);
|
||||
@ -192,3 +194,91 @@ it('should round-trip har.zip', async ({ contextFactory, isAndroid, server }, te
|
||||
expect(await page2.content()).toContain('hello, world!');
|
||||
await expect(page2.locator('body')).toHaveCSS('background-color', 'rgb(255, 192, 203)');
|
||||
});
|
||||
|
||||
it('should round-trip extracted 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 harDir = testInfo.outputPath('hardir');
|
||||
await extractZip(harPath, { dir: harDir });
|
||||
|
||||
const context2 = await contextFactory({ har: { path: path.join(harDir, 'har.har') } });
|
||||
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)');
|
||||
});
|
||||
|
||||
it('should round-trip har with postData', async ({ contextFactory, isAndroid, server }, testInfo) => {
|
||||
it.fixme(isAndroid);
|
||||
server.setRoute('/echo', async (req, res) => {
|
||||
const body = await req.postBody;
|
||||
res.end(body.toString());
|
||||
});
|
||||
|
||||
const harPath = testInfo.outputPath('har.zip');
|
||||
const context1 = await contextFactory({ recordHar: { path: harPath } });
|
||||
const page1 = await context1.newPage();
|
||||
await page1.goto(server.EMPTY_PAGE);
|
||||
const fetchFunction = async (body: string) => {
|
||||
const response = await fetch('/echo', { method: 'POST', body });
|
||||
return await response.text();
|
||||
};
|
||||
|
||||
expect(await page1.evaluate(fetchFunction, '1')).toBe('1');
|
||||
expect(await page1.evaluate(fetchFunction, '2')).toBe('2');
|
||||
expect(await page1.evaluate(fetchFunction, '3')).toBe('3');
|
||||
await context1.close();
|
||||
|
||||
const context2 = await contextFactory({ har: { path: harPath } });
|
||||
const page2 = await context2.newPage();
|
||||
await page2.goto(server.EMPTY_PAGE);
|
||||
expect(await page2.evaluate(fetchFunction, '1')).toBe('1');
|
||||
expect(await page2.evaluate(fetchFunction, '2')).toBe('2');
|
||||
expect(await page2.evaluate(fetchFunction, '3')).toBe('3');
|
||||
expect(await page2.evaluate(fetchFunction, '4').catch(e => e)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should disambiguate by header', async ({ contextFactory, isAndroid, server }, testInfo) => {
|
||||
it.fixme(isAndroid);
|
||||
|
||||
server.setRoute('/echo', async (req, res) => {
|
||||
res.end(req.headers['baz']);
|
||||
});
|
||||
|
||||
const harPath = testInfo.outputPath('har.zip');
|
||||
const context1 = await contextFactory({ recordHar: { path: harPath } });
|
||||
const page1 = await context1.newPage();
|
||||
await page1.goto(server.EMPTY_PAGE);
|
||||
|
||||
const fetchFunction = async (bazValue: string) => {
|
||||
const response = await fetch('/echo', {
|
||||
method: 'POST',
|
||||
body: '',
|
||||
headers: {
|
||||
foo: 'foo-value',
|
||||
bar: 'bar-value',
|
||||
baz: bazValue,
|
||||
}
|
||||
});
|
||||
return await response.text();
|
||||
};
|
||||
|
||||
expect(await page1.evaluate(fetchFunction, 'baz1')).toBe('baz1');
|
||||
expect(await page1.evaluate(fetchFunction, 'baz2')).toBe('baz2');
|
||||
expect(await page1.evaluate(fetchFunction, 'baz3')).toBe('baz3');
|
||||
await context1.close();
|
||||
|
||||
const context2 = await contextFactory({ har: { path: harPath } });
|
||||
const page2 = await context2.newPage();
|
||||
await page2.goto(server.EMPTY_PAGE);
|
||||
expect(await page2.evaluate(fetchFunction, 'baz1')).toBe('baz1');
|
||||
expect(await page2.evaluate(fetchFunction, 'baz2')).toBe('baz2');
|
||||
expect(await page2.evaluate(fetchFunction, 'baz3')).toBe('baz3');
|
||||
expect(await page2.evaluate(fetchFunction, 'baz4')).toBe('baz1');
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user