### Full Example Tape Script Source: https://termless.dev/guide/tape-format.html A comprehensive example demonstrating various tape commands for a build pipeline status simulation, including setup, execution, and screenshots. ```tape # Demo: build pipeline status Set Shell "bash" Set FontSize 14 Set Width 1200 Set Height 600 # Hide the setup Hide Type "cd ~/myproject" Enter Sleep 500ms Show # Show the build Type "npm run build" Enter Sleep 2s Screenshot build-start.png # Navigate the output Down 5 Sleep 500ms Screenshot build-done.png ``` -------------------------------- ### Installation Source: https://termless.dev/guide/cli.html Instructions for installing the @termless/cli package using npm, bun, pnpm, or yarn. Also includes an example of running the command directly. ```APIDOC ## Installation Install the `@termless/cli` package using your preferred package manager: ### npm ```bash npm install @termless/cli ``` ### bun ```bash bun add @termless/cli ``` ### pnpm ```bash pnpm add @termless/cli ``` ### yarn ```bash yarn add @termless/cli ``` Or run directly: ```bash $ bunx termless record -o demo.tape ls -la ``` ``` -------------------------------- ### Install @termless/cli Source: https://termless.dev/guide/cli.html Installation commands for various package managers. ```bash npm install @termless/cli ``` ```bash bun add @termless/cli ``` ```bash pnpm add @termless/cli ``` ```bash yarn add @termless/cli ``` -------------------------------- ### Full Example Tape Source: https://termless.dev/guide/tape-format.html A comprehensive example demonstrating the use of various tape commands and settings to script a build pipeline status. ```APIDOC ## Full Example tape ``` # Demo: build pipeline status Set Shell "bash" Set FontSize 14 Set Width 1200 Set Height 600 # Hide the setup Hide Type "cd ~/myproject" Enter Sleep 500ms Show # Show the build Type "npm run build" Enter Sleep 2s Screenshot build-start.png # Navigate the output Down 5 Sleep 500ms Screenshot build-done.png ``` ``` -------------------------------- ### Install Termless Backends Source: https://termless.dev/guide/multi-backend Use the `termless backends` command to see available backends and install specific ones for testing. ```bash bunx termless backends bunx termless backends install ghostty vt100 ``` -------------------------------- ### Create Setup Files for Vitest Backends Source: https://termless.dev/guide/multi-backend Define setup files for each backend to configure its specific `TerminalBackend` implementation. These files are referenced in the Vitest workspace configuration. ```typescript // test/setup-xterm.ts import { createXtermBackend } from "@termless/xtermjs" declare global { var createBackend: () => import("termless").TerminalBackend } globalThis.createBackend = () => createXtermBackend() ``` ```typescript // test/setup-ghostty.ts import { createGhosttyBackend, initGhostty } from "@termless/ghostty" declare global { var createBackend: () => import("termless").TerminalBackend } const ghostty = await initGhostty() globalThis.createBackend = () => createGhosttyBackend(undefined, ghostty) ``` -------------------------------- ### Usage Examples Source: https://termless.dev/matchers/to-have-cursor-visible.html Examples demonstrating how to use the toHaveCursorVisible matcher in various scenarios. ```APIDOC ## Usage Examples ### Assert cursor is visible ```typescript expect(term).toHaveCursorVisible() ``` ### With auto-retry ```typescript await expect(term).toHaveCursorVisible({ timeout: 5000 }) ``` ### Negation ```typescript expect(term).not.toHaveCursorVisible() ``` ``` -------------------------------- ### Check installation health Source: https://termless.dev/guide/cli.html Verify that backends are installed and configured correctly. ```bash $ termless doctor ``` -------------------------------- ### Install Termless Test Suite Source: https://termless.dev/guide/getting-started.html Install the primary testing package using your preferred package manager. ```bash npm install -D @termless/test ``` ```bash bun add -d @termless/test ``` ```bash pnpm add -D @termless/test ``` ```bash yarn add -D @termless/test ``` -------------------------------- ### toHaveScrollbackLines Usage Examples Source: https://termless.dev/matchers/to-have-scrollback-lines.html Examples demonstrating basic usage, auto-retry configuration, and negation. ```typescript // Check scrollback size expect(term).toHaveScrollbackLines(100) // With auto-retry await expect(term).toHaveScrollbackLines(50, { timeout: 5000 }) // Negation expect(term).not.toHaveScrollbackLines(0) ``` -------------------------------- ### Create libvterm Backend Source: https://termless.dev/guide/backends.html Initialize and create the libvterm backend using its factory function. This requires asynchronous initialization of the WebAssembly module. Ensure the backend is installed via `bunx termless backends install libvterm`. ```typescript import { createLibvtermBackend, initLibvterm } from "@termless/libvterm" await initLibvterm() const term = createTerminal({ backend: createLibvtermBackend() }) ``` -------------------------------- ### Start MCP server Source: https://termless.dev/guide/cli.html Launch the MCP server for AI agent integration. ```bash $ termless mcp ``` -------------------------------- ### Manage backends Source: https://termless.dev/guide/cli.html Commands for listing, installing, and updating terminal backends. ```bash $ termless backends ``` ```bash # Install default backends $ termless backends install # Install a specific backend $ termless backends install ghostty # Install multiple backends $ termless backends install ghostty alacritty ``` ```bash # Check for updates (dry run) $ termless backends update # Apply updates to backends.json $ termless backends update --apply ``` -------------------------------- ### toMatchSvgSnapshot Usage Examples Source: https://termless.dev/matchers/to-match-svg-snapshot.html Demonstrates basic usage, named snapshots, and custom theme application. ```typescript // Basic SVG snapshot expect(term).toMatchSvgSnapshot() // Named snapshot expect(term).toMatchSvgSnapshot({ name: "rendered-ui" }) // With custom theme expect(term).toMatchSvgSnapshot({ theme: myTheme }) ``` -------------------------------- ### Create Kitty Backend Source: https://termless.dev/guide/backends.html Use the factory function for explicit, synchronous creation of the Kitty backend. This backend requires building from source and has GPL-3.0 licensing. Ensure the backend is installed via `bunx termless backends install kitty`. ```typescript import { createKittyBackend } from "@termless/kitty" const term = createTerminal({ backend: createKittyBackend() }) ``` -------------------------------- ### Manage Termless Backends Source: https://termless.dev/guide/getting-started.html Use the CLI to list or install additional terminal backends. ```bash # See all available backends bunx termless backends # Install additional backends (e.g., Ghostty) bunx termless backends install ghostty ``` -------------------------------- ### Load libvterm Backend by Name Source: https://termless.dev/guide/backends.html Load the libvterm backend by name. This method automatically handles the asynchronous WebAssembly initialization. Ensure the backend is installed via `bunx termless backends install libvterm`. ```typescript import { backend } from "@termless/core" const b = await backend("libvterm") const term = createTerminal({ backend: b }) ``` -------------------------------- ### Backend Management Source: https://termless.dev/guide/cli.html Commands for managing backend installations, including listing, installing, and updating backends used by Termless. ```APIDOC ## Backend Management Manage backend installation with Playwright-inspired CLI commands. Backend versions are pinned in `backends.json` -- upgrading termless upgrades all backends together. ### `termless backends` List all available backends with their type, install status, and version: ```bash $ termless backends ``` ### `termless backends list` Same as `termless backends` -- list all backends. ### `termless backends install` Install backends. With no arguments, installs the default set (xtermjs, ghostty, vt100). * **Install default backends:** ```bash $ termless backends install ``` * **Install a specific backend:** ```bash $ termless backends install ghostty ``` * **Install multiple backends:** ```bash $ termless backends install ghostty alacritty ``` ### `termless backends update` Check upstream registries (npm, crates.io, GitHub) for newer backend versions. Compares against the versions pinned in `backends.json`. * **Check for updates (dry run):** ```bash $ termless backends update ``` * **Apply updates to backends.json:** ```bash $ termless backends update --apply ``` ``` -------------------------------- ### Create VT100 Rust Backend Source: https://termless.dev/guide/backends.html Use the factory function for explicit, synchronous creation of the vt100-rust backend. Ensure the backend is installed via `bunx termless backends install vt100-rust`. ```typescript import { createVt100RustBackend } from "@termless/vt100-rust" const term = createTerminal({ backend: createVt100RustBackend() }) ``` -------------------------------- ### Configure CI Pipeline Source: https://termless.dev/guide/faq.html Example configuration for running tests in a CI environment without display requirements. ```yaml # GitHub Actions - run: bun vitest run # No xvfb, no DISPLAY, no Docker-in-Docker ``` -------------------------------- ### Load Kitty Backend by Name Source: https://termless.dev/guide/backends.html Load the Kitty backend asynchronously by its name. This method handles native module loading. Ensure the backend is installed via `bunx termless backends install kitty`. ```typescript import { backend } from "@termless/core" const b = await backend("kitty") const term = createTerminal({ backend: b }) ``` -------------------------------- ### Create Ghostty Native Backend Source: https://termless.dev/guide/backends.html Use the factory function for explicit, synchronous creation of the native Ghostty backend. This backend requires the Zig toolchain for building. Ensure the backend is installed via `bunx termless backends install ghostty-native`. ```typescript import { createGhosttyNativeBackend } from "@termless/ghostty-native" const term = createTerminal({ backend: createGhosttyNativeBackend() }) ``` -------------------------------- ### Manage Backends via CLI Source: https://termless.dev/ Use the Termless CLI to list, install, and verify the health of terminal backends. ```bash $ bunx termless backends # List all backends and install status $ bunx termless backends install # Install default backends $ bunx termless backends install ghostty # Install a specific backend $ bunx termless doctor # Health check installed backends ``` -------------------------------- ### toHaveCursor Error Message Example Source: https://termless.dev/matchers/to-have-cursor.html An example of the output displayed when a toHaveCursor assertion fails. ```text Expected terminal to have cursor {"x":5,"y":10,"visible":true} x: expected 5, got 3 y: matched visible: matched ``` -------------------------------- ### toHaveAttrs Error Message Example Source: https://termless.dev/matchers/to-have-attrs.html An example of the output displayed when an assertion fails. ```text Expected cell (0,0) containing 'H' to have attrs {"bold":true,"fg":"#ff0000"} bold: expected true, got false fg: matched ``` -------------------------------- ### Create Terminal and Generate Basic Screenshots Source: https://termless.dev/guide/screenshots.html Initializes a terminal instance and generates an SVG screenshot. For PNG, ensure `@resvg/resvg-js` is installed. ```typescript import { createTerminal } from "@termless/core" import { createXtermBackend } from "@termless/xtermjs" const term = createTerminal({ backend: createXtermBackend(), cols: 80, rows: 24 }) term.feed("\x1b[1;38;2;255;85;85mError:\x1b[0m file not found") const svg = term.screenshotSvg() const png = await term.screenshotPng() // requires: bun add -d @resvg/resvg-js ``` -------------------------------- ### Load Ghostty Native Backend by Name Source: https://termless.dev/guide/backends.html Load the native Ghostty backend asynchronously by its name. This method handles native module loading. Ensure the backend is installed via `bunx termless backends install ghostty-native`. ```typescript import { backend } from "@termless/core" const b = await backend("ghostty-native") const term = createTerminal({ backend: b }) ``` -------------------------------- ### CI Integration Configuration Source: https://termless.dev/guide/recipes.html Examples for running Termless tests in GitHub Actions and GitLab CI environments. ```yaml name: Terminal Tests on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: oven-sh/setup-bun@v2 - run: bun install - run: bun vitest run # No display needed -- Termless runs headless ``` ```yaml terminal-tests: image: oven/bun:latest script: - bun install - bun vitest run ``` -------------------------------- ### Running Tape Files with Termless CLI Source: https://termless.dev/guide/tape-format.html Examples of using the 'termless play' command to execute tape files, with options for output generation, backend selection, and comparison. ```bash # Play a tape and see the output $ termless play demo.tape # Play and generate a GIF $ termless play -o demo.gif demo.tape # Play against a specific backend $ termless play -b ghostty demo.tape # Play with cross-terminal comparison $ termless play -b vterm,ghostty --compare side-by-side demo.tape ``` -------------------------------- ### Load VT100 Rust Backend by Name Source: https://termless.dev/guide/backends.html Load the vt100-rust backend asynchronously by its name. This method handles native module loading automatically. Ensure the backend is installed via `bunx termless backends install vt100-rust`. ```typescript import { backend } from "@termless/core" const b = await backend("vt100-rust") const term = createTerminal({ backend: b }) ``` -------------------------------- ### Running Tape Files with Termless CLI Source: https://termless.dev/guide/tape-format.html Command-line interface examples for running tape files using the `termless play` command, including options for output generation, backend selection, and comparison modes. ```APIDOC ## Running Tape Files bash ``` # Play a tape and see the output $ termless play demo.tape # Play and generate a GIF $ termless play -o demo.gif demo.tape # Play against a specific backend $ termless play -b ghostty demo.tape # Play with cross-terminal comparison $ termless play -b vterm,ghostty --compare side-by-side demo.tape ``` ``` -------------------------------- ### toHaveCursorHidden Usage Source: https://termless.dev/matchers/to-have-cursor-hidden.html Examples showing basic usage, auto-retry configuration, and negation. ```typescript // Assert cursor is hidden (e.g., after DECTCEM hide) expect(term).toHaveCursorHidden() // With auto-retry await expect(term).toHaveCursorHidden({ timeout: 5000 }) // Negation expect(term).not.toHaveCursorHidden() ``` -------------------------------- ### Basic Tape Commands Source: https://termless.dev/guide/tape-format.html Illustrates fundamental tape commands including comments, setting terminal properties, typing text, and capturing screenshots. Blank lines and lines starting with '#' are ignored. ```tape # This is a comment Set FontSize 14 Set Width 1200 Set Height 600 Type "echo hello world" Enter Sleep 1s Screenshot ``` -------------------------------- ### Usage examples for toHaveCursorStyle Source: https://termless.dev/matchers/to-have-cursor-style.html Demonstrates checking for different cursor styles and using the timeout option for auto-retry. ```typescript // Block cursor (default for most terminals) expect(term).toHaveCursorStyle("block") // Beam cursor (common in insert mode) expect(term).toHaveCursorStyle("beam") // Underline cursor expect(term).toHaveCursorStyle("underline") // With auto-retry await expect(term).toHaveCursorStyle("beam", { timeout: 5000 }) ``` -------------------------------- ### Usage examples for toBeAtBottomOfScrollback Source: https://termless.dev/matchers/to-be-at-bottom-of-scrollback.html Demonstrates standard assertion, usage with auto-retry, and negation for checking if the user has scrolled up. ```typescript // Assert at bottom (default state) expect(term).toBeAtBottomOfScrollback() // With auto-retry await expect(term).toBeAtBottomOfScrollback({ timeout: 5000 }) // Negation (user has scrolled up) expect(term).not.toBeAtBottomOfScrollback() ``` -------------------------------- ### toHaveText Usage Examples Source: https://termless.dev/matchers/to-have-text.html Common usage patterns including exact matches, timeouts, and negation. ```typescript // Exact match on a row expect(term.row(0)).toHaveText("Title") // Full screen match expect(term.row(2)).toHaveText("status: ok") // With auto-retry await expect(term.row(0)).toHaveText("Ready", { timeout: 5000 }) // Negation expect(term.row(0)).not.toHaveText("Loading...") ``` -------------------------------- ### `termless mcp` Server Source: https://termless.dev/guide/cli.html Information on starting and using the `termless mcp` server, which provides a stdio interface for AI agents to interact with terminal sessions, including process management, input/output handling, and screenshots. ```APIDOC ## `termless mcp` Start a stdio MCP server for AI agents (Claude Code, etc.). The server manages terminal sessions -- AI agents can spawn processes, send input, read output, and take screenshots. ```bash $ termless mcp ``` The MCP server exposes tools for: * Creating terminal sessions with spawned processes * Sending keypresses and typed text * Reading terminal text * Taking SVG or PNG screenshots * Managing multiple concurrent sessions ### Claude Code Integration Add to your Claude Code MCP configuration: ```json { "mcpServers": { "termless": { "command": "bunx", "args": ["termless", "mcp"] } } } ``` ``` -------------------------------- ### toHaveClipboardText Usage Source: https://termless.dev/matchers/to-have-clipboard-text.html Examples demonstrating positive assertion and negation for clipboard content. ```typescript // Assert clipboard content after an OSC 52 write expect(term).toHaveClipboardText("copied text") // Negation expect(term).not.toHaveClipboardText("wrong text") ``` -------------------------------- ### toBeDim Usage Examples Source: https://termless.dev/matchers/to-be-dim.html Demonstrates checking a specific cell for dim styling and using negation to verify the absence of the style. ```typescript // Check a specific cell expect(term.cell(0, 0)).toBeDim() // Negation expect(term.cell(0, 5)).not.toBeDim() ``` -------------------------------- ### Describe Backends for Cross-Backend Tests Source: https://termless.dev/guide/multi-backend The `describeBackends` function runs the same tests across all installed backends, creating a `describe` block for each. You can also filter to specific backends. ```typescript import { describeBackends } from "@termless/test" describeBackends((ctx) => { test("renders bold", async () => { const term = await ctx.createTerminal({ cols: 80, rows: 24 }) term.feed("\x1b[1mBold\x1b[0m") expect(term.cell(0, 0)).toBeBold() }) }) // Or filter to specific backends: describeBackends(["ghostty", "vt100"], (ctx) => { test("italic works", async () => { const term = await ctx.createTerminal() term.feed("\x1b[3mI") expect(term.cell(0, 0)).toBeItalic() }) }) ``` -------------------------------- ### Hiding and Showing Output Source: https://termless.dev/guide/tape-format.html Control the visibility of terminal output during playback using 'Hide' and 'Show' commands. This is useful for skipping setup steps. ```tape Hide Type "npm install" Enter Sleep 5s Show Type "npm start" Enter Screenshot ``` -------------------------------- ### Iterate Over Installed Backends Manually Source: https://termless.dev/guide/multi-backend The `backendCases` function provides an array of available backends, allowing you to manually iterate and create terminals for each. This is useful for custom test loops. ```typescript import { backendCases } from "@termless/test" const cases = await backendCases() for (const { name, createTerminal } of cases) { test(`renders correctly on ${name}`, async () => { const term = await createTerminal({ cols: 80, rows: 24 }) term.feed("\x1b[1mBold\x1b[0m") expect(term.cell(0, 0)).toBeBold() }) } ``` -------------------------------- ### toHaveCursor Usage Examples Source: https://termless.dev/matchers/to-have-cursor.html Various ways to use the toHaveCursor matcher, including partial property checks, auto-retry options, and negation. ```typescript // Position only expect(term).toHaveCursor({ x: 5, y: 10 }) // Visibility and style expect(term).toHaveCursor({ visible: true, style: "block" }) // All properties expect(term).toHaveCursor({ x: 0, y: 0, visible: true, style: "beam" }) // With auto-retry await expect(term).toHaveCursor({ x: 5, y: 10 }, { timeout: 5000 }) // Negation expect(term).not.toHaveCursor({ visible: false }) ``` -------------------------------- ### Configure Vitest Workspace for Multi-Backend Testing Source: https://termless.dev/guide/multi-backend The `vitest.workspace.ts` file defines separate Vitest projects for each backend, specifying their respective setup files and test inclusion patterns. This enables per-backend configuration and isolated test runs. ```typescript // vitest.workspace.ts export default [ { test: { name: "xterm", setupFiles: ["./test/setup-xterm.ts"], include: ["test/**/*.test.ts"], }, }, { test: { name: "ghostty", setupFiles: ["./test/setup-ghostty.ts"], include: ["test/**/*.test.ts"], }, }, ] ``` -------------------------------- ### Discover and Verify Backends Source: https://termless.dev/guide/backends.html Use the CLI to list available backends and check their health status. ```bash # List all backends with install status and capabilities $ bunx termless backends # Check health of installed backends (version mismatches, missing deps) $ bunx termless doctor ``` -------------------------------- ### Initializing Custom Backends Source: https://termless.dev/guide/writing-tests Manually create and pass a backend instance to the test terminal. ```typescript import { createGhosttyBackend, initGhostty } from "@termless/ghostty" const ghostty = await initGhostty() const term = createTestTerminal({ backend: createGhosttyBackend(undefined, ghostty) }) ``` -------------------------------- ### Deprecated toHaveCursorAt usage example Source: https://termless.dev/matchers/to-have-cursor-at.html This example demonstrates the deprecated toHaveCursorAt matcher for checking cursor position. Prefer toHaveCursor for checking multiple cursor properties. ```typescript expect(term).toHaveCursor({ x: 5, y: 2 }) ``` -------------------------------- ### Initialize Terminal with Core API Source: https://termless.dev/guide/faq.html Demonstrates using the framework-agnostic @termless/core package to create a terminal and perform assertions. ```typescript // Works with any test framework import { createTerminal } from "@termless/core" import { createXtermBackend } from "@termless/xtermjs" const term = createTerminal({ backend: createXtermBackend(), cols: 80, rows: 24 }) term.feed("Hello") // Use your framework's built-in assertions assert(term.screen.getText().includes("Hello")) assert(term.cell(0, 0).bold === false) ``` -------------------------------- ### createTerminal Source: https://termless.dev/api/terminal Initializes a new terminal instance with a specified backend and configuration options. ```APIDOC ## createTerminal(options) ### Description Creates a Terminal instance wrapping a backend with optional PTY support. ### Parameters #### Request Body - **backend** (TerminalBackend) - Required - Backend instance (e.g., from createXtermBackend()) - **cols** (number) - Optional - Terminal width in columns (Default: 80) - **rows** (number) - Optional - Terminal height in rows (Default: 24) - **scrollbackLimit** (number) - Optional - Maximum scrollback lines ### Request Example { "backend": "createXtermBackend()", "cols": 80, "rows": 24, "scrollbackLimit": 1000 } ``` -------------------------------- ### Create a Terminal instance Source: https://termless.dev/api/terminal Initializes a new terminal with a specified backend and dimensions. ```typescript import { createTerminal } from "@termless/core" import type { Terminal, TerminalCreateOptions } from "@termless/core" import { createXtermBackend } from "@termless/xtermjs" const term = createTerminal({ backend: createXtermBackend(), cols: 80, // default: 80 rows: 24, // default: 24 scrollbackLimit: 1000, }) ``` -------------------------------- ### Initialize Peekaboo Backend Source: https://termless.dev/guide/backends.html Automates real terminal applications on macOS. Requires accessibility permissions and is intended for end-to-end testing. ```typescript // Factory function (preferred — explicit, sync) import { createPeekabooBackend } from "@termless/peekaboo" const term = createTerminal({ backend: createPeekabooBackend() }) ``` ```typescript // By name (async) import { backend } from "@termless/core" const b = await backend("peekaboo") const term = createTerminal({ backend: b }) ``` -------------------------------- ### Get cell attributes Source: https://termless.dev/api/terminal Retrieves a single cell's content and styling properties. ```typescript const cell = term.getCell(0, 0) cell.text // string -- character cell.fg // RGB | null -- foreground color cell.bg // RGB | null -- background color cell.bold // boolean cell.faint // boolean cell.italic // boolean cell.underline // "none" | "single" | "double" | "curly" | "dotted" | "dashed" cell.strikethrough // boolean cell.inverse // boolean cell.wide // boolean -- double-width character ``` -------------------------------- ### Run Cross-Backend Tests Source: https://termless.dev/emulator-differences.html Commands to execute cross-backend conformance tests and scrollback fuzzing. ```bash # Cross-backend conformance (requires Ghostty WASM) bun vitest run tests/cross-backend.test.ts # Cross-backend scrollback fuzz (in a silvery project with termless) FUZZ=1 bun vitest run tests/features/scrollback-cross-backend.fuzz.tsx ``` -------------------------------- ### Initialize Terminal Backends Source: https://termless.dev/ Choose between explicit factory functions or registry-based async initialization for terminal backends. ```typescript // 1. Factory function (explicit, sync) import { createXtermBackend } from "@termless/xtermjs" const term = createTerminal({ backend: createXtermBackend() }) ``` ```typescript // 2. String name via registry (async — handles WASM/native init) import { backend } from "@termless/core" const b = await backend("ghostty") const term = createTerminal({ backend: b }) ``` -------------------------------- ### Negate strikethrough assertion Source: https://termless.dev/matchers/to-be-strikethrough.html Example of negating the toBeStrikethrough assertion to check if a cell does NOT have strikethrough styling. ```typescript expect(term.cell(0, 5)).not.toBeStrikethrough() ``` -------------------------------- ### Initialize VT100 Backend Source: https://termless.dev/guide/backends.html Use the factory function for synchronous initialization or the backend loader for asynchronous access. ```typescript // Factory function (preferred — explicit, sync) import { createVt100Backend } from "@termless/vt100" const term = createTerminal({ backend: createVt100Backend() }) ``` ```typescript // By name (async) import { backend } from "@termless/core" const b = await backend("vt100") const term = createTerminal({ backend: b }) ``` -------------------------------- ### toHaveAttrs Usage Examples Source: https://termless.dev/matchers/to-have-attrs.html Various ways to use toHaveAttrs for single, multiple, or negated attribute assertions. ```typescript // Single attribute expect(term.cell(0, 0)).toHaveAttrs({ bold: true }) // Multiple attributes expect(term.cell(0, 0)).toHaveAttrs({ bold: true, fg: "#ff0000" }) // Underline with specific style expect(term.cell(5, 3)).toHaveAttrs({ italic: true, underline: "curly" }) // Any underline expect(term.cell(0, 0)).toHaveAttrs({ underline: true }) // Negation expect(term.cell(0, 0)).not.toHaveAttrs({ bold: true }) ``` -------------------------------- ### Test Responsive Layouts Source: https://termless.dev/guide/recipes.html Verifies layout adaptation by resizing the terminal and re-asserting content. ```typescript test("layout adapts to narrow terminal", () => { const term = createTestTerminal({ cols: 120, rows: 40 }) term.feed("Wide layout: sidebar | content") expect(term.screen).toContainText("sidebar | content") // Resize to narrow term.resize(40, 24) term.feed("\x1b[2J\x1b[H") // Clear screen (simulate app redraw) term.feed("Narrow layout:\nsidebar\ncontent") expect(term.row(1)).toContainText("sidebar") expect(term.row(2)).toContainText("content") }) ``` ```typescript test("app reflows on resize", async () => { const term = createTestTerminal({ cols: 120, rows: 40 }) await term.spawn(["./my-tui-app"]) await expect(term.screen).toContainText("wide mode", { timeout: 5000 }) term.resize(40, 24) await expect(term.screen).toContainText("compact mode", { timeout: 5000 }) }) ``` -------------------------------- ### Compare terminal backends side-by-side Source: https://termless.dev/guide/recording.html Play a tape file against multiple specified backends and compare their outputs. Options include side-by-side, separate screenshots, grid layout, or diff mode to highlight differences. ```bash # Side-by-side comparison (composed SVG) $ termless play -b vterm,ghostty --compare side-by-side -o comparison.svg demo.tape ``` ```bash # Separate screenshots per backend $ termless play -b vterm,ghostty,xtermjs --compare separate -o ./out/ demo.tape ``` ```bash # Grid layout $ termless play -b vterm,ghostty,alacritty --compare grid -o grid.svg demo.tape ``` ```bash # Diff mode — highlights differences between backends $ termless play -b vterm,ghostty --compare diff -o diff.svg demo.tape ``` -------------------------------- ### Check a specific cell for strikethrough Source: https://termless.dev/matchers/to-be-strikethrough.html Example of checking a specific cell at row 0, column 0 for strikethrough styling. ```typescript expect(term.cell(0, 0)).toBeStrikethrough() ``` -------------------------------- ### Hide/Show Commands Source: https://termless.dev/guide/tape-format.html Control the visibility of terminal output during playback. Useful for hiding setup steps or showing final results. ```APIDOC ### Hide / Show Control whether terminal output is visible during playback. Useful for skipping setup steps in animations: tape ``` Hide Type "npm install" Enter Sleep 5s Show Type "npm start" Enter Screenshot ``` ``` -------------------------------- ### Record to multiple output formats Source: https://termless.dev/guide/recording.html Record a session once and specify multiple output files with different extensions to generate various formats simultaneously. ```bash # Tape file + GIF in one pass $ termless record -o demo.tape -o demo.gif my-app ``` -------------------------------- ### Navigation Key Commands Source: https://termless.dev/guide/tape-format.html Simulate pressing navigation keys such as Home, End, PageUp, and PageDown. ```tape Home End PageUp PageDown ``` -------------------------------- ### Input API Source: https://termless.dev/api/terminal Methods for sending various types of input to the spawned process, including keypresses, raw text, and mouse events. ```APIDOC ## Input ### `press(key)` Send a keypress to the spawned process. Parses human-readable key descriptions into ANSI escape sequences. ### Request Example ```typescript term.press("a") // Single character term.press("Enter") // Named keys term.press("ArrowUp") // Arrow keys term.press("Ctrl+c") // Modifier + key term.press("Ctrl+Shift+a") // Multiple modifiers term.press("Alt+x") // Alt modifier term.press("F5") // Function keys F1-F12 term.press("Shift+Tab") // Reverse tab ``` Supported modifiers: `Ctrl`, `Control`, `Alt`, `Option`, `Shift`, `Meta`, `Cmd`, `Super`. Supported named keys: `ArrowUp`, `ArrowDown`, `ArrowLeft`, `ArrowRight`, `Home`, `End`, `PageUp`, `PageDown`, `Enter`, `Tab`, `Backspace`, `Delete`, `Escape`, `Space`, `F1`--`F12`. ### `type(text)` Send raw text to the spawned process. Unlike `press()`, this does not parse key descriptions -- it writes the string directly to the PTY. ### Request Example ```typescript term.type("Hello, world!") term.type("search query\r") // \r for Enter ``` ### `click(x, y, options?)` Send a mouse click at terminal coordinates (0-based column, 0-based row). Requires PTY and mouse reporting to be enabled by the application. ### Request Example ```typescript term.click(5, 10) // Click at column 5, row 10 term.click(0, 0, { ctrl: true }) // Ctrl+click at top-left term.click(20, 5, { shift: true }) // Shift+click for selection term.click(10, 3, { alt: true }) // Alt+click ``` | Option | Type | Default | Description | | ------- | --------- | ------- | ------------------- | | `ctrl` | `boolean` | `false` | Hold Ctrl modifier | | `shift` | `boolean` | `false` | Hold Shift modifier | | `alt` | `boolean` | `false` | Hold Alt modifier | ### `dblclick(x, y, options?)` Send a double-click at terminal coordinates. Returns a promise because it sends two clicks with a configurable delay between them. ### Request Example ```typescript await term.dblclick(5, 10) // Double-click at column 5, row 10 await term.dblclick(5, 10, { delay: 50 }) // Custom inter-click delay (default: 100ms) await term.dblclick(5, 10, { ctrl: true }) // Ctrl+double-click ``` | Option | Type | Default | Description | | ------- | --------- | ------- | ----------------------------------- | | `ctrl` | `boolean` | `false` | Hold Ctrl modifier | | `shift` | `boolean` | `false` | Hold Shift modifier | | `alt` | `boolean` | `false` | Hold Alt modifier | | `delay` | `number` | `100` | Milliseconds between the two clicks | ``` -------------------------------- ### Import All Termless Matchers Source: https://termless.dev/matchers Auto-registers all available Termless matchers for use in Vitest tests. Ensure this import is present in your test setup. ```typescript import "@termless/test/matchers" // Auto-registers all matchers ``` -------------------------------- ### Initialize xterm.js backend Source: https://termless.dev/api/backend Usage of the xterm.js backend for in-process terminal emulation. ```typescript import { createXtermBackend } from "@termless/xtermjs" const backend = createXtermBackend() // or with eager initialization: const backend = createXtermBackend({ cols: 80, rows: 24 }) ``` -------------------------------- ### Assert a cell does not contain a wide character Source: https://termless.dev/matchers/to-be-wide.html Example usage of .not.toBeWide() to assert that a cell does not contain a wide character, such as an ASCII character. This matcher is deprecated. ```typescript // ASCII characters are not wide expect(term.cell(0, 0)).not.toBeWide() ``` -------------------------------- ### Initialize xterm.js Backend Source: https://termless.dev/guide/backends.html Initialize the default xterm.js backend using either a factory function or by name. ```typescript // Factory function (preferred — explicit, sync) import { createXtermBackend } from "@termless/xtermjs" const term = createTerminal({ backend: createXtermBackend() }) ``` ```typescript // By name (async — handles init automatically) import { backend } from "@termless/core" const b = await backend("xtermjs") const term = createTerminal({ backend: b }) ``` -------------------------------- ### Output Command Source: https://termless.dev/guide/tape-format.html Declare output file paths for generated media (e.g., GIF, PNG). Note: Termless prefers the `-o` CLI flag for output. ```APIDOC ### Output Declare output file paths (VHS compatibility). In termless, prefer the `-o` CLI flag instead: tape ``` Output demo.gif Output demo.png ``` ``` -------------------------------- ### Check for wide characters in a terminal cell Source: https://termless.dev/matchers/to-be-wide.html Example usage of toBeWide() to assert a cell contains a wide character, such as a CJK character. This matcher is deprecated. ```typescript // CJK character occupies two columns expect(term.cell(0, 0)).toBeWide() ``` -------------------------------- ### Initialize WezTerm Backend Source: https://termless.dev/guide/backends.html Provides the broadest feature set via native Rust bindings. Use the factory function or async loader to initialize. ```typescript // Factory function (preferred — explicit, sync) import { createWeztermBackend } from "@termless/wezterm" const term = createTerminal({ backend: createWeztermBackend() }) ``` ```typescript // By name (async — handles native module loading) import { backend } from "@termless/core" const b = await backend("wezterm") const term = createTerminal({ backend: b }) ``` -------------------------------- ### Define Spawn Options Source: https://termless.dev/api/terminal Configuration interface for spawning processes. ```typescript interface SpawnOptions { command: string[] env?: Record cwd?: string } ``` -------------------------------- ### `termless doctor` Command Source: https://termless.dev/guide/cli.html Use the `termless doctor` command to check the health of your Termless installation, verifying backend loading, detecting version mismatches, and reporting missing dependencies. ```APIDOC ## `termless doctor` Check installation health: verify installed backends load correctly, detect version mismatches, and report missing dependencies. ```bash $ termless doctor ``` ``` -------------------------------- ### Settings Commands Source: https://termless.dev/guide/tape-format.html Configure the terminal environment using the `Set` command, including terminal size, font, shell, theme, and default typing speed. ```APIDOC ## Settings Configure the terminal environment with `Set`: ### Terminal Size tape ``` Set Width 1200 Set Height 600 ``` ### Font tape ``` Set FontSize 14 Set FontFamily "Menlo" ``` ### Shell tape ``` Set Shell "bash" Set Shell "/bin/zsh" ``` ### Theme tape ``` Set Theme "Dracula" Set Theme "Monokai" ``` ### Typing Speed Default speed for all `Type` commands: tape ``` Set TypingSpeed 50ms ``` ``` -------------------------------- ### Capture Terminal State for Regression Testing Source: https://termless.dev/guide/recipes.html Use `terminalSerializer` and `terminalSnapshot` to capture terminal state as SVG snapshots for visual regression testing. Ensure `terminalSerializer` is added to your expect setup. ```typescript import { terminalSerializer, terminalSnapshot } from "@termless/test" expect.addSnapshotSerializer(terminalSerializer) test("renders header correctly", () => { const term = createTestTerminal({ cols: 60, rows: 10 }) term.feed("\x1b[1mMy App\x1b[0m v2.1.0\r\n\x1b[2m" + "─".repeat(60) + "\x1b[0m") expect(terminalSnapshot(term)).toMatchSnapshot() }) ``` -------------------------------- ### Run termless directly Source: https://termless.dev/guide/cli.html Execute the CLI tool directly using bunx. ```bash $ bunx termless record -o demo.tape ls -la ``` -------------------------------- ### Capture TUI with keys and screenshot Source: https://termless.dev/guide/recording.html Use `--keys` and `--screenshot` for one-shot captures of TUIs. The `--wait-for` option can be used to pause recording until specific text appears. ```bash # Run a TUI, navigate, capture $ termless record --keys j,j,Enter --screenshot /tmp/app.svg bun km view /path ``` ```bash # Wait for specific text before pressing keys $ termless record --wait-for "ready>" --keys Enter --screenshot /tmp/out.png my-app ``` ```bash # Just capture text output $ termless record --text ls -la ``` -------------------------------- ### Create and Manage a Terminal Session Source: https://termless.dev/guide/cli.html Use `createSession` to start a new terminal session with specified options. Interact with the terminal using methods like `press` and `getText`, and manage the session lifecycle with `stopSession`. ```typescript import { createSessionManager } from "@termless/cli" const manager = createSessionManager() const { id, terminal } = await manager.createSession({ command: ["my-app"], cols: 120, rows: 40, waitFor: "ready>", timeout: 5000, }) terminal.press("ArrowDown") await terminal.waitForStable() console.log(terminal.getText()) await manager.stopSession(id) // or: await manager.stopAll() ``` -------------------------------- ### Test a Go TUI App (Bubbletea) Source: https://termless.dev/guide/recipes.html Spawns a compiled binary and interacts with it via PTY. Requires the @termless/test package. ```typescript import { test, expect } from "vitest" import { createTestTerminal } from "@termless/test" test("bubbletea app navigates list", async () => { const term = createTestTerminal({ cols: 80, rows: 24 }) await term.spawn(["./my-bubbletea-app"]) await expect(term.screen).toContainText("Welcome", { timeout: 5000 }) term.press("ArrowDown") term.press("ArrowDown") term.press("Enter") await expect(term.screen).toContainText("Selected: item 3", { timeout: 5000 }) term.press("q") await expect(term).not.toBeInMode("altScreen", { timeout: 3000 }) }) ``` -------------------------------- ### Run Cross-Backend Tests Source: https://termless.dev/advanced/compat-matrix.html Executes the full suite of cross-backend conformance tests using the Vitest runner. ```bash bun vitest run tests/cross-backend.test.ts ``` -------------------------------- ### Inspect Terminal State with Termless Source: https://termless.dev/ Use createTestTerminal to simulate terminal interactions and assert on various terminal states like scrollback, screen content, specific rows, cell styles, cursor position, and terminal modes. This example uses Vitest for testing. ```typescript import { test, expect } from "vitest" import { createTestTerminal } from "@termless/test" // ANSI helpers — real apps use @silvery/ag-term or @silvery/ansi, these are just for test data const BOLD = (s: string) => `\x1b[1m${s}\x1b[0m` const GREEN = (s: string) => `\x1b[38;2;0;255;0m${s}\x1b[0m` test("inspect what string matching can't see", () => { // Creates an xterm.js terminal by default. Ghostty, Alacritty, WezTerm, vt100, // and Peekaboo backends are also available — see Multi-Backend Testing below. const term = createTestTerminal({ cols: 40, rows: 3 }) // Simulate a build pipeline — 4 lines overflow a 3-row terminal term.feed("Step 1: install\r\n") term.feed(`Step 2: ${GREEN("build ok")}\r\n`) term.feed(`Step 3: ${BOLD("test")}\r\n`) term.feed("Step 4: deploy") // Region selectors — screen, scrollback, buffer expect(term.scrollback).toContainText("install") // scrolled off, still in history expect(term.screen).toContainText("deploy") // visible area expect(term.buffer).toContainText("install") // everything (scrollback + screen) expect(term.row(0)).toHaveText("Step 2: build ok") // specific row // Cell styles — colors that getText() can't see expect(term.cell(0, 8)).toHaveFg("#00ff00") // "build ok" is green expect(term.cell(1, 8)).toBeBold() // "test" is bold // Scroll up, then assert on viewport term.backend.scrollViewport(1) expect(term.viewport).toContainText("install") // Resize — verify content survives term.resize(20, 3) expect(term.screen).toContainText("deploy") // Terminal state — window title, cursor, modes term.feed("\x1b]2;Build Pipeline\x07") // OSC 2 — set window title expect(term).toHaveTitle("Build Pipeline") expect(term).toHaveCursorAt(14, 2) // after "Step 4: deploy" expect(term).toBeInMode("autoWrap") // default mode expect(term).not.toBeInMode("altScreen") // not in alternate screen }) ``` -------------------------------- ### Initialize Ghostty backend Source: https://termless.dev/api/backend Usage of the Ghostty backend, requiring WASM initialization before creation. ```typescript import { createGhosttyBackend, initGhostty } from "@termless/ghostty" // WASM must be loaded first const ghostty = await initGhostty() const backend = createGhosttyBackend(undefined, ghostty) backend.init({ cols: 80, rows: 24 }) ``` -------------------------------- ### Test a Rust TUI App (Ratatui) Source: https://termless.dev/guide/recipes.html Drives a Rust binary using keypresses. For performance, build the release binary once before running tests. ```typescript test("ratatui dashboard renders", async () => { const term = createTestTerminal({ cols: 120, rows: 40 }) await term.spawn(["cargo", "run", "--release"]) await expect(term.screen).toContainText("Dashboard", { timeout: 15000 }) expect(term).toBeInMode("altScreen") // Navigate tabs term.press("Tab") await expect(term.screen).toContainText("Settings", { timeout: 5000 }) }) ``` -------------------------------- ### Initialize Alacritty Backend Source: https://termless.dev/guide/backends.html Requires a Rust toolchain for native binding compilation. Supports both synchronous factory and asynchronous name-based loading. ```typescript // Factory function (preferred — explicit, sync) import { createAlacrittyBackend } from "@termless/alacritty" const term = createTerminal({ backend: createAlacrittyBackend() }) ``` ```typescript // By name (async — handles native module loading) import { backend } from "@termless/core" const b = await backend("alacritty") const term = createTerminal({ backend: b }) ``` -------------------------------- ### Setting the Shell Source: https://termless.dev/guide/tape-format.html Specify the shell to be used for executing commands with 'Set Shell'. Accepts a shell name or a full path. ```tape Set Shell "bash" Set Shell "/bin/zsh" ```