> ## 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.

# Device CLI

> Let your coding agent run the device and your app for you — it sees the screen and taps by description, with no locators and no coordinates.

Your coding agent can take the phone out of your hands. It opens your app on a real device, sees what's on screen, taps and types its way through, and tells you what happened — you stay in your editor. This page is what it can do there. How agents connect to noqa is on [CLI & MCP](/guide/cli-and-mcp); setup and every option live in the [CLI reference](/docs/cli).

## Connect a device

```bash theme={null}
noqa devices ios                       # list iOS devices & simulators (or: noqa devices android)
noqa devices connect <device-id>       # connect to one from the list
noqa action activate-app --bundle-id com.example.app   # bring your app to the foreground
```

One device is active at a time, and every screen read and action goes to it.

## Read the screen

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

Your agent reads the screen on **every** step, so how it reads drives the token bill. The three ways differ enormously — measured on the same screen (the Lingua Talks paywall):

| Approach                               |  Tokens | vs `noqa screen` |
| -------------------------------------- | ------: | ---------------: |
| `noqa screen` — cleaned element tree   |   \~800 |               1× |
| Screenshot (vision)                    | \~1,500 |             \~2× |
| `noqa screen --full` — raw Appium tree | \~5,600 |             \~7× |

* **`noqa screen --full`** is the raw accessibility tree straight from Appium — every wrapper, container, and duplicated label. Complete, but noisy and heavy, and it balloons on complex screens.
* **A screenshot** is cheap in tokens, but it's pixels only: the model has to infer where elements are and read small text visually, which hurts tap precision and misses anything off-screen.
* **`noqa screen`** is our cleaned element tree — the redundant nodes stripped, the meaningful elements kept with their exact bounding boxes. Here that's **\~7× fewer tokens than the raw tree, and lighter than a screenshot** — while still giving precise, structured positions to act on.

## Act by description

Working out pixel coordinates from a screenshot is where agents lose their footing: a tap lands 40 pixels off and the run is wrong from there. So the CLI takes the target in plain language and noqa **grounds** it — finds that element on the current screen and places the touch itself.

```bash theme={null}
noqa action tap -d "Blue login button at the bottom"    # tap
noqa action tap -d "Login button" --double              # double tap
noqa action tap -d "Login button" --duration 2          # long-press, in seconds
noqa action swipe -d "photo carousel, swipe left"       # swipe
noqa action drag -d "card onto the drop zone"           # drag
noqa action input -d "email field" --text "hi@noqa.ai"  # type into a field
```

Describe what a person would look for — position, colour, and the words on it all help ("the X in the top-right corner of the paywall"). Grounding is free; it only needs an account.

It works where locators don't, because it never asks the app for an element tree: a Unity button, a WebView, an ad overlay and a native control are all just things on the screen.

If grounding puts the touch in the wrong place, fall back to the relative coordinates you just read from `noqa screen` (`0–1000` on both axes):

```bash theme={null}
noqa action tap --x 500 --y 320                         # tap
noqa action swipe --x1 500 --y1 800 --x2 500 --y2 200   # swipe between two points
noqa action input --x 500 --y 640 --text "hi@noqa.ai"   # tap a field and type
```

## Control the app and the system

```bash theme={null}
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
noqa action background-app                              # send the current app to the background
noqa action open-url --url "https://noqa.ai"            # open a deep link or URL
noqa action alert --action accept                       # accept a system alert (or --action dismiss)
```

`restart-app` is how your agent gets back to a known state without touching the device by hand.

## The loop

Put together, it's **inspect → act → verify**, one step at a time and never an action fired blind:

1. **Inspect** — `noqa screen` to confirm the target is there and the UI is in the expected state.
2. **Act** — one `noqa action …`, by description.
3. **Verify** — `noqa screen` again, or `noqa screenshot` for a visual check.

That loop is enough to check a feature you just built. To turn it into saved tests that run on every release, see [Full-cycle testing](/guide/full-cycle-testing).

<CardGroup cols={2}>
  <Card title="Full-cycle testing" icon="rotate" href="/guide/full-cycle-testing">
    From a build to passing tests
  </Card>

  <Card title="CLI reference" icon="terminal" href="/docs/cli">
    Every command and option
  </Card>
</CardGroup>
