claude-home/development/tui-testing.md
Cal Corum 4b7eca8a46
All checks were successful
Reindex Knowledge Base / reindex (push) Successful in 3s
docs: add YAML frontmatter to all 151 markdown files
Adds title, description, type, domain, and tags frontmatter to every
doc for improved KB semantic search. The description field is prepended
to every search chunk, and domain/type/tags enable filtered queries.

Type values: context, guide, runbook, reference, troubleshooting
Domain values match directory structure (networking, docker, etc.)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 09:00:44 -05:00

148 lines
5.2 KiB
Markdown

---
title: "TUI Testing with mcp-tui-driver"
description: "Guide to using mcp-tui-driver for Playwright-like TUI automation in Claude Code. Covers installation, MCP config, all 23 tools (session, keyboard, mouse, scripting), testing workflows, and accessibility snapshots."
type: guide
domain: development
tags: [tui, testing, mcp, automation, mcp-tui-driver, claude-code]
---
# TUI Testing with mcp-tui-driver
## Overview
[mcp-tui-driver](https://github.com/michaellee8/mcp-tui-driver) is an MCP server that provides Playwright-like automation for TUI applications. It enables Claude Code to launch, view, interact with, and test terminal UI apps through structured MCP tools.
## Installation
```bash
cargo install --git https://github.com/michaellee8/mcp-tui-driver
```
Binary installs to: `~/.cargo/bin/mcp-tui-driver`
### MCP Config
Configured globally in `~/.claude.json` under the top-level `mcpServers` key:
```json
"tui-driver": {
"command": "/home/cal/.cargo/bin/mcp-tui-driver",
"args": []
}
```
> **Note:** `~/.claude/.mcp.json` is NOT read by Claude Code. Global MCP servers go in `~/.claude.json`.
### Updating
```bash
cargo install --git https://github.com/michaellee8/mcp-tui-driver --force
```
## Tool Reference (23 tools)
### Session Management
| Tool | Description |
|------|-------------|
| `tui_launch` | Start a new TUI app session (command, args, cols, rows) |
| `tui_close` | Terminate a session and its process |
| `tui_list_sessions` | List all active sessions |
| `tui_get_session` | Get session details and status |
| `tui_resize` | Change terminal dimensions |
### Viewing
| Tool | Description |
|------|-------------|
| `tui_text` | Get plain text from the terminal screen |
| `tui_snapshot` | Accessibility-style snapshot with element references (like Playwright locators) |
| `tui_screenshot` | Capture terminal as PNG image |
### Keyboard Input
| Tool | Description |
|------|-------------|
| `tui_press_key` | Press a single key or key combo (e.g., `Ctrl+c`, `Enter`) |
| `tui_press_keys` | Press multiple keys sequentially |
| `tui_send_text` | Send raw text string to the terminal |
### Mouse Input
| Tool | Description |
|------|-------------|
| `tui_click` | Click a snapshot element by reference |
| `tui_click_at` | Click at specific terminal coordinates (row, col) |
| `tui_double_click` | Double-click an element |
| `tui_right_click` | Right-click an element |
### Waiting
| Tool | Description |
|------|-------------|
| `tui_wait_for_text` | Block until specific text appears on screen |
| `tui_wait_for_idle` | Block until screen stops changing |
### Scripting
| Tool | Description |
|------|-------------|
| `tui_get_code_interface` | Get TypeScript API definitions for scripting |
| `tui_run_code` | Execute JavaScript automation scripts |
### Debug
| Tool | Description |
|------|-------------|
| `tui_get_input` | Get raw input buffer with escape sequences |
| `tui_get_output` | Get raw PTY output |
| `tui_get_scrollback` | Get lines scrolled off-screen |
| `tui_send_signal` | Send signals (SIGINT, SIGTERM, etc.) |
## Typical Testing Workflow
1. **Launch** the TUI app under test:
```
tui_launch → command: "python", args: ["-m", "myapp"], cols: 120, rows: 40
```
2. **Wait** for it to render:
```
tui_wait_for_text → text: "Welcome" or tui_wait_for_idle
```
3. **Inspect** the screen:
```
tui_snapshot → returns accessibility tree with element refs
tui_screenshot → returns PNG for visual verification
```
4. **Interact** with the app:
```
tui_press_key → key: "Tab" (navigate)
tui_send_text → text: "search query" (type into fields)
tui_press_key → key: "Enter" (confirm)
tui_click → ref: "button-submit" (click element from snapshot)
```
5. **Assert** expected state:
```
tui_text → verify expected text content
tui_snapshot → verify element structure
```
6. **Cleanup**:
```
tui_close → terminate the session
```
## Key Concepts
### Accessibility Snapshots
`tui_snapshot` returns a structured view of the terminal with labeled element references. These refs can be used with `tui_click`, `tui_double_click`, and `tui_right_click` — similar to Playwright's `getByRole()` locators but for terminal elements.
### Multi-Session Support
Multiple TUI sessions can run concurrently. Each `tui_launch` returns a session ID used by all other tools. This enables:
- Testing multiple instances side by side
- Launching a helper process alongside the app under test
- Comparing output between different configurations
### Asciicast Recording
Sessions record output in asciicast v3 format (.cast files) compatible with `asciinema play`. Useful for reviewing test sessions after the fact.
### JavaScript Scripting
For complex automation sequences, `tui_run_code` accepts JavaScript with access to the full TUI automation API. Use `tui_get_code_interface` to get the TypeScript definitions.
## Alternatives Considered
- **mcpterm** (https://github.com/dwrtz/mcpterm): Go-based PoC with only 2 tools (`run`, `runScreen`). Single session, no mouse support, no screenshots, no accessibility snapshots. Too minimal for systematic TUI testing.
## Dependencies
- Rust toolchain (cargo)
- Uses: wezterm-term, portable-pty, boa_engine (JS), rmcp, image