# Run tests from the terminal

> Start a run, wait for its result and download its evidence.

Source: https://rehearsal.dev/docs/cli/run-tests

The CLI runs the tests you saved in Rehearsal. The tests run on Rehearsal's servers, and the terminal follows them. You create and change tests in the app, with Re:agent.

You need the CLI [signed in](https://rehearsal.dev/docs/cli/log-in.md). Starting a run needs **Manage projects**. Reading runs needs **View projects**.

## Choose a project once

Most commands work inside one workspace and one project. Save both in your repository, so you do not type them each time.

```sh
rehearsal workspaces list
rehearsal projects list --workspace <workspace-id>
rehearsal init --workspace <workspace-id> --project parcel
```

`init` writes `rehearsal.config.json` in the current folder. It holds identifiers and the project's slug, never a sign-in.

```json filename="rehearsal.config.json"
{
  "schemaVersion": 1,
  "workspaceId": "2f6e1c7a-8d4b-4e0a-9c55-3b1f0d7e6a21",
  "projectId": "parcel"
}
```

- Commands read the file from the current folder or any folder above it, up to the repository root.
- A flag, such as `--project`, wins over the file for that one command.
- `rehearsal context show` prints what is in use and where each value came from.
- `init` also offers to add a short note to `AGENTS.md`, so a coding agent knows this repository uses Rehearsal.

## Find the tests

```sh
rehearsal tests list
rehearsal suites list
```

Each test shows its status and its readiness. Readiness says what a run would do with the test today. Only a `ready` test gets checked. The run lists any other test it was given as not ready.

## Start a run

Rehearsal never picks the tests for you. Name them in one of three ways:

```sh
# Some tests, up to 200
rehearsal runs start --test <test-id> --test <test-id>
# One suite
rehearsal runs start --suite <suite-id>
# Every approved test of one app
rehearsal runs start --app web
```

`--test` and `--suite` take identifiers from the lists above. `--app` also takes the app's name or the host of one of its addresses.

```text
Run #42 is queued with 2 tests.
Identifier  7c1f0a9e-3b52-4d18-a6e4-5f2d9b8c0e13
Report      https://app.rehearsal.dev/parcel/projects/0b8d4e6f-1a2c-4f3e-9d7b-6c5a4e3f2d1b/results/42
Key         9b4e1d7c-2a6f-4c8e-b3d5-7f1a9c2e4b6d
  Wait for a verdict: rehearsal runs wait 7c1f0a9e-3b52-4d18-a6e4-5f2d9b8c0e13 --timeout 60s --json
```

The command returns as soon as Rehearsal records the run. A queued run has not passed anything yet, so wait for it.

### Choose where each app runs

Each app in a run is tested at one address. An app with one address needs nothing. For an app with several, name one with `--environment`:

```sh
rehearsal environments list --app web
rehearsal runs start --app web --environment staging
```

`--environment` takes a kind, such as `production`, `staging`, `preview` or `local`. It also takes a computer's name or an address identifier. Repeat it once for each app in the run.

- Leave it out for an app with several addresses, and nothing starts. The CLI answers `SELECTION_REQUIRED` and lists the addresses to choose from.
- Name a local address that nothing is connected to, and nothing starts. The CLI answers `ENVIRONMENT_OFFLINE`. [Connect the app](https://rehearsal.dev/docs/cli/connect-a-local-app.md) first.

### Ask again safely

Each run request carries a key. In a terminal, the CLI makes one for you. Before it sends the request, it prints the arguments that repeat it with the same key.

From a script, or with `--json`, pass your own key with `--idempotency-key`. Use 8 to 200 characters, such as a build number.

```sh
rehearsal runs start --suite <suite-id> --idempotency-key build-1842 --json
```

> [!NOTE]
> The same request with the same key returns the same run. If an answer never arrives, repeat the command with the same key. A new key starts a second run.

## Wait for the result

```sh
rehearsal runs wait 42 --timeout 10m
```

A run is named by its identifier or by the number the app shows. `runs wait` checks the run until it ends or the time is up. It waits 60 seconds unless you say otherwise, and 1 hour at most.

```text
Run #42 failed: a test failed
Identifier        7c1f0a9e-3b52-4d18-a6e4-5f2d9b8c0e13
Address           https://parcel.example.com
Selected          2
Passed            1
Failed            1
Needs review      0
Without a result  0
Time in tests     38s
Started           2026-09-23T10:14:05.000Z
Finished          2026-09-23T10:15:02.000Z
Report            https://app.rehearsal.dev/parcel/projects/0b8d4e6f-1a2c-4f3e-9d7b-6c5a4e3f2d1b/results/42

What failed
  Check out a cart (5b0e2c4d-7f91-4a3b-8e6d-2c1f0a9b8e77)
    step 4: Check the order confirmation
    expected: The confirmation page shows an order number.
    saw: expect(locator).toBeVisible() failed Locator: getByRole('heading', { name: 'Order confirmed' }) Expected: visible Timeo…
    error: expect(locator).toBeVisible() failed Locator: getByRole('heading', { name: 'Order confirmed' }) Expected: visible Timeout: 10000ms Error: element(s) not found
    screenshot of the step 4: 1f9c3e5a-7b2d-4f6e-8a0c-2d4f6b8e0a1c
    video of the whole test: 6e8a0c2e-4f6b-4d8f-a0c2-e4f6b8d0a2c4
    trace of the whole test: 4b6d8f0a-2c4e-4a6b-9d8f-0a2c4e6b8d0f
```

Below that, the CLI prints the commands that list and download the evidence.

The exit status says how the run ended: `0` when every selected test passed, `1` when a test failed. A script can stop on anything but `0`. [JSON output](https://rehearsal.dev/docs/cli/json-output.md) lists every code.

> [!NOTE]
> Stopping the wait, by timeout or `Ctrl+C`, never stops the run. To stop a run, use `rehearsal runs cancel <run-id>`.

## Read a run

```sh
rehearsal runs list --status failed
rehearsal runs get 42
rehearsal runs open 42
```

`runs get` prints the run as it stands. `runs open` opens the same run in the app, in your browser.

## Download evidence

```sh
rehearsal runs artifacts list 42
rehearsal runs artifacts download 42 --artifact <artifact-id> --output ./evidence
```

- A run keeps screenshots of each test's steps, a video and a Playwright trace.
- `--output` takes a folder or a file name. In a folder, the file keeps its own name.
- The CLI replaces a file that is already there only with `--force`.

Open a trace with Playwright to step through the test: `npx playwright show-trace trace.zip`.

## Run again and compare

```sh
rehearsal runs rerun 42
rehearsal runs compare 42 43
```

```text
Run #42 failed against run #43 passed
fixed  Check out a cart       5b0e2c4d-7f91-4a3b-8e6d-2c1f0a9b8e77  failed to passed
same   Apply a discount code  8e7d6c5b-4a39-4281-9f0e-d1c2b3a4f5e6  passed to passed
```

- `runs rerun` runs the same test versions again, at the same addresses. To test somewhere else, start a new run instead.
- `runs compare` lines up the tests of two runs, oldest first. A test reads `fixed` only if it failed before, passes now, and ran the same version at the same address.

## Next steps

- Read the [JSON output](https://rehearsal.dev/docs/cli/json-output.md) to use these commands from a script.
- Let [your coding agent](https://rehearsal.dev/docs/coding-agents/use-rehearsal.md) run the tests and read the failures.
- See every flag in the [Command reference](https://rehearsal.dev/docs/cli/commands.md).
