I am currently using Playwright to test an application. For this purpose, I need to mock calls to my backend because the backend is not running during the tests, and I don’t want the tests to hit the real backend.
To achieve this, I am using page.route to mock the calls. At the beginning of my tests, I initialize a variable called requests, which is an array. Whenever page.route matches a route of interest, I add the request from the page.route function to this array:
test(`my test test`, async ({
page,
}) => {
const response = [...];
let requests: Request[] = [];
await page.route("**/api/endpoint**", (route, request) => {
if(request.method() == "POST") {
requests.push(request);
}
route.fulfill({
status: 200,
contentType: "application/json",
body: JSON.stringify(response),
});
});
// Doing my test stuff
...
// check if calls was successfully done
expect(requests).toHaveLength(1);
expect(requests[0].postDataJSON()).toHaveLength(2);
expect(requests[0].postDataJSON()).toBe({...});
At the end of the test, I need to verify that the mocked call was actually made during the test execution. I check whether the array is empty or not to determine if the call was triggered by the actions performed in my test.
However, I occasionally encounter an issue where the array does not contain the expected request after performing the action that should trigger the call. It seems that the test completes faster than the application sends out the request. To handle this, I am also using page.waitForResponse:
test(`my test test`, async ({
page,
}) => {
...
// STUFF
const [request] = await Promise.all([
page.waitForRequest(
request =>
request.url().includes("/api/endpoint") &&
request.method() === "POST",
),
button.click(), // this button click triggers the /api/endpoint call
]);
// check if calls was successfully done
expect(requests).toHaveLength(1);
expect(requests[0].postDataJSON()).toHaveLength(2);
expect(requests[0].postDataJSON()).toBe({...});
Can I streamline this process by omitting certain steps to avoid redundancy in my test? What are the best practices to achieve the goal of verifying that the mocked backend call was made?