Mock the dependency. Label the boundary.
A mocked quote can prove your UI handles a response. It cannot prove the quote service works. Keep both kinds of evidence without mixing their names.


A delivery quote fails during a release check. Is the checkout UI broken, is the quote provider unavailable, or has the test environment lost its credentials? One red result now represents several systems. A controlled response can help you examine the UI, but it changes what the result means.
This guide uses a small delivery-quote screen to show how to mock a dependency and label the evidence honestly. It is based on Playwright's mocking guide and network documentation. The screen shown here is a local illustrative demo with invented shipping options, not a customer workflow or a live service.
Decide which question the test answers
The UI question is whether the page displays a returned price, handles an empty list and explains an unavailable quote. The integration question is whether the real service accepts the request and returns the agreed response shape. You can test these separately and keep a smaller real-service check beside a deterministic UI suite.
Do not call the mocked path full end-to-end evidence for the service. Its value is narrower: your frontend receives known data and behaves correctly. That is useful evidence when named correctly. A green mock cannot tell you whether a provider changed its credentials, rejected your payload or stopped serving your region.
Install the route before the request happens
In this illustrative app, loading the quote page requests /api/delivery-quote. The example intercepts that exact path and returns a controlled JSON object. Register the handler before navigating so the first request cannot escape the intended setup.
await page.route('**/api/delivery-quote', async route => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ label: 'Standard', price: '4.00' })
});
});
await page.goto('/delivery-quote');
await expect(page.getByRole('status')).toHaveText('Standard: 4.00');Use a configured staging baseURL for this relative navigation. The response shape is our demo contract, not a universal delivery API. A real test should use your documented schema and currency rules. Match only the endpoint you mean to control; intercepting all traffic can hide unrelated failures.
Playwright's Route API distinguishes fulfilling a request from fetching a real response and modifying it. The example above does not call the upstream quote service. A route.fetch() example would have a different boundary because it still depends on the upstream response.
Test failure states without waiting for a vendor outage
Return a 503 response in a second test, then verify the page explains that the quote is unavailable and offers the intended next action. A third test can return a successful empty result if that is a meaningful state in your contract. Keep each setup small and explicit.
await page.route('**/api/delivery-quote', route =>
route.fulfill({ status: 503, body: 'Unavailable' })
);
await page.goto('/delivery-quote');
await expect(page.getByRole('alert')).toHaveText('Quote unavailable');These snippets belong in separate test cases. The app must implement that alert behavior; this is not a matcher that creates it. Verify that a user has a safe next step, not merely that some red text appears. Never fake a completed payment to prove that a real payment works.
Watch the blind spots
A service worker can intercept requests before Playwright's page or context routing sees them. The network documentation recommends blocking service workers when native routing is missing expected requests. Choose that setting deliberately in your controlled test configuration; changing it can remove behavior you otherwise need to test.
Browser-context routing can cover pages and popups within the context, whereas a page-level rule has a narrower scope. Decide which behavior you need rather than moving every rule to the broadest scope. Keep the test's route handlers and data inside its lifecycle.
Recorded HTTP archives can also replay traffic, but recordings may contain sensitive headers, cookies and response data. Review and sanitize a recording before storing it. For this simple quote case, a hand-authored response is easier to inspect than a large captured archive.
Give the evidence a name that survives the dashboard
Use a test title such as delivery quote UI, mocked provider response. In the review notes, state the controlled endpoint, contract version and separate real-service check. A teammate should not need to inspect route code to discover that the provider was absent.
AnyTest describes URL-led exploration and tests humans review. Apply the same evidence question to any proposed flow: which dependencies were real, which were controlled, and what does a pass establish? This guide does not claim a specific mocking interface inside AnyTest.
For a small QA team, the payoff is a clearer diagnosis path and deliberate failure-state coverage. For a developer-owned test suite, it is the same: keep repeatable UI checks, keep the integration boundary visible and do not let a convenient mock become a larger promise than the test can support.
Common questions
Mock the dependency. Label the boundary. - what should I keep in mind?
A mocked quote can prove your UI handles a response. It cannot prove the quote service works. Keep both kinds of evidence without mixing their names.
Are the examples a measured AnyTest result?
No. The examples illustrate testing techniques using Playwright. AnyTest describes web exploration and generated end-to-end tests for human review; no particular runner integration is claimed.