# karagoz tap

Taps a point, or finds one node in the tree and taps its center.

- Android emulator Done
- Android device Done
- iOS simulator Done
- iOS device Done

## Usage

```console title="~/app"
karagoz tap <x> <y> [--duration <ms>] [--device <id>]
karagoz tap --text <label> [--timeout <ms>] [--duration <ms>] [--device <id>]
karagoz tap --id <resource-id> [--timeout <ms>] [--duration <ms>] [--device <id>]
```

Give exactly one of `<x> <y>`, `--text` or `--id`.

## Before you start

- On Android: the screen on and unlocked. With the screen off, taps are dropped and the command still exits `0`.
- On Android, for `--text` and `--id`: no other UiAutomation client connected (Appium, Maestro, `uiautomator events`).
- On an iOS simulator: Xcode 27 or newer, opened once.
- On an iPhone: paired with the Mac, Developer Mode on, connected by USB cable, Settings > Developer > Enable UI Automation on, and Karagöz’s runner installed with [`install-runner`](https://karagozmcp.com/docs/commands/install-runner/).

## Point or node?

Times on Android; the iOS sections below give theirs.

|                                  | Point: `<x> <y>`        | Node: `--text` or `--id`                                                                 |
| -------------------------------- | ----------------------- | ---------------------------------------------------------------------------------------- |
| Speed                            | About 0.2 s             | Adds one tree read, 2.5 to 3.3 s                                                         |
| Finds the target                 | No: you give the pixels | Yes, in the [tree](https://karagozmcp.com/docs/commands/ui-tree/)                        |
| Can wait for it                  | No                      | Yes, with `--timeout`                                                                    |
| With another UiAutomation client | Works                   | Fails with [`AUTOMATION_BUSY`](https://karagozmcp.com/docs/error-codes/#automation-busy) |

## Options

| Option               | Default                                                               | Meaning                                                                                                                                                                      |
| -------------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `<x> <y>`            |                                                                       | A point in [screen pixels](https://karagozmcp.com/docs/output/#coordinates). Non-negative, decimals allowed (`12`, `12.5`).                                                  |
| `--text <label>`     |                                                                       | A node whose `text` or `contentDesc` equals the label: whole string, case-sensitive, no trimming. Invisible direction marks (U+200E and the like) are ignored on both sides. |
| `--id <resource-id>` |                                                                       | A node whose `resourceId` equals the value, or ends with `:id/<value>`. `--id save` matches `com.example:id/save`.                                                           |
| `--duration <ms>`    | none                                                                  | Hold for this long (a long press). Whole milliseconds, 0 to 999999999.                                                                                                       |
| `--timeout <ms>`     | `0`                                                                   | Keep reading the tree until a node matches or this much time has passed. Only with `--text` or `--id`.                                                                       |
| `--device <id>`      | see [Device selection](https://karagozmcp.com/docs/device-selection/) |                                                                                                                                                                              |

## Examples

### Tap a point

```console title="~/app"
$ karagoz tap 540 1200
{"device":"emulator-5554","x":540,"y":1200}
```

### Tap a node by its text

```console title="~/app"
$ karagoz tap --text Chrome
{"device":"emulator-5554","x":667.5,"y":2002.5,"element":{"class":"android.widget.TextView","text":"Chrome","contentDesc":"Chrome","clickable":true,"longClickable":true,"focusable":true,"bounds":[581,1905,754,2100]}}
```

### Hold with `--duration`

```console title="~/app"
$ karagoz tap 540 1200 --duration 10
{"device":"emulator-5554","x":540,"y":1200,"duration":10}
```

## Output

```json
{
  "device": "emulator-5554",
  "x": 667.5,
  "y": 2002.5,
  "element": {
    "class": "android.widget.TextView",
    "text": "Chrome",
    "contentDesc": "Chrome",
    "clickable": true,
    "longClickable": true,
    "focusable": true,
    "bounds": [581, 1905, 754, 2100]
  }
}
```

- `device` string: Serial, or the simulator's or iPhone's UDID.
- `x` number: With `<x> <y>`: a point in [screen pixels](https://karagozmcp.com/docs/output/#coordinates), non-negative, decimals allowed. With `--text` or `--id`: the center of `element`.
- `y` number: With `<x> <y>`: a point in screen pixels, non-negative, decimals allowed. With `--text` or `--id`: the center of `element`.
- `element` object: The matched node as [`ui-tree`](https://karagozmcp.com/docs/commands/ui-tree/) returns it, without `children`.
- `element.class` string: Android class, e.g. `android.widget.Button`. Can be empty.
- `element.text` string: Only when not empty. Jetpack Compose puts text in `text`, Flutter puts it in `contentDesc`.
- `element.contentDesc` string: Only when not empty. Jetpack Compose puts text in `text`, Flutter puts it in `contentDesc`.
- `element.clickable` boolean: Only when `true`.
- `element.longClickable` boolean: Only when `true`.
- `element.focusable` boolean: Only when `true`.
- `element.bounds` array: `[left, top, right, bottom]` in screen pixels.
- `element.role` string: On an iOS simulator, the accessibility subrole when there is one, else the role, without the `AX` prefix. On an iPhone, XCTest's element type.
- `element.label` string: On iOS, only when not empty: what VoiceOver reads.
- `element.identifier` string: On iOS, only when not empty: the app's `accessibilityIdentifier`.
- `duration` number: Only with `--duration`, right after `y`: how long the tap was held, in whole milliseconds.

**Exit 0 is not proof the app reacted**

Exit `0` means Android accepted the event, not that the app reacted to it. Read the tree again to check.

```console title="Read, tap, check"
# 1. find the target
$ karagoz ui-tree
# 2. tap it
$ karagoz tap --text Chrome
# 3. read again: did the screen change?
$ karagoz ui-tree
```

## How a node is found

### What matches

- The tap goes to the center of the node that matched, not to a clickable parent.
- Nodes with zero-size bounds never match.

### When the tap is refused

- A parent and a child that both match are two matches: [`ELEMENT_AMBIGUOUS`](https://karagozmcp.com/docs/error-codes/#element-ambiguous).
- If the keyboard is visible and the node’s center is inside it, the tap is refused with [`ELEMENT_COVERED`](https://karagozmcp.com/docs/error-codes/#element-covered). Only the keyboard is checked; bubbles and picture-in-picture windows are not.

### Waiting with `--timeout`

- Only “no match” triggers another read, and it starts right away. The last read can end up to one read (about 3 s) past the timeout. The tap itself is never repeated.
- The screen can change between the read and the tap; the tap then lands on the old point.

## Errors

| Code                                                                              | When                                                                                                                                                              |
| --------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`INVALID_ARGS`](https://karagozmcp.com/docs/error-codes/#invalid-args)           | No target or more than one (`'tap' takes <x> <y>, --text or --id`), a single coordinate (`'tap' needs <x> <y>`), `--timeout` with a point, or a malformed number. |
| [`ELEMENT_NOT_FOUND`](https://karagozmcp.com/docs/error-codes/#element-not-found) | `no node with text or contentDesc 'Save' in com.example (1 read in 2.6 s)`.                                                                                       |
| [`ELEMENT_AMBIGUOUS`](https://karagozmcp.com/docs/error-codes/#element-ambiguous) | The message lists up to five matches with class and bounds. Pick one and tap its coordinates.                                                                     |
| [`ELEMENT_COVERED`](https://karagozmcp.com/docs/error-codes/#element-covered)     | The node is under the keyboard. Close the keyboard with `karagoz key BACK`.                                                                                       |

Node taps also get every [`ui-tree` error](https://karagozmcp.com/docs/commands/ui-tree/#errors). Every tap can also get [`INPUT_BLOCKED`](https://karagozmcp.com/docs/error-codes/#input-blocked), the [device selection errors](https://karagozmcp.com/docs/device-selection/#errors) and the adb errors.

## Notes

- A long press with `--duration`: View and Compose use the device’s long-press setting (`settings get secure long_press_timeout`; 400 ms on stock Android, Samsung offers 300 to 1500 ms), Flutter 500 ms.
- Points are not checked against the screen size.

## On an iOS simulator

Same arguments and output. The point goes to the simulator’s own input service as a real touch, and `--duration` holds it there.

```json
{
  "device": "27024DC1-EDB0-4BF2-8010-08FE3936BAB6",
  "x": 603,
  "y": 1015,
  "element": {
    "role": "Button",
    "label": "Tap me 0",
    "identifier": "tap-button",
    "bounds": [48, 937, 1158, 1093]
  }
}
```

- `--text` matches a node’s `label` or `value`, `--id` its `identifier`; both whole and case-sensitive, direction marks ignored. There is no `:id/` rule.

- The node is tapped at its center like a finger, so what covers it gets the tap.

- There is no keyboard check on a simulator.

- The message for no match is `no node with label or value 'Save' in the frontmost app (1 read in 0.3 s)`.

- A tap takes about 0.6 s; a node tap adds one tree read, about 0.3 s.

- The first of `ui-tree`, `tap`, `swipe`, `text` or `key` on a simulator compiles a small [helper](https://karagozmcp.com/docs/requirements/#cache-folder), which takes a few seconds.

- Errors:

  - [`NOT_SUPPORTED`](https://karagozmcp.com/docs/error-codes/#not-supported) with Xcode 26 or older.
  - [`DEVICE_NOT_READY`](https://karagozmcp.com/docs/error-codes/#device-not-ready) when the input service does not answer within 4 s (a simulator that has just booted).
  - [`HELPER_FAILED`](https://karagozmcp.com/docs/error-codes/#helper-failed).
  - For node taps, the [`ui-tree` errors on iOS](https://karagozmcp.com/docs/commands/ui-tree/#on-an-ios-simulator).

## On an iPhone

Same arguments and output. Karagöz’s runner plays the touch; it is started and stopped as for [`ui-tree`](https://karagozmcp.com/docs/commands/ui-tree/#on-an-iphone), and installed with `install-runner`. The pixels are turned into the panel’s points for the interface orientation.

- `--text` and `--id` match as on the simulator. Unlike there, a node whose center the on-screen keyboard covers is refused with `ELEMENT_COVERED` (a key of the keyboard itself can be tapped). Hide the keyboard first, for example with `key ENTER` in a single-line field.
- `--duration` holds for that long. For a 0.5 s long press, 500 ms did not trigger it and 550 ms did.
- A tap takes about 0.6 s; the first after the runner stopped about 3.3 s.
- Errors: those of `ui-tree` on an iPhone, with `HELPER_FAILED` for a touch the runner could not play.

## MCP equivalent

MCP equivalent `tap {"text":"Chrome"}` [MCP tools](https://karagozmcp.com/docs/mcp/#tools)

Arguments: `x`, `y`, `text`, `id`, `duration`, `timeout`, `device`. The names are the CLI's option and positional names.

## Related commands

- [karagoz ui-tree](https://karagozmcp.com/docs/commands/ui-tree/): Find a node's text, id and bounds before the tap, and read the screen again after it.
- [karagoz install-runner](https://karagozmcp.com/docs/commands/install-runner/): Install the runner that plays the touch on an iPhone.
