# night-fury-cli

Interactive CLI for [`night-fury-core`](../night-fury-core/) browser automation.

## Install

```bash
cargo install night-fury-cli
```

For the full command guide, selector syntax, and examples, see [../docs/cli.md](../docs/cli.md).

## Usage

```bash
# Launch interactive REPL
nf --headed

# Navigate on launch
nf --url https://example.com

# Inject cookies at startup
nf --url https://example.com --cookies cookies.txt

# Route through proxy
nf --proxy http://user:pass@host:10000

# Machine-readable JSON output (agent / scripting mode)
nf --json --url https://example.com
```

## `--json` Flag

When `--json` is passed, every command outputs a JSON object:

```json
{ "ok": true, "data": "...", "msg": "..." }
{ "ok": false, "error": "Element not found" }
```

This makes it easy to pipe `nf` into scripts, agents, or CI pipelines.

## Commands

### Navigation

| Command | Description |
|---------|-------------|
| `go <url>` | Navigate to URL (aliases: `nav`, `navigate`) |
| `back` | History back |
| `forward` | History forward |
| `reload` | Reload page |
| `url` | Print current URL |
| `title` | Print page title |

### Interaction

| Command | Description |
|---------|-------------|
| `click <sel>` | Click element (alias: `c`) |
| `type <sel> <text>` | Type text into element (alias: `t`) |
| `scroll [px]` | Scroll page (default: 600px) |
| `hover <sel>` | Hover element |
| `select <sel> <value>` | Select dropdown option |
| `check <sel>` | Check checkbox |
| `uncheck <sel>` | Uncheck checkbox |
| `wait [ms]` | Wait (default: 1000ms, alias: `sleep`) |
| `wait element <sel> [timeout_ms]` | Wait for selector to appear |
| `wait load [timeout_ms]` | Wait for page load/navigation |
| `wait network [timeout_ms]` | Wait for network idle |
| `wait text <text> [timeout_ms]` | Wait until page text appears |
| `wait url <pattern> [timeout_ms]` | Wait until URL contains pattern |

### Capture

| Command | Description |
|---------|-------------|
| `snap` | Print page snapshot (aliases: `s`, `snapshot`) |
| `screenshot [file]` | Save PNG screenshot (alias: `ss`) |
| `pdf [file]` | Export current page as PDF |
| `eval <js>` | Evaluate JavaScript expression (alias: `js`) |

### Tabs

| Command | Description |
|---------|-------------|
| `tab new [url]` | Open new tab, optionally navigate |
| `tab switch <idx>` | Switch to tab by index |
| `tab list` | List all open tabs |
| `tab close [idx]` | Close tab (current if no index) |

### Queries

| Command | Description |
|---------|-------------|
| `get text <sel>` | Get element text content |
| `get attr <sel> <name>` | Get element attribute |
| `get html <sel>` | Get element innerHTML |
| `get value <sel>` | Get input value |
| `get count <sel>` | Count matching elements |
| `get box <sel>` | Get bounding box {x, y, width, height} |

### State

| Command | Description |
|---------|-------------|
| `is visible <sel>` | Check if element is visible |
| `is checked <sel>` | Check if checkbox is checked |
| `is enabled <sel>` | Check if element is enabled |

### Cookies

| Command | Description |
|---------|-------------|
| `cookies get` | List all cookies |
| `cookies set <file>` | Inject cookies from Netscape or JSON file |
| `cookies delete <name> <domain>` | Delete a specific cookie |
| `cookies clear` | Clear all cookies |

### Session

| Command | Description |
|---------|-------------|
| `session save [file]` | Save session (cookies + storage) |
| `session load <file>` | Restore session from file |

### Routes

| Command | Description |
|---------|-------------|
| `route block <pattern>` | Block requests matching pattern |
| `route fulfill <pattern> <status> <body>` | Mock response for pattern |
| `route capture <pattern>` | Capture response bodies for pattern |
| `route list` | Show captured responses |
| `route clear` | Remove all routes |

### Frames

| Command | Description |
|---------|-------------|
| `frame enter <sel>` | Switch context into iframe |
| `frame main` | Switch back to main frame |

### Storage

| Command | Description |
|---------|-------------|
| `storage get <local\|session> [key]` | Read one localStorage/sessionStorage key, or omit key to dump the selected store |
| `storage set <local\|session> <key> <value>` | Write to storage |
| `storage clear <local\|session>` | Clear storage |

### Clipboard

| Command | Description |
|---------|-------------|
| `clipboard read` | Read clipboard text |
| `clipboard write <text>` | Write text to clipboard |

### Mouse

| Command | Description |
|---------|-------------|
| `mouse move <x> <y>` | Move cursor to coordinates |
| `mouse wheel <delta>` | Scroll mouse wheel |
| `mouse down [button]` | Press mouse button |
| `mouse up [button]` | Release mouse button |

### Touch

| Command | Description |
|---------|-------------|
| `touch tap <x> <y>` | Simulate a tap |
| `touch swipe <x1> <y1> <x2> <y2>` | Simulate a swipe gesture |

### Emulation

| Command | Description |
|---------|-------------|
| `emulate tz <timezone>` | Set timezone (e.g. `Asia/Tokyo`) |
| `emulate locale <locale>` | Set locale (e.g. `ja-JP`) |
| `emulate media <feature> <value>` | Set media feature (e.g. `prefers-color-scheme dark`) |
| `emulate geo <lat> <lng>` | Set geolocation |

### Download

| Command | Description |
|---------|-------------|
| `download path <dir>` | Set download directory |
| `download wait [seconds]` | Wait for a download to complete |

### WebSocket

| Command | Description |
|---------|-------------|
| `ws start` | Start capturing WebSocket messages |
| `ws messages` | Print captured WebSocket messages |

### Coverage

| Command | Description |
|---------|-------------|
| `coverage start` | Start CSS/JS coverage collection |
| `coverage stop` | Stop coverage and print report |

### Other

| Command | Description |
|---------|-------------|
| `cdp <method> [json]` | Send raw CDP command with optional JSON params |
| `viewport <w> <h>` | Resize browser viewport |
| `headers <json>` | Set extra request headers (JSON object) |
| `auth <user> <pass>` | Set HTTP Basic/Digest auth credentials |
| `help` | Show all commands |
| `quit` | Exit (aliases: `exit`, `q`) |

## Selectors

- `@eN` — ref index from snapshot (e.g. `@e3`)
- `#id`, `.class`, `tag[attr]` — CSS selectors
- `text Sign in` — visible accessible text (prefix with `text `)

## Testing

```bash
# Unit + in-crate tests (command resolvers, argument parsers, helpers)
cargo test --bin nf -p night-fury-cli
```

60 tests cover every `CommandKind` variant (40 top-level commands + aliases),
11 sub-command resolvers (`cookies`, `tab`, `query`, `state`, `storage`,
`frame`, `clipboard`, `coverage`, `download`, `emulate`, `mouse`, `route`,
`session`, `touch`, `ws`, `wait`), and pure helpers (`split_tail_timeout`,
`parse_kind`, `parse_button`). Property tests (`proptest`) guarantee
`resolve_command` never panics on arbitrary input.

## License

Licensed under MIT OR Apache-2.0.
