I am setting up our testing on Playwright. The idea is to only test behaviour of the front-end with given HTTP responses, so I'm saving HTTP requests to a HAR file on first run and then routing everything from a file on successive test runs.
I read from documentation (https://playwright.dev/docs/mock#replaying-from-har) that
HAR replay matches URL and HTTP method strictly. For POST requests, it also matches POST payloads strictly. If multiple recordings match a request, the one with the most matching headers is picked.
So I want to make sure that calls to the same resource (i.e. get collection) are matched to the correct responses (for example if one is done before and one after making a modification to a resource.
My thought was to append a unique header to each request.
But looking at the resulting HAR file, the new header is not added to any requests. What am I doing wrong? Here's the full code to the fixture I'm using:
This thread is trying to answer question "Why is the new header not added to any requests in the resulting HAR file when testing on Playwright?"
import { test as base } from '@playwright/test';
import { existsSync } from 'fs';
import getTestFileName from './getTestFileName';
import sanitizeHar from './sanitizeHar';
const apiUrlsGlob = '**/api/portal/**';
/**
* Overwrites the default `page` fixture with our custom one that checks for the existence of a HAR file in a given location
* If that file exists, it's used to mock HTTP requests during the test
* If it doesn't exist, new browser context is created that records network activity into a new HAR file
*/
export const test = base.extend({
page: async ({ page, browser, browserName }, use, testInfo) => {
/**
* Assign a unique header to each request so that they're matched to their mocks in HAR files in the correct order
*/
let requestIndex = 1;
await page.route(apiUrlsGlob, async (route) => {
route.continue({
headers: {
...route.request().headers(),
'Playwright-Request-Index': (requestIndex++).toString(),
},
});
});
const harFilePath = getTestFileName(testInfo.title, browserName);
console.debug(`Checking HAR file at: ${harFilePath}`);
if (existsSync(harFilePath)) {
console.debug('HAR file found, using it for the test');
await page.routeFromHAR(harFilePath, {
notFound: 'abort',
url: apiUrlsGlob,
});
await use(page);
} else {
console.debug(
'HAR file not found, running test without it and recording answers to a new HAR file'
);
const browserContext = await browser.newContext({
recordHar: {
path: harFilePath,
mode: 'minimal',
urlFilter: apiUrlsGlob,
},
});
const page = await browserContext.newPage();
// Run the test
await use(page);
await browserContext.close();
await sanitizeHar(harFilePath);
}
},
});
Rayrun is a community for QA engineers. I am constantly looking for new ways to add value to people learning Playwright and other browser automation frameworks. If you have feedback, email [email protected].