Skip to content

NoamGaash/playwright-advanced-har

Repository files navigation

🎭 playwright-advanced-har

npm version Build and test the library

Playwright-advanced-har is a library that allows various use-cases for network record-and-playback, including:

  • ignoring post data and get arguments
  • ignoring the base-url when serving HAR files (good when you record network in test environment and play on staging/production)
  • ignoring aborted requests and requests that had errors

install

npm install playwright-advanced-har

usage

The playwright-advanced-har provides a playwright fixture called advancedRouteFromHAR. Here is an example of using a custom matcher to ignore 500 status code errors:

import { test, defaultMatcher, customMatcher } from "playwright-advanced-har";

test("don't route responses that have errors", async ({ page, advancedRouteFromHAR }) => {
	await advancedRouteFromHAR("tests/har/first-has-error.har", {
		matcher: (request, entry) => {
			if (entry.response.status >= 500 && entry.response.status < 600) {
				return -1;
			}
			return defaultMatcher(request, entry);
		},
	});

	await page.goto("https://noam-gaash.co.il");
	await page.getByText("Hello World").waitFor();
});

The matcher arguments is a callback function that receives the request and the HAR entry and returns a number. The number indicates how "good" the response is. Negative numbers (such as -1) tells the router to ignore the entry, while positive numbers indicates the entry is a qualified candidate to be routed from.

examples

ignoring port numbers:

test("ignore port number", async ({ page, advancedRouteFromHAR }) => {
	await advancedRouteFromHAR("tests/har/different-port.har", {
		matcher: customMatcher({
			urlComparator(a, b) {
				a = a.replace(/:\d+/, "");
				b = b.replace(/:\d+/, "");
				return a === b;
			},
		}),
	});
	await page.goto("https://noam-gaash.co.il");
	await page.getByText("from different port").waitFor();
});

choosing arbitrary responses:

test("pick arbirtrary response", async ({ page, advancedRouteFromHAR }) => {
	// good when you're testing a long polling requests
	await advancedRouteFromHAR("tests/har/differentNumbers.har", {
		matcher: customMatcher({
			scoring() {
				return Math.random();
			},
		}),
	});
	await page.goto("https://noam-gaash.co.il");
	await page.getByText("1234").waitFor();
});

apply post-proccessing on the chosen HAR entry:

test("get the largest number... squared!", async ({ page, advancedRouteFromHAR }) => {
	// the file contains 3 responses - 42, 1234, 5
	await advancedRouteFromHAR("tests/har/differentNumbers.har", {
		matcher: {
			postProcess(entry) {
				entry.response.content.text = (parseInt(entry.response.content.text || "0") ** 2).toString();
				return entry;
			},
			matchFunction: customMatcher({
				scoring: (request, entry) => parseInt(entry.response.content.text || "0"),
			}),
		}
	});
	await page.goto("https://noam-gaash.co.il");
	await page.getByText((1234**2).toString()).waitFor();
});

for more examples, please see our tests directory

Contribution

Contributions are welcome! Please open an issue with a use-case before opening a PR, so we can discuss it. Make sure you add tests and run npm run test before commiting.

Install dependencies

npm install

Run tests

npm test

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •