| Crates.io | termwright |
| lib.rs | termwright |
| version | 0.1.0 |
| created_at | 2026-01-11 22:21:32.58995+00 |
| updated_at | 2026-01-11 22:21:32.58995+00 |
| description | Playwright-like automation framework for terminal TUI applications |
| homepage | |
| repository | https://github.com/fcoury/termwright |
| max_upload_size | |
| id | 2036588 |
| size | 133,183 |
A Playwright-like automation framework for terminal TUI applications.
Termwright enables AI agents and integration tests to interact with and observe terminal user interfaces by wrapping applications in a pseudo-terminal (PTY).
Add to your Cargo.toml:
[dependencies]
termwright = "0.1"
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
Or install the CLI:
cargo install termwright
use termwright::prelude::*;
#[tokio::main]
async fn main() -> Result<()> {
// Spawn a terminal application
let term = Terminal::builder()
.size(80, 24)
.spawn("vim", &["test.txt"])
.await?;
// Wait for the application to be ready
term.expect("VIM")
.timeout(Duration::from_secs(5))
.await?;
// Send input
term.send_key(Key::Char('i')).await?;
term.type_str("Hello, world!").await?;
term.send_key(Key::Escape).await?;
// Query screen state
let screen = term.screen().await;
assert!(screen.contains("Hello, world!"));
// Get structured output for AI agents
println!("{}", screen.to_json()?);
// Take a screenshot
term.screenshot().await.save("vim.png")?;
// Quit the application
term.type_str(":q!").await?;
term.enter().await?;
term.wait_exit().await?;
Ok(())
}
Capture terminal output as text:
termwright run -- ls -la
Take a screenshot of a TUI application:
termwright screenshot --wait-for "VIM" -o vim.png -- vim test.txt
Get JSON output for AI processing:
termwright run --format json -- htop
termwright runRun a command and capture its output.
termwright run [OPTIONS] -- <COMMAND> [ARGS]...
Options:
--cols <COLS> Terminal width [default: 80]
--rows <ROWS> Terminal height [default: 24]
--wait-for <TEXT> Wait for this text to appear before capturing
--delay <MS> Delay in milliseconds before capturing [default: 500]
--format <FORMAT> Output format: text, json, json-compact [default: text]
--timeout <SECS> Timeout for wait conditions [default: 30]
termwright screenshotTake a PNG screenshot of a terminal application.
termwright screenshot [OPTIONS] -- <COMMAND> [ARGS]...
Options:
--cols <COLS> Terminal width [default: 80]
--rows <ROWS> Terminal height [default: 24]
--wait-for <TEXT> Wait for this text to appear before capturing
--delay <MS> Delay in milliseconds before capturing [default: 500]
-o, --output <PATH> Output file path (defaults to stdout)
--font <NAME> Font name for rendering
--font-size <SIZE> Font size in pixels [default: 14]
--timeout <SECS> Timeout for wait conditions [default: 30]
The main entry point for controlling terminal applications:
let term = Terminal::builder()
.size(80, 24)
.spawn("vim", &["file.txt"])
.await?;
// Input
term.type_str("hello").await?;
term.send_key(Key::Enter).await?;
term.enter().await?; // Shorthand for Enter key
// Screen access
let screen = term.screen().await;
// Wait conditions
term.expect("Ready").timeout(Duration::from_secs(5)).await?;
term.wait_exit().await?;
// Screenshots
term.screenshot().await.save("output.png")?;
Query the terminal screen state:
let screen = term.screen().await;
// Text access
let text = screen.text();
let line = screen.line(0);
assert!(screen.contains("hello"));
// Cell-level access
let cell = screen.cell(0, 0);
println!("Char: {}, FG: {:?}, BG: {:?}", cell.char, cell.fg, cell.bg);
// Cursor position
let cursor = screen.cursor();
println!("Cursor at row={}, col={}", cursor.row, cursor.col);
// Region extraction
let region = screen.region(0..10, 0..5);
// Pattern matching
if let Some(pos) = screen.find_text("error") {
println!("Found at row={}, col={}", pos.row, pos.col);
}
// Box detection (UI boundaries)
let boxes = screen.detect_boxes();
// Output formats
println!("{}", screen.to_json()?); // Pretty JSON
println!("{}", screen.to_json_compact()?); // Compact JSON
Available key types for input:
Key::Char('a') // Regular characters
Key::Enter // Enter/Return
Key::Tab // Tab
Key::Escape // Escape
Key::Backspace // Backspace
Key::Up, Key::Down, Key::Left, Key::Right // Arrow keys
Key::Home, Key::End
Key::PageUp, Key::PageDown
Key::Insert, Key::Delete
Key::F(1)..Key::F(12) // Function keys
Key::Ctrl('c') // Ctrl combinations
Key::Alt('x') // Alt combinations
MIT License - see LICENSE for details.