class

Termisu::Testing::Terminal

Inherits Reference / Object

High-level E2E harness: spawns a program on a PTY, continuously emulates its output into a Screen, and exposes assertion helpers that mirror JS terminal test runners (get_by_text, get_cursor, snapshot) — with auto-retrying waits so tests don't sprinkle fixed sleeps.

Prefer the block form which guarantees cleanup:

Termisu::Testing.terminal("./bin/app", cols: 100, rows: 50) do |t|
  t.get_by_text("Ready").should be_true
  t.write("q")
end

Constants

KEYS = { up: "\e[A", down: "\e[B", right: "\e[C", left: "\e[D", enter: "\r", esc: "\e", tab: "\t", backspace: "\u007F", space: " ", home: "\e[H", end: "\e[F", page_up: "\e[5~", page_down: "\e[6~", }

Byte sequences for common special keys (xterm/standard).

Constructors

new(program : String, args : Array(String) = [] of String, *, cols : Int32 = 100, rows : Int32 = 50, env : Hash(String, String) | Nil = nil)
Source

Class methods

terminal(program : String, args : Array(String) = [] of String, *, cols : Int32 = 100, rows : Int32 = 50, env : Hash(String, String) | Nil = nil, &)

Spawns program, yields the harness, and always cleans up.

Source

Instance methods

close

Stops the program and releases the PTY. Idempotent.

Source
cols
Source
ctrl(char : Char) : Nil

Sends a Ctrl+<char> combination (e.g. ctrl('c') → 0x03).

Source
cursor

Cursor position once the screen settles.

Source
cursor_visible?

Whether the cursor is currently visible (waits for the screen to settle).

Source
exited?

Whether the program has exited.

Source
find(pattern : String | Regex) : Tuple(Int32, Int32) | Nil

Current {x, y} of pattern right now, without waiting (returns nil if absent). Use for polling a moving element; use locate to wait for it to appear. Reads @screen under the same lock the reader fiber writes with.

Source
get_by_text(pattern : String | Regex, timeout : Time::Span = 3.seconds) : Bool

Waits (up to timeout) until pattern appears on screen. Returns whether it became visible — assert with .should be_true.

Source
key(name : Symbol) : Nil

Sends a named special key (see KEYS).

Source
key_press(char : Char) : Nil

Sends a single character.

Source
locate(pattern : String | Regex, timeout : Time::Span = 3.seconds) : Tuple(Int32, Int32) | Nil

Waits for pattern to appear, then returns its first {x, y} (or nil).

Source
resize(cols : Int32, rows : Int32) : Nil

Resizes the terminal (delivers SIGWINCH to the child).

Source
row(y : Int32) : String

The text of screen row y once the screen settles.

Source
rows
Source
screen
Source
snapshot(mask : Array(Regex) = [] of Regex) : String

Styled snapshot of the rendered screen (glyph grid + per-cell fg/bg/attr). mask blanks volatile regions (matched per row) so animated screens are deterministic.

Source
wait_stable(quiet_for : Time::Span = 80.milliseconds, timeout : Time::Span = 3.seconds) : Bool

Blocks until the program has produced no new output for quiet_for (render-stable), or timeout elapses. Returns whether the screen actually stabilized: animated screens (a spinner, a moving element) never quiesce and return false on timeout by design — callers mask the volatile region rather than rely on stability.

Source
wait_until(timeout : Time::Span = 3.seconds, &) : Bool

Blocks until block returns true, or timeout elapses. Yields to the reader fiber between checks (no busy spin).

Source
write(data : String) : Nil

Sends raw text to the program.

Source