warpdotdev/warp · Archived

tui-testing

Write and run unit tests for Warp TUI (crates/warp_tui) elements/screens by rendering to text lines. Use for TUI test work.

Installation

$ npx skills add warpdotdev/warp --skill tui-testing

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from warpdotdev/warp · top by installs.

npx skills add warpdotdev/warp

Browse all from warpdotdev/warp

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 64.9K
License LICENSE-AGPL
Default branch master
Open issues 3,847
Status Archived

Skill metadata

Parsed from SKILL.md frontmatter.

Declared agents cursor

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 7,016 B
  • docs SUMMARY.md 142 B

History

  1. First recorded snapshot · 1 installs

SKILL.md

tui-testing

How to write and run unit tests for Warp's headless TUI front-end (crates/warptui and the element library at crates/warpuicore/src/elements/tui). This complements rust-unit-tests (general Rust test conventions) and parallels gui-integration-test for the TUI.

TUI tests are plain, fast unit tests: they render an element tree to a fixed cell grid and assert on the resulting text lines. They do not use the GUI real-display / integration / computer-use framework (that's gui-integration-test / gui-integration-test-video, which are GUI-only).

Two test locations, two harnesses

TUI tests live in two crates, and which render helper you use depends on where the test is:

Element-library tests (in warpui_core)

Tests for the shared cell-grid elements live in crates/warpuicore/src/elements/tui/*tests.rs and use the crate-internal testsupport helpers from crates/warpuicore/src/elements/tui/mod.rs:

  • testsupport::rendertolines(element: &dyn TuiElement, size: TuiSize) -> Vec<String> — one-call harness: builds area = TuiRect::new(0, 0, size.width, size.height) and TuiBuffer::empty(area), calls element.render(area, &mut buffer, ctx) inside a paint context, and returns buffer.tolines(). It only calls render, not layout — fine for a leaf like TuiText, but composite elements (e.g. TuiFlex) populate child sizes during layout, so lay the element out first (see the layoutat helper in flextests.rs) or it renders empty/stale.
  • testsupport::withpaint_context(|ctx| ...) — runs a closure with a TuiPaintContext over a fresh, empty view map. Use it when you need the TuiBuffer afterward to assert on individual Cells.

These helpers are pub(crate) to warpuicore, so they are only callable from that crate's own tests. Simplest leaf assertion (see texttests.rs, flex_tests.rs):

```rust path=null start=null asserteq!( renderto_lines(&TuiText::new("hello"), TuiSize::new(10, 1)), vec!["hello "], );


### View/screen tests (in `warp_tui`)

`warp_tui` tests (`crates/warp_tui/src/*_tests.rs`) can NOT use `test_support` — render directly instead, under an `App::test` read/update so an `AppContext` is available. `layout` must run before `render` so child sizes are populated. This local helper mirrors `render_element` in `transcript_view_tests.rs` and `render_lines` in `editor_element_tests.rs`:

```rust path=null start=null
fn render_lines(app_ctx: &AppContext, mut element: impl TuiElement, w: u16, h: u16) -> Vec<String> {
    let mut rendered_views = EntityIdMap::default();
    let mut lctx = TuiLayoutContext { rendered_views: &mut rendered_views };
    let size = element.layout(TuiConstraint::loose(TuiSize::new(w, h)), &mut lctx, app_ctx);
    let area = TuiRect::new(0, 0, size.width, size.height);
    let mut buffer = TuiBuffer::empty(area);
    let mut paint_ctx = TuiPaintContext::new(&mut rendered_views);
    element.render(area, &mut buffer, &mut paint_ctx);
    buffer.to_lines()
}

Views that resolve theme styles need an Appearance singleton (ctx.addsingletonmodel(|| Appearance::mock())). To exercise a whole view through the real draw path, drive the presenter: TuiPresenter::new(), presenter.invalidate(&invalidation, ctx, windowid), then presenter.present(ctx, &view, area) and assert on frame.buffer.tolines() (see transcriptview_tests.rs).

Asserting on styles, cursor, and events

  • Styles/colors: paint into a buffer yourself and index cells. to_lines() only carries glyphs, so style assertions read Cell fields:

```rust path=null start=null let mut buffer = TuiBuffer::empty(TuiRect::new(0, 0, 1, 1)); withpaintcontext(|ctx| text.render(TuiRect::new(0, 0, 1, 1), &mut buffer, ctx)); let cell = &buffer[(0, 0)]; asserteq!(cell.symbol(), "a"); asserteq!(cell.fg, Color::Red); assert!(cell.modifier.contains(Modifier::BOLD));


(`with_paint_context` is the `warpui_core`-only helper; in a `warp_tui` test construct the paint context directly with `TuiPaintContext::new(&mut rendered_views)` as in the `render_lines` helper above.)

- **Cursor:** call `element.cursor_position(area, ctx)` and assert on the returned `Option<(u16, u16)>`.
- **Events:** build a `TuiEvent` (e.g. `TuiEvent::KeyDown { keystroke, chars, details, is_composing }` or `TuiEvent::ScrollWheel { .. }`), then call `element.dispatch_event(&event, area, &mut event_ctx, &mut layout_ctx, app_ctx)` and assert on the returned `bool` and on the re-rendered lines/cursor. Layout must run first. See `render_element` / `dispatch_event` / `dispatch_scroll` helpers in `crates/warp_tui/src/transcript_view_tests.rs`.

Keep test areas at a stable, small width/height so golden line vectors stay readable and deterministic; trailing padding is spaces (e.g. `"hello     "`).

## Where tests live

Follow the repo convention: put tests in a sibling `*_tests.rs` file included at the end of the source module:

```rust path=null start=null
#[cfg(test)]
#[path = "foo_tests.rs"]
mod tests;

Real examples to model:

  • Element library: crates/warpuicore/src/elements/tui/texttests.rs, flextests.rs, containertests.rs, constrainedboxtests.rs, buffer_tests.rs.
  • Views/screens: crates/warptui/src/transcriptviewtests.rs, crates/warptui/src/input/view_tests.rs.

Appearance in view tests

Views that resolve theme styles (via TuiUiBuilder::fromapp) need an Appearance singleton. Install the mock in the test with app.addsingletonmodel(|| Appearance::mock()); (as in transcriptviewtests.rs). Appearance::mock() comes from warp_core's test-util feature, wired as a dev-dependency of the TUI crates.

Process-level tests (no integration harness)

The TUI has no GUI-style integration harness: the real-display, synthetic-event framework in crates/integration (see gui-integration-test) is GUI-only and does not drive the TUI. Besides render-to-lines unit tests, binary-level behavior is covered by a process-level test that spawns the built binary and asserts on its output/exit — see crates/warptui/tests/workerdispatch.rs (it runs CARGOBINEXE_warp-tui-oss and checks that a worker invocation dispatches without launching the TUI frontend). Use that pattern for process/CLI-level behavior, and render-to-lines unit tests for element/screen rendering. There is no separate TUI integration-test skill because there is no such framework today.

Running

  • Whole crates: cargo nextest run -p warptui and cargo nextest run -p warpuicore.
  • The TUI element library is behind the tui feature; if a test needs it explicitly, add --features tui.
  • A single test by substring: cargo nextest run -p warp_tui -E 'test(<substring>)'.
  • Before opening a PR, run ./script/format and cargo clippy per repo conventions.