What is Network Interception?
Modern web applications constantly communicate with backend services through REST APIs, GraphQL APIs, authentication endpoints, analytics services, payment gateways, and third-party integrations.
Playwright Network Interception allows automation engineers to intercept these network requests before they reach the server.
Instead of depending on a live backend, your tests can inspect, modify, block, or replace requests and responses. This capability makes automated tests faster, more reliable, and easier to execute in CI/CD environments.
Network Interception is one of the main reasons Playwright is widely adopted for enterprise automation because it enables complete control over application behavior during testing.
Why Network Interception Matters
Without interception, automated tests depend on:
- API availability
- Database state
- Network speed
- Third-party services
- Authentication servers
If any of these systems fail, UI tests may fail even though the application's frontend works correctly.
Network interception allows engineers to isolate the frontend and verify its behavior independently.
Benefits include:
- Faster execution
- Stable automation
- Independent frontend testing
- Easier debugging
- Better negative testing
- Reduced flaky tests
Understanding route()
Playwright intercepts requests using page.route().
await page.route('**/api/products', async route => {
await route.continue();
});This intercepts every request matching the specified URL pattern.
Continuing Requests
Sometimes you simply want to observe traffic without modifying it.
await page.route('**/api/users', async route => {
console.log(route.request().url());
await route.continue();
});The request proceeds normally.
Blocking Requests
You can simulate network failures.
await page.route('**/*.png', route => route.abort());This blocks image downloads.
This technique speeds up UI automation because unnecessary resources are never downloaded.
Mocking API Responses
Instead of calling the real backend:
await page.route('**/api/products', async route => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
products: [
{
id: 1,
name: 'Playwright Book'
}
]
})
});
});The application believes the server returned this response.
Modifying Requests
Modify Request Headers
await page.route('**/api/orders', async route => {
const headers = {
...route.request().headers(),
Authorization: 'Bearer TEST_TOKEN'
};
await route.continue({
headers
});
});Useful for testing authorization scenarios.
Modify POST Data
await page.route('**/api/login', async route => {
const request = route.request();
console.log(request.postData());
await route.continue();
});Engineers often inspect request payloads before allowing them to continue.
Modifying Responses
You can also alter real responses before they reach the browser.
await page.route('**/api/products', async route => {
const response = await route.fetch();
const json = await response.json();
json.products[0].name = 'Mocked Product Name';
await route.fulfill({
response,
body: JSON.stringify(json)
});
});This is powerful for testing edge cases that are hard to reproduce on a real backend.
Simulating Server Errors
Testing error handling is critical.
await page.route('**/api/products', async route => {
await route.fulfill({
status: 500,
body: 'Internal Server Error'
});
});Now you can verify that the UI displays proper error messages.
Simulate Slow Networks
await page.route('**/api/orders', async route => {
await new Promise(resolve =>
setTimeout(resolve, 3000)
);
await route.continue();
});Useful for loading indicator validation.
Mocking Authentication APIs
Authentication APIs can also be mocked.
await page.route('**/login', async route => {
await route.fulfill({
status: 200,
body: JSON.stringify({
token: 'mock-token'
})
});
});Tests become independent of authentication servers.
Testing Offline Scenarios
You can simulate complete network failures.
await page.context().setOffline(true);Verify:
- Offline messages
- Retry buttons
- Cached data
- Error handling
Enterprise Framework Examples
Many enterprise frameworks centralize network mocks.
src/
mocks/
product.mock.ts
order.mock.ts
user.mock.ts
payment.mock.ts
auth.mock.tsTests remain clean.
test('Checkout', async ({
checkoutPage,
productMock
}) => {
// Test logic only
});Best Practices
- Mock only when necessary.
- Test real APIs separately.
- Keep mock data realistic.
- Store mock JSON in dedicated files.
- Reuse mocks across tests.
- Verify both success and failure scenarios.
Common Mistakes
Mocking everything.
Some tests should always call the real backend.
Hardcoding mock data inside test files.
Store reusable mock responses separately.
Ignoring negative scenarios.
Always test:
- 404
- 401
- 403
- 500
- Network timeout
Interview Questions
What is Network Interception?
The ability to inspect, modify, block, or replace HTTP requests and responses during automation.
Difference between continue() and fulfill()?
continue() sends the original request. fulfill() returns a mocked response without contacting the server.
When should API Mocking be used?
- UI testing
- Offline testing
- Third-party integrations
- Error scenarios
- Faster execution
Why do enterprise teams use Network Interception?
To create stable, repeatable automation independent of backend availability.
Real-World Mocking Scenarios
Network interception becomes valuable the moment your UI depends on data you cannot reliably produce on demand. In real projects, that situation shows up constantly, and each case has a slightly different mocking strategy.
Empty States and First-Time Users
Product teams spend a lot of design effort on empty states — the dashboard a brand-new user sees before any data exists. Reproducing that state against a real backend usually means creating a fresh account for every run, which is slow and pollutes the database. Intercepting the list endpoint and fulfilling it with an empty array gives you a deterministic empty state in milliseconds, with no test data cleanup afterwards.
Pagination and Large Data Sets
Verifying that a table paginates correctly at 500 rows does not require 500 real records. Generate the payload in the test, return it from a mocked route, and assert on page size, page controls, and total counts. The same technique lets you test virtual scrolling and performance-sensitive rendering without seeding a database.
Third-Party and Payment Providers
Payment gateways, mapping services, analytics collectors, and identity providers are outside your control. They rate limit, they go down, and they charge money for traffic. Intercepting those hosts and returning canned responses keeps your suite fast and free of third-party flakiness, while still exercising the code paths in your own application that handle their responses.
Error and Degraded-Service Paths
A resilient frontend must handle 401 sessions expiring mid-session, 429 rate limits, 500 server errors, and slow responses that trigger loading skeletons. Forcing those conditions against a live backend is nearly impossible. With route interception, each one is a two-line mock, which is why error-path coverage is usually the single biggest win teams get from adopting interception.
Mock vs Real API: How to Decide
The most common mistake teams make after learning interception is mocking everything. A suite where every response is faked proves that your UI can render JSON you wrote yourself — it proves nothing about the contract between frontend and backend. The healthier model is a layered strategy.
- Mock in UI component and page-level tests where the goal is rendering, state, and user interaction.
- Use the real API in a smaller set of end-to-end journeys that validate the integration contract.
- Always mock third-party services you do not own, in every layer.
- Always mock destructive or costly operations such as real payments, SMS sends, and outbound email.
- Never mock the endpoint that is the actual subject of the test.
A practical ratio many enterprise teams settle on is roughly seventy percent mocked UI tests, twenty percent real-backend integration journeys, and ten percent contract tests that compare mocked fixtures against live schema. That mix keeps the suite fast without letting your mocks silently drift away from reality.
Keeping Mocks Honest
Mocked payloads rot. The backend adds a required field, renames a property, or changes a status code, and your mocked tests keep passing while production breaks. Guard against this by storing mock fixtures in a single shared folder, validating them against the API schema in CI, and running a nightly job that executes a subset of the suite against the real backend. If the fixture no longer matches the live contract, the nightly run fails and you fix the fixture before it hides a real defect.
Debugging Network Interception
When a route handler does not seem to fire, the cause is almost always one of a handful of issues. Work through them in order rather than guessing.
- The glob or regex pattern does not match. Log every request URL first, then narrow the pattern to what you actually see.
- The route was registered after navigation started. Register handlers before page.goto(), not after.
- The handler is registered on the wrong object. page.route() covers one page; context.route() covers every page and popup in the context.
- A more specific handler registered later is taking precedence, because Playwright matches handlers in reverse registration order.
- The request is served from the browser or service worker cache and never reaches the network layer at all.
Playwright's trace viewer is the fastest way to confirm what actually happened. Run with tracing enabled, open the trace, and inspect the network tab: every request shows whether it was fulfilled, continued, or aborted, along with the response body that the page received. Pairing that with a temporary catch-all route that logs each URL will resolve the overwhelming majority of interception problems in a few minutes.
Frequently Asked Questions
Does mocking make my tests less valuable?
Only if it replaces integration coverage entirely. Mocking makes UI tests faster and more deterministic; it is a complement to a smaller set of real-backend tests, not a substitute for them.
Can I intercept WebSocket traffic?
Playwright exposes WebSocket frames for inspection and supports routing WebSocket connections in recent versions, but the ergonomics differ from HTTP routing. For most applications, asserting on received frames is sufficient.
How do I mock only some requests to the same endpoint?
Inspect the request inside the handler. Check the method, query string, or post body, then call fulfill() for the cases you want to fake and continue() for everything else. A single handler can serve both paths.
Do mocks work in headed and headless mode equally?
Yes. Interception happens at Playwright's network layer, below the browser UI, so behaviour is identical in headed, headless, and CI environments.
Summary
Network Interception is one of Playwright's most powerful enterprise features.
By controlling HTTP requests and responses, automation engineers can isolate frontend behavior, simulate failures, improve execution speed, and build highly reliable test suites.
Mastering Network Interception is essential for advanced Playwright automation and is frequently discussed in senior SDET interviews.
Complete professional Playwright + TypeScript enterprise framework
Production-grade architecture, fixtures, reporters and CI/CD — ready to run.
Get Playwright tutorials in your inbox
Weekly tips, real-world examples, and framework patterns – no spam, unsubscribe anytime.
Playwright Framework Series
View all →- 1Getting Started with Playwright: Installation, Setup, and Your First Test
- 2Playwright Locators: The Complete Guide with Real-World Examples
- 3Playwright Actions: Complete Guide to Click, Fill, Hover, Keyboard, Mouse & File Upload
- 4Playwright Assertions Complete Guide: Web-First Assertions, Auto-Retry & Custom Matchers
- 5Playwright Auto Waiting: The Complete Guide with Real-World Examples
- 6Playwright Fixtures: The Complete Guide with Real-World Examples
- 7Playwright Browser Context & Multiple Tabs: The Complete Guide with Real-World Examples
- 8Playwright Authentication & Session Management: Complete Guide with Enterprise Examples
- 9Playwright Network Interception & API Mocking: Complete Guide with Real-World Examples
- 10Playwright Page Object Model (POM): The Complete Guide with Enterprise Examples
- 11Page Object Model with Playwright: A Practical Guide
- 12How to Build a Robust Professional Playwright Framework from Scratch (Step-by-Step)
- 13Building an Enterprise Playwright Framework from Scratch
API Testing Series
View all →- 1Part 1 : Playwright API Testing Tutorial: Build Enterprise-Level API Automation Framework
- 2Part 2: Playwright API Testing Tutorial: Setting Up Project & Sending Your First API Request
- 3Part 3: Mastering CRUD Operations in Playwright API Testing
- 4Part 4: Authentication in Playwright API Testing (Bearer Token, JWT, API Key & Reusable Fixtures)
- 5Part 5: Building an Enterprise-Level Playwright API Automation Framework
- 6Part 6: API Models, Schema Validation & Test Data Management in Playwright
- 7Part 7: Custom Fixtures, Hooks, Logging & Parallel Execution in Playwright API Testing
- 8Part 8: Building a Production-Ready Playwright API Framework (Environment Management, CI/CD, Reporting & Best Practices)
- 9Part 9: Advanced Playwright API Testing Techniques for Enterprise Automation
- 10Part 10: Building a Complete Enterprise Playwright API Automation Framework (Final Part)
- 11Playwright Backend Testing Tutorial – REST API, GraphQL, WebSocket, Kafka, Database & Microservices