tui-test
Use tui-test to control and test a real terminal.
Pick an API
| Context |
Use |
Reference |
| Agent or shell workflow |
CLI |
CLI |
| Python code |
tui_test |
Python |
| JavaScript or TypeScript |
@microsoft/tui-test |
JavaScript |
| Rust code |
tui-test-rs |
Rust |
| Common tasks |
Current project language |
Recipes |
Use the library that matches the project. Use the CLI when the terminal must persist across separate commands or be watched with monitor.
CLI and library sessions do not share state.
CLI
tui-test run my-app
tui-test expect text "Ready"
tui-test click text "Continue"
tui-test expect text "Done"
tui-test close
Run tui-test agent-context for exact command and option names.
Python
from tui_test import TuiTest
async with TuiTest.ephemeral() as terminal:
await terminal.run("my-app")
await terminal.get_by_text("Ready").expect()
await terminal.get_by_text("Continue").click()
JavaScript
import { TuiTest } from "@microsoft/tui-test";
const terminal = TuiTest.ephemeral();
try {
await terminal.run("my-app");
await terminal.getByText("Ready").expect();
await terminal.getByText("Continue").click();
} finally {
await terminal.closeQuiet();
}
Locators
Use text and style locators for visible terminal state.
save = (
terminal
.get_by_text("Settings")
.get_by_text("Save", direction="after")
.unique()
)
await save.click()
- Use
first(), last(), nth(), or unique() before an action when text repeats.
- Use
get_by_style() or getByStyle() for colors and attributes.
- Use
direction="within", "after", or "before" for relative matches.
- Use
locations() or count() for immediate reads.
- Use
wait(), expect(), or click() when the app may still be changing.
Wait for state
| Need |
Use |
| Visible or hidden text |
Locator wait() or expect() |
| Submitted command finished |
wait command, wait_command(), waitCommand() |
| Program exited |
wait exit, wait_exit(), waitExit() |
| Shell prompt ready |
wait ready, wait_ready(), waitReady() |
| Screen stopped changing |
wait idle, wait_idle(), waitIdle() |
| Clipboard changed or matched |
wait clipboard, wait_clipboard(), waitClipboard() |
| Bell fired |
wait bell, wait_bell(), waitBell() |
Do not use a fixed sleep when a wait can describe the state.
Keep tests stable
- Give parallel tests unique sessions.
- Use
open for shell commands and run for an app.
- Assert the exit code separately from visible text.
- Keep the shell, terminal size, cwd, environment, and timeouts explicit when they affect output.
- Use semantic mouse buttons:
left, middle, or right.
- Close every session. Prefer the Python and JavaScript test helpers.
Capture output
Use screenshot for text or SVG. Use record for APNG, GIF, MP4, or asciinema. Use recording mode on-failure for test artifacts.
References
- CLI
- Python
- JavaScript
- Rust
- Recipes
1---2name: tui-test3description: Control, inspect, test, and record real terminal apps with the tui-test CLI or its Rust, Python, and JavaScript APIs. Use for shells, TUI apps, text and style locators, keyboard or mouse input, terminal state, clipboard waits, screenshots, recordings, snapshots, and live terminal sessions.4---56# tui-test78Use `tui-test` to control and test a real terminal.910## Pick an API1112| Context | Use | Reference |13| --- | --- | --- |14| Agent or shell workflow | CLI | [CLI](references/cli.md) |15| Python code | `tui_test` | [Python](references/python.md) |16| JavaScript or TypeScript | `@microsoft/tui-test` | [JavaScript](references/javascript.md) |17| Rust code | `tui-test-rs` | [Rust](references/rust.md) |18| Common tasks | Current project language | [Recipes](references/recipes.md) |1920Use the library that matches the project. Use the CLI when the terminal must persist across separate commands or be watched with `monitor`.2122CLI and library sessions do not share state.2324## CLI2526```sh27tui-test run my-app28tui-test expect text "Ready"29tui-test click text "Continue"30tui-test expect text "Done"31tui-test close32```3334Run `tui-test agent-context` for exact command and option names.3536## Python3738```python39from tui_test import TuiTest4041async with TuiTest.ephemeral() as terminal:42 await terminal.run("my-app")43 await terminal.get_by_text("Ready").expect()44 await terminal.get_by_text("Continue").click()45```4647## JavaScript4849```js50import { TuiTest } from "@microsoft/tui-test";5152const terminal = TuiTest.ephemeral();53try {54 await terminal.run("my-app");55 await terminal.getByText("Ready").expect();56 await terminal.getByText("Continue").click();57} finally {58 await terminal.closeQuiet();59}60```6162## Locators6364Use text and style locators for visible terminal state.6566```python67save = (68 terminal69 .get_by_text("Settings")70 .get_by_text("Save", direction="after")71 .unique()72)7374await save.click()75```7677- Use `first()`, `last()`, `nth()`, or `unique()` before an action when text repeats.78- Use `get_by_style()` or `getByStyle()` for colors and attributes.79- Use `direction="within"`, `"after"`, or `"before"` for relative matches.80- Use `locations()` or `count()` for immediate reads.81- Use `wait()`, `expect()`, or `click()` when the app may still be changing.8283## Wait for state8485| Need | Use |86| --- | --- |87| Visible or hidden text | Locator `wait()` or `expect()` |88| Submitted command finished | `wait command`, `wait_command()`, `waitCommand()` |89| Program exited | `wait exit`, `wait_exit()`, `waitExit()` |90| Shell prompt ready | `wait ready`, `wait_ready()`, `waitReady()` |91| Screen stopped changing | `wait idle`, `wait_idle()`, `waitIdle()` |92| Clipboard changed or matched | `wait clipboard`, `wait_clipboard()`, `waitClipboard()` |93| Bell fired | `wait bell`, `wait_bell()`, `waitBell()` |9495Do not use a fixed sleep when a wait can describe the state.9697## Keep tests stable9899- Give parallel tests unique sessions.100- Use `open` for shell commands and `run` for an app.101- Assert the exit code separately from visible text.102- Keep the shell, terminal size, cwd, environment, and timeouts explicit when they affect output.103- Use semantic mouse buttons: `left`, `middle`, or `right`.104- Close every session. Prefer the Python and JavaScript test helpers.105106## Capture output107108Use `screenshot` for text or SVG. Use `record` for APNG, GIF, MP4, or asciinema. Use recording mode `on-failure` for test artifacts.109110## References111112- [CLI](references/cli.md)113- [Python](references/python.md)114- [JavaScript](references/javascript.md)115- [Rust](references/rust.md)116- [Recipes](references/recipes.md)