Backend Development 5 min read

Mocking API Responses with Playwright: Success, Errors, Latency, Pagination, and Conditional Logic

This article demonstrates how to use Playwright to mock various API responses—including successful login, dynamic data, network latency, pagination, HTTP errors, redirects, authentication failures, custom headers, not‑found resources, and conditional responses—by defining route handlers that fulfill requests with custom status codes, bodies, and headers.

Test Development Learning Exchange
Test Development Learning Exchange
Test Development Learning Exchange
Mocking API Responses with Playwright: Success, Errors, Latency, Pagination, and Conditional Logic

Mock login success

Scenario: In login testing, simulate a successful server response by returning a fake JWT token without calling the real API.

def login_success_mock(route):
    if "/login" in route.request().url and route.request().method == 'POST':
        route.fulfill(
            status=200,
            headers={"Content-Type": "application/json"},
            body=json.dumps({"token": "mocked_token"})
        )
    else:
        route.continue_()
with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    context = browser.new_page()
    context.route("**/api/login*", login_success_mock)
    # login operation...

Dynamic API response

Scenario: Generate different responses based on request parameters to simulate multiple API interaction scenarios.

def dynamic_response(route):
    params = parse_qs(urlparse(route.request().url).query)
    if params.get('type') == ['success']:
        route.fulfill(status=200, body=json.dumps({"status": "success", "data": "mocked_data"}))
    else:
        route.fulfill(status=400, body=json.dumps({"status": "error", "message": "Invalid request"}))
context.route("**/api/dynamic*", dynamic_response)

Simulate network latency

Scenario: Test application behavior under slow network conditions by adding a three‑second delay before responding.

import time

def latency(route):
    time.sleep(3)  # simulate 3‑second delay
    route.fulfill(status=200, body='{"response": "delayed"}')
context.route("**/api/slow*", latency)

Simulate paginated data

Scenario: In pagination testing, return different data sets for each page number.

def paginated_response(route):
    page_number = int(route.request().url.split('/')[-1])
    mock_data = [{"id": i} for i in range(page_number*10, page_number*10 + 10)]
    route.fulfill(status=200, body=json.dumps({"page": page_number, "items": mock_data}))
context.route("**/api/items/page/*", paginated_response)

Simulate HTTP error

Scenario: Verify application handling of server errors such as 500 Internal Server Error.

def http_error(route):
    route.fulfill(status=500, body='{"message": "Internal Server Error"}')
context.route("**/api/error*", http_error)

Simulate redirect

Scenario: Mock a 302 redirect from one URL to another.

def redirect(route):
    route.fulfill(status=302, headers={"Location": "http://example.com/mock-redirect-target"})
context.route("**/api/redirect*", redirect)

Simulate authorization failure

Scenario: Mock an authentication failure by returning a 401 Unauthorized response.

def auth_failure(route):
    route.fulfill(status=401, body=json.dumps({"message": "Unauthorized"}))
context.route("**/api/auth*", auth_failure)

Simulate custom HTTP headers

Scenario: Add or modify specific HTTP headers in the mocked response.

def custom_headers(route):
    route.fulfill(status=200, headers={"X-Mock-Header": "mocked_value"}, body='{}')
context.route("**/api/headers*", custom_headers)

Simulate resource not found

Scenario: Mock a 404 Not Found error for missing resources.

def not_found(route):
    route.fulfill(status=404, body='{"message": "Resource not found"}')
context.route("**/api/nonexistent*", not_found)

Conditional response based on request body

Scenario: Dynamically decide the mocked response by inspecting the POST request payload.

def conditionally_mocked_response(route):
    request_body = json.loads((await route.request().post_data_buffer()).decode())
    if request_body["key"] == "mock":
        route.fulfill(status=200, body=json.dumps({"mocked": True}))
    else:
        route.continue_()
context.route("**/api/conditional*", conditionally_mocked_response)
Automationtestingbackend developmentPlaywrightAPI mocking
Test Development Learning Exchange
Written by

Test Development Learning Exchange

Test Development Learning Exchange

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.