Manuals / Playwright with Python / Ch 25

Part 4 · Advanced TechniquesAdvanced50 min read

17. Network Interception & Mocking

Playwright with Python · 244 pages source format

page.route() basics page.route() intercepts network requests matching a URL pattern before they reach the server, letting you inspect, modify, block, or fully replace the response. def handle_route(route): route.continue_() # let it through unchanged page.route("**/*.png", handle_route) page.route(url_pattern, handler) What it does: Registers an interceptor for any request matching a URL pattern.

What you'll learn

  • Mocking API responses
  • 500 for error-state testing
  • Blocking resources (images, ads) for speed

Overview

the server, letting you inspect, modify, block, or fully replace the response.

Run / study this snippet
page.route() basics
Interactive study board
OverviewDrag stickies · tap for tips
Study mapDrag stickies · tap for tipsKeep it shortdrag · tap →Name the waitdrag · tap →Scope locatorsdrag · tap →Trace when stuckdrag · tap →One browser firstdrag · tap →Isolate statedrag · tap →Assert the UIdrag · tap →Retry wiselydrag · tap →Seed datadrag · tap →Close the loopdrag · tap →Keep it shortdrag · tap →Name the waitdrag · tap →Scope locatorsdrag · tap →Trace when stuckdrag · tap →One browser firstdrag · tap →Isolate statedrag · tap →Pathwise hackdrag · tap →Page under testdrag · tap →Multi-browserdrag · tap →Automation pathdrag · tap →Tooling nodedrag · tap →
Clear?

page.route(url_pattern, handler)

What it does: Registers an interceptor for any request matching a URL pattern.

Types/params:

Pointers: Every matched request must be resolved by the handler (continue/fulfill/abort) or the request hangs indefinitely. Register routes before the navigation/action that triggers the request.

  • url_pattern (string or regex, required)
  • Glob string, e.g. "**/api/users", "**/*.png" — ** matches any path segment
  • Regex, e.g. re.compile(r".*/api/.*") for more complex matching
  • handler (function, required) — receives a route object; must call exactly one of
route.continue_(), route.fulfill(), or route.abort()
Interactive study board
page.route(url_pattern, handler)Drag stickies · tap for tips
Study mapDrag stickies · tap for tipsKeep it shortdrag · tap →Name the waitdrag · tap →Scope locatorsdrag · tap →Trace when stuckdrag · tap →One browser firstdrag · tap →Isolate statedrag · tap →Assert the UIdrag · tap →Retry wiselydrag · tap →Seed datadrag · tap →Close the loopdrag · tap →Keep it shortdrag · tap →Name the waitdrag · tap →Scope locatorsdrag · tap →Trace when stuckdrag · tap →One browser firstdrag · tap →Isolate statedrag · tap →Pathwise hackdrag · tap →Page under testdrag · tap →Multi-browserdrag · tap →Automation pathdrag · tap →Tooling nodedrag · tap →
Clear?

Mocking API responses

This lets you test UI behavior for scenarios that are hard to trigger naturally — server errors, empty states, slow responses — without needing the actual backend to cooperate.

What it does: Responds to the intercepted request with custom data instead of letting it reach the real server.

Types/params:

Run / study this snippet
def mock_users_api(route):
    route.fulfill(
        status=200,
        content_type="application/json",
        body='{"users": [{"id": 1, "name": "Test User"}]}'
    )
Interactive study board
Mocking API responsesDrag stickies · tap for tips
Study mapDrag stickies · tap for tipsKeep it shortdrag · tap →Name the waitdrag · tap →Scope locatorsdrag · tap →Trace when stuckdrag · tap →One browser firstdrag · tap →Isolate statedrag · tap →Assert the UIdrag · tap →Retry wiselydrag · tap →Seed datadrag · tap →Close the loopdrag · tap →Keep it shortdrag · tap →Name the waitdrag · tap →Scope locatorsdrag · tap →Trace when stuckdrag · tap →One browser firstdrag · tap →Isolate statedrag · tap →Pathwise hackdrag · tap →Page under testdrag · tap →Multi-browserdrag · tap →Automation pathdrag · tap →Tooling nodedrag · tap →
Clear?

