> ## Documentation Index
> Fetch the complete documentation index at: https://docs.noqa.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# CLI

> Drive noqa from your terminal — inspect devices, control the screen, manage test cases, and run tests without leaving the command line.

The noqa CLI brings the platform to your terminal: inspect devices, drive the screen, author and edit test cases, run them with the noqa agent, and read results — all scriptable, and easy to wire into CI or an AI coding agent.

It ships with the macOS desktop app and talks to it locally, so there's nothing separate to configure.

<Note>You need the noqa macOS app **running** and the **CLI installed**. To drive it with an AI agent, see [CLI for agents](/guide/cli-for-agents): skill setup, token-efficient screen reads, and the agent test loop.</Note>

## Setup

<Steps>
  <Step title="Install and open the app">
    [Download noqa](https://noqa.ai/download) and install it. **Keep the app running** — the CLI talks to it locally, so it must be open for any command to work. Sign in for account features (test management, running the agent); base commands work without an account.
  </Step>

  <Step title="Install the CLI">
    In the app, open **Settings → Tools** and click **Install CLI**. This links the `noqa` command into `~/.local/bin` and adds it to your `PATH` — no `sudo` required. Restart your terminal afterward.
  </Step>

  <Step title="Install the skill (for AI agents)">
    In the same **Settings → Tools**, click **Install skill** to install the `noqa-testing` skill for your coding agent, so it knows the commands and workflows. Skip it if you only use the CLI by hand. See [CLI for agents](/guide/cli-for-agents).
  </Step>

  <Step title="Verify">
    ```bash theme={null}
    noqa devices ios
    ```
  </Step>
</Steps>

## Base commands

No account and no app prefix needed. Connect a device first with `noqa devices connect` — `screen` and `action` run against the connected device.

### Devices

```bash theme={null}
noqa devices ios                             # list iOS devices & simulators (add --all to show every simulator)
noqa devices android                         # list Android devices & emulators (add --all to show every emulator)
noqa devices connect <device-id>             # open a session on a device (use the full ID from the list)
noqa devices active                          # show the currently connected device
```

### Inspect the screen

```bash theme={null}
noqa screen                                  # cleaned element tree — meaningful elements with relative coordinates (0–1000)
noqa screen --full                           # raw Appium accessibility tree (everything, unfiltered)
noqa screenshot ./shot.png                   # save a screenshot
```

<Note>For how `noqa screen`, `--full`, and a screenshot compare by token cost, see [Reading the screen](/guide/cli-for-agents#reading-the-screen-efficiently).</Note>

### Actions

Gestures (`tap`, `swipe`, `drag`, `pinch`, `input`) target an element two ways. **Prefer describing the element (grounding)** — it's the recommended approach; fall back to explicit relative coordinates only when needed.

**By description (automatic grounding, recommended)** — describe the element in plain language and noqa grounds it to the right spot on screen, no coordinates needed. Requires being signed in:

```bash theme={null}
noqa action tap --description "Login button"          # tap by description (-d for short)
noqa action tap -d "Login button" --double            # double tap
noqa action tap -d "Login button" --duration 2        # long-press for 2 seconds
noqa action swipe -d "photo carousel, swipe left"     # swipe by description
noqa action drag -d "card onto the drop zone"         # drag by description
noqa action pinch -d "map in the center" --direction in   # zoom in / enlarge (out to zoom out / shrink)
noqa action input -d "email field" --text "hi@noqa.ai"  # type into a field by description
```

**By coordinates (fallback)** — `0–1000`, relative to the screen; read them from `noqa screen`. Use when grounding mislocates a target or you already know the exact spot:

```bash theme={null}
noqa action tap --x 500 --y 320                          # tap
noqa action tap --x 500 --y 320 --double                 # double tap
noqa action tap --x 500 --y 320 --duration 2             # long-press for 2 seconds
noqa action swipe --x1 500 --y1 800 --x2 500 --y2 200    # swipe from one point to another
noqa action drag --x1 300 --y1 500 --x2 700 --y2 500     # drag from one point to another
noqa action pinch --direction in --x1 200 --y1 200 --x2 800 --y2 900   # zoom in over the area
noqa action input --x 500 --y 640 --text "hi@noqa.ai"    # tap a field and type text
```

App & system controls take no target:

```bash theme={null}
noqa action open-url --url "myapp://profile"             # open a deep link or URL on the device
noqa action alert --action accept                        # accept a system alert
noqa action alert --action dismiss                       # dismiss a system alert
noqa action activate-app --bundle-id com.example.app     # bring an app to the foreground
noqa action terminate-app --bundle-id com.example.app    # force-quit an app
noqa action restart-app --bundle-id com.example.app      # terminate and relaunch an app
noqa action background-app                               # send the current app to the background
```

## Test management

Author and maintain your test suite from the terminal — free, with an account. Every command here takes your **app prefix** as its first argument (shown as `APP`); find it with `noqa apps list`. See [Test Cases](/docs/test-cases) for how cases and flows fit together.

```bash theme={null}
noqa apps list                               # list apps (NAME, PREFIX)
```

### Apps & context

```bash theme={null}
noqa apps get APP                                              # app details, including its shared context
noqa apps update APP '{"name": "...", "app_context": "..."}'  # update name or context
```

`app_context` is a shared description injected into every run — credentials, screen names, and rules the agent should always follow. `update` overwrites, so read the current value first, then send the full replacement.

### Test cases

A test case has a title, optional tags, and a list of flows (steps + expected results).

```bash theme={null}
noqa cases list APP                          # list cases (ID, TITLE, TAGS)
noqa cases list APP --tag smoke              # filter by tag (repeat --tag for AND)
noqa cases get APP 42                        # show case 42 as JSON
noqa cases create APP '{"title": "Login", "tags": ["smoke"], "flows": [{"instructions": "tap login, enter credentials", "result": "home screen shows"}]}'   # create a case
noqa cases update APP 42 '{"title": "New title"}'   # update fields of case 42
noqa cases delete APP 42                             # delete case 42
```

Each flow is either **inline** (`{"instructions": "...", "result": "..."}`) or a **reference** to a reusable flow (`{"id": "..."}`) — never both. Tags are created automatically when named.

<Tip>For how to phrase instructions and expected results, see [Writing Good Test Cases](/guide/writing-test-cases).</Tip>

### Reusable flows & tags

A reusable flow is a named step shared across cases (e.g. "Go through onboarding"). Update it once and every case that references it updates too.

```bash theme={null}
noqa flows list APP                          # list reusable flows (ID, NAME, USES)
noqa flows get APP <flow-id>                 # show a flow as JSON
noqa flows create APP '{"name": "Onboarding", "instructions": "...", "result": "..."}'   # create a reusable flow
noqa flows update APP <flow-id> '{"name": "..."}'   # update fields of a flow
noqa flows delete APP <flow-id>              # delete a flow (fails while any case still uses it)

noqa tags APP                                # list tags (TAG, USES, CASES)
```

## Builds & test runs

Register builds and run test cases with the noqa agent on a connected device. Each run uses credits.

### Builds

```bash theme={null}
noqa builds list APP                         # list builds (local & cloud)
noqa builds create APP /abs/path/App.ipa     # register a build (.ipa/.app/.apk); add -n "name" to label it; version & bundle ID parsed for you
noqa builds delete APP <build-id>            # delete a build
```

<Note>Build paths must be **absolute** (e.g. `/Users/me/build/App.ipa`, not `build/App.ipa`).</Note>

### Run tests

Hand saved cases (by number) or ad-hoc cases (inline JSON) to the **noqa agent**, which runs them autonomously on the connected device.

```bash theme={null}
noqa runs create APP 1 2 5                            # run saved cases on the app already on the device
noqa runs create APP 1 2 5 --build-path /abs/App.ipa  # install a build first, then run
noqa runs create APP 1 2 5 --build-id <build-id>      # use a build from `noqa builds`
noqa runs create APP '[{"name": "Login", "flows": [{"instructions": "tap login", "result": "home shows"}]}]'  # ad-hoc, no saved case

noqa runs list APP                                    # list recent runs (ID, STATUS, TESTS, SOURCE, CREATED); -n limits, --offset pages
noqa runs get APP <run-id>                            # per-test pass/fail and check counts
noqa runs get APP <run-id> <test-id>                  # flows, expected results, and agent steps
noqa runs delete APP <run-id>                         # delete a run and its results
```

Omitting both build flags reuses whatever is already installed on the device — quick, but the app keeps its existing state across cases. Pass a build so each run starts clean for a regression suite. `--build-path` and `--build-id` are mutually exclusive; connect a device first with `noqa devices connect`.

<Warning>`delete` commands (`cases`, `flows`, `runs`, `builds`) are irreversible. Double-check the id before running.</Warning>

## Output & scripting

Most read commands accept `--json` for raw output you can pipe into `jq` or a script:

```bash theme={null}
noqa cases list APP --json | jq '.[].title'
```

Errors go to stderr with a non-zero exit code, so the CLI composes cleanly in CI pipelines and agent tooling.

<CardGroup cols={2}>
  <Card title="Test cases" icon="list-check" href="/docs/test-cases">
    How cases and flows work
  </Card>

  <Card title="CLI for agents" icon="robot" href="/guide/cli-for-agents">
    Let an AI agent drive the CLI
  </Card>
</CardGroup>
