The problem, dynamic content on a critical page
For this test we’re using the demo Danube web shop, testing a book’s detail page for the correct product information.
book-details.spec.ts
Options for testing dynamic content
Here are some of the paths we could take with dynamic information like a book’s rating or stock number on our demo site. All of these approaches are workable for some subset of dynamic content on pages we want to test, but we want to understand all four to create stable tests in every situation:- Don’t test the dynamic content - only test things that should remain constant like the book title. This is often our default approach, but obviously means that we miss testing big chunks of the page.
-
Populate our test assertions with an API call - if details like price are constantly shifting, it may make sense to have our test start with a request to our API, loading in details from that API, and using that response to create our assertion dynamically. One problem with this approach: if we make assertions based on the same API as the page, we’re no longer ‘testing’ that this API response looks right to us, since the response sets the requirements. For example if the API responded
stock:"potato"
, both the page and the test would just check for “Left in stock: potato” and the test would pass. -
Make our assertion dynamic with a regular expression - right now our final assertion is
await expect(page.locator('#app-content')).toContainText('Left in stock: 1');
but thetoContainText
assertion will accept a regex, so we could write a passing test with:await expect(page.locator('#app-content')).toContainText(/Left in stock: \d/);
Numbers other than 1 would now pass, but if the page rendered “Left in stock: potato” the test would fail. Solving this (and most other) dynamic content problems with a regex has two major drawbacks:- When writing easy-to-maintain testing, a regex should not be the tool we use first. Not every developer finds regex patterns easy to read or edit.
- Not everything is particularly easy to test with regex, for example the
rating
api response here comes back as Unicode stars like “★★★★☆,” which isn’t as straightforward to test with regex as a digit.
- Modify the API response - Finally the option that gives us high consistency in what we’re testing and what we expect in response. By modifying the API response we can set only the key value pairs that concern us to fixed values, letting the others remain dynamic. We test how the page renders with fixed data, and we’re still testing that the API is available.
The Solution: Modify an API response with await *page*.route()
Let’s start by looking at the API response in full, from the network tab of either our browser or the Playwright UI mode. The body looks as follows
book-api-response.json
"stock"
value to be the same every time. The process is easy.
Before we load this page, let’s add a call to page.route()
to modify the network requests made by the page:
mock-book-details.spec.ts

Going Further: Mocking Whole APIs
If we’re able to intercept a request and change a single key/value pair, can we replace an entire payload from an API request? Sure, in fact we don’t need to wait for the real API to respond. the new version would look something like this:full-mock-api.spec.ts

Going Further: Replacing API responses to stress test our page
The last use case for API mocking and response editing is simulating an unusual circumstance on a live page. For example, on our page we expect that a book with zero remaining stock should show up as sold out.
out-of-stock-test.spec.ts

Editing API responses and visual regression tests
As we find ourselves testing correct rendering of a page under unusual conditions, this does suggest a visual regression test to make sure a page looks correct. Visual regression tests shouldn’t be a default mode for functionality testing, but they are part of our toolkit and editing dynamic API responses can be an effective way of making sure that a page is always rendering with identical data for visual comparison.
Results and Conclusions: Playwright Mocking and Testing in Production
With Playwright mocking you can remain tightly in control of API responses your page is using to render pages for users. This tool can help you in testing against production by ensuring that even with your production pages and data sources, your testing always sees consistent results. The result is more in-depth testing with higher reliability and fewer false alarms. And when a feature isn’t working correctly for users, you can find out before they complain. With Playwright’s powerful API mocking capabilities, you gain precise control over the responses your web pages use to render content for users. This functionality is particularly valuable when testing against production environments, as it ensures consistent results even when dealing with dynamic data sources. By leveraging tools likepage.route()
, you can simulate various scenarios—such as out-of-stock items, unusual data inputs, or edge cases—without needing to alter your production database or backend systems.
Key Takeaways:
- Consistency in Testing: By mocking API responses, you can create stable and reliable tests that are not affected by fluctuating data, such as stock numbers or ratings. This reduces false positives and ensures your tests are always accurate.
- Flexibility: Playwright allows you to modify specific parts of an API response or replace the entire payload, giving you the flexibility to test a wide range of scenarios, from stress testing to edge cases.
- Speed and Efficiency: Mocking API responses can significantly speed up test execution by eliminating the need to wait for real API calls. This is especially useful for large-scale testing or when testing under time constraints.
- Improved Debugging: By controlling API responses, you can isolate and test specific UI behaviors, making it easier to identify and fix issues in your application.
- Visual Regression Testing: Mocking dynamic content ensures that visual regression tests are consistent, allowing you to create reliable “golden files” for comparison.
When to Use API Mocking:
- Testing Dynamic Content: Use mocking to stabilize tests for elements that frequently change, such as stock levels, prices, or ratings.
- Stress Testing: Simulate unusual or extreme conditions (e.g., zero stock, large numbers, or long text) to ensure your UI handles them gracefully.
- Edge Case Testing: Test how your application behaves under rare or unexpected conditions without needing to replicate those conditions in your production environment.
- Visual Regression Testing: Ensure consistent screenshots for visual comparisons by fixing dynamic content in place.
Limitations and Considerations:
- Real API Availability: While mocking is powerful, it’s important to occasionally test against real API responses to ensure your production APIs are functioning correctly.
- Maintenance: Mocked responses need to be updated if the structure of your API changes, so keep your mocks in sync with your API contracts.
- Over-Mocking: Avoid mocking everything, as this can lead to tests that don’t reflect real-world behavior. Use mocking strategically to complement, not replace, real API testing.