# Mocking requests

> Replace a request with test data or a network error to check how your app responds.

Source: https://rehearsal.dev/retest/docs/guides/mocking-requests

Use request mocking to test how your page handles a particular response or connection failure. You provide the response in the test, so you can exercise an error state without making the server fail.

## Answer a request

Add a route before the action that sends the request. In the task app, clicking Save sends a request to `/api/tasks` and displays the title from its response.

```ts filename="tests/tasks.retest.ts"
import { expect, test } from '@rehearsal-labs/retest'

test('shows the title returned by the server', async ({ page }) => {
  await page.route('**/api/tasks', {
    status: 200,
    contentType: 'application/json',
    body: JSON.stringify({ title: 'Release checklist' }),
  })

  await page.goto('/')
  await page.getByTestId('task-title').fill('Release checklist')
  await page.getByTestId('save-task').click()
  await expect(page.getByTestId('saved-task')).toHaveText('Release checklist')
})
```

Await `page.route()` so the mock is ready before the test continues. Matching requests receive its response before leaving the browser; other requests go to the network as usual.

The response is an object with optional `status`, `headers`, `contentType` and `body`. Status defaults to 200, and the body accepts text or bytes. The example checks the page's response handling; the mocked save never reaches the server.

## Match the right address

A string pattern matches the whole request address, including its query. `**` matches any characters, while `*` stops at a slash. Other characters match themselves, so `**/api/tasks` does not match `/api/tasks?page=1`.

Start a string pattern with `*` or a scheme such as `https://`. You can also pass a regular expression, which Retest searches for anywhere in the address. A pattern matches by address, so the same route answers every matching request regardless of its method.

## Exercise an error state

To check an error message, return an error status from the save endpoint. The task app displays the same message when the server refuses a save or the connection fails.

```ts
test('explains that a task could not be saved', async ({ page }) => {
  await page.route('**/api/tasks', { status: 503, body: 'Unavailable' })
  await page.goto('/')
  await page.getByTestId('task-title').fill('Release checklist')
  await page.getByTestId('save-task').click()
  await expect(page.getByTestId('saved-task')).toHaveText('Could not save')
})
```

To exercise a connection failure instead, replace the route above with this one. An aborted request has no response status or body.

```ts
await page.route('**/api/tasks', { abort: 'connectionrefused' })
```

A strict diagnostics policy also counts mocked errors. If your suite rejects error responses, allow the endpoint this test intentionally fails, as described in [Console and network](https://rehearsal.dev/retest/docs/guides/console-and-network.md).

## Replace or remove a route

When several routes match, the one added last answers. Remove routes with the pattern you originally passed, using the same string or the same regular expression source and flags.

```ts
await page.unroute('**/api/tasks')
```

`page.unroute()` removes every route added with that pattern. Removing a pattern you never added fails with `usage`. Routes end when the page closes, and a popup shares its opener's routes, so a change through either page affects both.

## Read the result

The report and `retest inspect --test` show route changes as steps. Network diagnostics mark mocked responses and connection failures with `mocked: true`, so you can distinguish them from real responses. Route events keep the status, header names and body size, without storing the body or header values.

Invalid patterns or answers fail with `usage`. If Chrome refuses a route's answer, Retest fails the request and the test reports `setup_failed`, naming that request. Keep credentials out of mock bodies because Retest treats them as test data.

## Platform support

Routes work on Chromium-family browsers. Firefox and WebKit report `unsupported`; Electron windows and native apps do not support request mocking.

A route covers the page and its same-site frames. Requests from a frame of another site or requests answered by a service worker bypass it. Use mocks for the page's requests, and test worker behaviour against the server.

## Next steps

- [Console and network](https://rehearsal.dev/retest/docs/guides/console-and-network.md): Read the requests a test made and the responses it received.
- [Test API](https://rehearsal.dev/retest/docs/reference/test-api.md): Look up route patterns and response options.