500 for error-state testing

Pointers: Use json= instead of manually building a body JSON string where possible

— less error-prone. Mocking error statuses (500, 403) is one of the highest-value uses here, since these are notoriously hard to trigger from a real backend on demand.

What it does: Lets the request proceed to the real server, optionally with modifications.

Types/params:

Pointers: Use this when you only want to observe or slightly tweak a request (e.g., inject a test header) rather than fully replace the response.

What it does: Blocks the request entirely, simulating a network failure.

Types/params:

"timedout", "connectionrefused"

Pointers: Useful for testing how the UI handles total network failure (not just an error response, but no response at all) — a distinct code path from a mocked 500.

  • content_type (string, optional) — MIME type, e.g. "application/json", "text/html"
  • body (string, optional) — the response body content, typically a JSON string for API mocks
  • json (dict, optional alternative to body) — pass a Python dict directly and Playwright serializes it to JSON automatically
  • headers (dict, optional) — override or add request headers
  • method (string, optional) — override the HTTP method
  • post_data (string, optional) — override the request body
  • error_code (string, optional, default "failed") — e.g. "failed",
Run / study this snippet
route.abort(error_code=...)
Interactive study board
500 for error-state testingDrag stickies · tap for tips
Study mapDrag stickies · tap for tipsKeep it shortdrag · tap →Name the waitdrag · tap →Scope locatorsdrag · tap →Trace when stuckdrag · tap →One browser firstdrag · tap →Isolate statedrag · tap →Assert the UIdrag · tap →Retry wiselydrag · tap →Seed datadrag · tap →Close the loopdrag · tap →Keep it shortdrag · tap →Name the waitdrag · tap →Scope locatorsdrag · tap →Trace when stuckdrag · tap →One browser firstdrag · tap →Isolate statedrag · tap →Pathwise hackdrag · tap →Page under testdrag · tap →Multi-browserdrag · tap →Automation pathdrag · tap →Tooling nodedrag · tap →
Clear?

Blocking resources (images, ads) for speed

Run / study this snippet
def block_images(route):
    if route.request.resource_type == "image":
        route.abort()
    else:
        route.continue_()
Interactive study board
Blocking resources (images, ads) for speedDrag stickies · tap for tips
Study mapDrag stickies · tap for tipsKeep it shortdrag · tap →Name the waitdrag · tap →Scope locatorsdrag · tap →Trace when stuckdrag · tap →One browser firstdrag · tap →Isolate statedrag · tap →Assert the UIdrag · tap →Retry wiselydrag · tap →Seed datadrag · tap →Close the loopdrag · tap →Keep it shortdrag · tap →Name the waitdrag · tap →Scope locatorsdrag · tap →Trace when stuckdrag · tap →One browser firstdrag · tap →Isolate statedrag · tap →Pathwise hackdrag · tap →Page under testdrag · tap →Multi-browserdrag · tap →Automation pathdrag · tap →Tooling nodedrag · tap →
Clear?

route.request.resource_type

What it does: Read-only property identifying the category of the intercepted request.

Types/params:

"xhr", "fetch", "font", "media"

Pointers: Blocking images/fonts/ad-tracker scripts on tests that don't need to visually verify them can meaningfully speed up a large suite — but don't block resources your test actually depends on rendering correctly (defeats visual regression testing in Chapter 19).

Interactive study board
route.request.resource_typeDrag stickies · tap for tips
Study mapDrag stickies · tap for tipsKeep it shortdrag · tap →Name the waitdrag · tap →Scope locatorsdrag · tap →Trace when stuckdrag · tap →One browser firstdrag · tap →Isolate statedrag · tap →Assert the UIdrag · tap →Retry wiselydrag · tap →Seed datadrag · tap →Close the loopdrag · tap →Keep it shortdrag · tap →Name the waitdrag · tap →Scope locatorsdrag · tap →Trace when stuckdrag · tap →One browser firstdrag · tap →Isolate statedrag · tap →Pathwise hackdrag · tap →Page under testdrag · tap →Multi-browserdrag · tap →Automation pathdrag · tap →Tooling nodedrag · tap →
Clear?

Checklist