Skip to content

ducks/tuishot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tuishot

Snapshot testing for Ratatui TUIs. Declare the canonical screens of your TUI as an enum, derive Tuishot, and capture them as SVG. Wire the capture step into cargo test or CI and your documentation screenshots can never drift from reality.

Quickstart

1. Add tuishot as a dev-dependency:

[dev-dependencies]
tuishot = "20260415.0.0"

2. Create tuishot.toml at your crate root (all fields optional):

output     = "docs/screens"
size       = "100x30"
background = "#0d1117"
foreground = "#d0d0d0"

3. Declare shots next to the screen they capture, inside a #[cfg(test)] mod shots — same pattern as unit tests, so you get access to your screen's private state:

#[cfg(test)]
mod shots {
    use super::*;
    use tuishot::Tuishot;

    #[derive(Tuishot)]
    enum HomeShot {
        #[tuishot(name = "home", description = "Initial view on launch")]
        Home,
        #[tuishot(name = "about", description = "About panel")]
        About,
    }

    // The derive emits a per-enum `{Name}Render` trait + a blanket `Capture`
    // impl that forwards to it. You write just the render logic.
    impl HomeShotRender for HomeShot {
        fn render(&self, buf: &mut ratatui::buffer::Buffer, area: ratatui::layout::Rect) {
            match self {
                HomeShot::Home  => { /* draw home into buf */ }
                HomeShot::About => { /* draw about into buf */ }
            }
        }
    }

    #[test]
    fn capture() {
        HomeShot::check_all().unwrap();
    }
}

4. Run it:

  • cargo test — fails if a screenshot has drifted.
  • TUISHOT_UPDATE=1 cargo test — accept the new output.

Why a module next to the screen, not tests/?

Captures need access to your screen's internal state to construct specific states (mid-stream, error mode, prompt open, ...). That's the same reason Rust unit tests live inside src/ rather than tests/ — access to private items. tuishot captures are unit tests for what your TUI looks like, so they live in the same neighborhood.

Design

  • Derive attrs are for identity onlyname, description on variants.
  • Visual config lives in tuishot.toml — output dir, size, colors.
  • Rendering is pure — no PTY, no timing, no flakiness. You construct the screen state, tuishot renders it into a ratatui::Buffer, and serializes to SVG.

Status

Early. Working on Ratatui, Ratatui-only. First dogfood: claux.

License

MIT

About

Snapshot testing for Ratatui TUIs - capture screens as SVG, fail CI on drift

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors