nornir-saga
Saga — capture a user's navigation (nav / click / log) as structured events, persist them to the nornir warehouse, and let the test matrix replay the path as a generated robot test for bug-finding and regression.
It is the production sibling of nornir-testmatrix: emit real state from inside the running app → warehouse → read it back as a replayable saga.
The core is toolkit-neutral — pure std + serde, with no eframe / leptos / iceberg / arrow dependencies — so any frontend (an egui app or a web Leptos + Axum app) can pull it cheaply. The capture buffer (record() / drain()) is a process-global, gated behind the saga feature, so a default build pays zero cost and carries no dependency edge: only the serde event types, the warehouse sink, and the replay planner are in the default surface.
What it gives you
- Record — structured
SagaEvents (navigation, clicks, log lines) emitted from inside the live app. - Persist — a warehouse sink writes the events to nornir's
saga_eventsstream. - Replay — the test matrix reads the recorded path back and replays it as a generated robot test, turning a real user session into a reproducible regression case.
ui — live UI-movement viewer + replay
The ui module is the second face of the crate: capture a saga-enabled Elm app's ordered Msg stream (pointer / click / nav / focus / scroll / edit) and view it live or replay it deterministically so a web page re-animates the recorded session. It shares the same dev-only discipline:
- Contract —
ui::UiMsg/TimedUiMsg/Saga(tagged serde,f64coordinates round-trip exactly via serde_jsonfloat_roundtrip). - Capture — the one-liner
ui::tap(&msg)at your Elmupdate(featuresaga, compiled out of release), or the pluggable emit seamui::Emitter<S>overui::UiSink(VecSink/ChannelSinkfor LIVE /NullSink). - View + replay —
ui::Viewer(Elm fold →state_json),ui::Player(seekable, time-scaled, deterministic frames),ui::WebReplayDriver(drive a real page; mock/no-op built in, real WebDriver behind featuredrive), and an axum + SSE web frontend behind featureweb. - Wire-against fixture —
ui::wire_synthetic/ui::SyntheticAppdrive a synthetic saga-enabled Elm app end to end (capture → persist → replay) with no real host and no browser. Runnornir saga view --demoto see it.
Design + how-to: .nornir/saga-design.md, .nornir/saga-idiot-guide.md.
License
MIT OR Apache-2.0