Snapshot Testing
FrankenTUI uses insta for visual snapshot testing.
Every screen in the demo showcase has a blessed baseline; running
cargo test -p ftui-demo-showcase renders the screens and fails if any
frame diverges from its baseline.
This is a how-to. If you’re new to insta, the short version is: tests
compare frame text against a stored .snap file, and BLESS=1 or
cargo insta review is how you accept a change. If you’re new to the
FrankenTUI showcase, read overview first.
The audience is anyone making a change that affects rendering — a widget tweak, a layout fix, a style update, a new screen. If your change changes pixels, you’ll need to re-bless and review.
Motivation
Rendering regressions are hard to catch with unit tests alone. A subtle off-by-one in the presenter, a broken UTF-8 width calculation, a style leak across widgets — all of these look correct under unit tests but produce the wrong bytes on screen. Snapshot tests catch them because they freeze the rendered output.
The trick is keeping the workflow fast enough that contributors
actually run it. insta + BLESS=1 + cargo insta review is designed
for that.
Mental model
The three commands
# 1) Run tests — fails if any screen diverges.
cargo test -p ftui-demo-showcase
# 2) Accept changes non-interactively (use sparingly).
BLESS=1 cargo test -p ftui-demo-showcase
# 3) Review pending changes interactively (preferred).
cargo insta reviewMost of the time you run (1) to check, (3) to review accepted changes,
and commit the resulting .snap files. BLESS=1 is useful in CI or
when you’re certain the diffs are correct and you don’t want to scroll
through them individually.
The review workflow
Make your change
Edit widget code, style code, layout code, whatever. Keep the change focused — smaller diffs are easier to review at snapshot-time.
Run the tests
cargo test -p ftui-demo-showcaseIf everything matches, you’re done. If not, you’ll see one or more
test failures listing .snap.new files that differ from the committed
.snap baselines.
Review
cargo insta reviewThis is an interactive TUI. For each changed snapshot you see a side- by-side diff. The controls are:
a— accept: overwrite the baseline.r— reject: drop the.snap.newfile.s— skip: leave it for later.q— quit.
Accept only the diffs you actually intended. If a diff shows unexpected changes elsewhere, that’s likely a real regression from your change.
Re-run to confirm
cargo test -p ftui-demo-showcaseShould be green now. If it isn’t, you have more snapshots to review or a genuine bug.
Commit
Commit both your code change and the updated .snap files in the
same commit. Reviewers can see the rendering impact of a code change
inline with the code.
git add crates/ftui-demo-showcase/src/snapshots/
git add <your code changes>
git commitWhen to use BLESS=1 directly
BLESS=1 cargo test -p ftui-demo-showcase skips the review step and
overwrites every divergent baseline. Use it when:
- You are adding a new screen and its baseline doesn’t exist yet.
- You made a workspace-wide cosmetic change (e.g. a font metric update) and you’ve already manually verified the diffs are uniform.
- You’re scripting a CI job that regenerates baselines on a named branch.
Otherwise prefer cargo insta review so you actually see the diffs.
Committing snapshots
Snapshot files live under
crates/ftui-demo-showcase/src/snapshots/. They are plain text .snap
files — diff-friendly, grep-able, and small enough to commit without
LFS.
A typical commit looks like:
commit abc123
Author: you
widgets: fix Table hover style leak
The hover transition was missing a CUSUM reset so the style leaked
to the adjacent row on fast pointer movement.
crates/ftui-widgets/src/table.rs | 4 ++
crates/ftui-demo-showcase/src/snapshots/… | 12 ++++--Keep snapshot diffs reviewable by keeping code diffs small.
Running the showcase E2E
For full-showcase end-to-end runs under deterministic fixtures:
E2E_DETERMINISTIC=1 E2E_SEED=42 ./scripts/demo_showcase_e2e.shThis runs the showcase binary against a scripted input sequence with a fixed PRNG seed, captures frames at canonical tick points, and compares them against baselines. Used in CI as a determinism gate.
Pitfalls
Don’t BLESS=1 without reviewing the diffs. A diff you didn’t
intend can sneak in, and the next reviewer will have to back it out
in a separate commit. Always review with cargo insta review unless
you are certain.
Don’t commit .snap.new files. Those are the pending-review
artifacts; only .snap files are baselines. If you see .snap.new
in your working tree, run cargo insta review to accept or reject.
Don’t introduce non-determinism to fix a “flaky snapshot.” If a snapshot diverges run-to-run, that’s a determinism bug. Fix the source of non-determinism (usually a clock read, a PRNG without a seed, or a HashMap iteration). Baselines are only useful if they’re stable.
Don’t run BLESS=1 across a merge without resolving the snapshot
conflicts first. .snap files merge conflict like any text file;
the correct resolution is usually to take neither side, rerun the
tests, and re-bless from the merged code.