Store assets
Store assets
pekoshots generates App Store screenshots and preview recordings by driving
your real app through a scripted sequence and capturing its own webview. There is
no screen recording and no window chrome in the output.
It is a gated package, and it is scoped to demo builds so it cannot reach a shipped binary:
[dependencies]
pekoshots = { version = "0.1.0", demo = true }Attaching
import pekoshots as shots;
fn on_start() {
let application = ui::app::from_bundle();
demo {
shots::driver::attach(application, closure(d: shots::demo::Demo) => void {
register_demo(d);
});
}
application.run();
}attach is a no-op unless the demo environment is active, so the same entry
ships to production. Wrapping it in a demo { } block goes further and removes
the code at compile time, so the dependency never reaches the binary at all.
Authoring a shot
d.device(shots::catalog::iphone_69());
d.shots(closure(s: shots::builder::ShotSet) => void {
s.screenshot("home", closure(shot: shots::builder::Shot) => void {
shot.navigate("/")
.wait_for(sel("#feed"))
.caption("Everything in one place")
.capture()
});
});The catalog module provides the exact store dimensions: iphone_69,
ipad_13, mac_1440x900, play_phone, windows_1080p, and more.
Steps cover navigation (navigate, back, forward), waiting (wait_for,
wait_for_gone, wait_for_idle), interaction (click, double_click, hover,
type_text, fill, submit, press, scroll_to, drag), cursor control, and
labels. Targets are sel("#id") for an element's centre or
at("#id", x, y) for a point within it.
The one rule
Wait on conditions, never on time. Machines differ, and a sleep that works on your laptop fails in CI.
shot.click(sel("#save")).wait_for(sel(".saved")) // right
shot.click(sel("#save")).dwell(500) // wrong as a gatedwell(ms) exists, but it is a presentation pause inside a recording, not a
control gate. Everything that advances the script waits for a predicate:
an element appearing, an element disappearing, or the page going idle. Idle means
no in-flight requests and no DOM mutation for a short quiet period.
Verifying without capturing
peko demo
peko demo onboarding --from 2This builds in demo mode, launches against the dev server, and runs every step, printing each as it passes or fails. It produces no screenshots; it verifies that the scripts navigate, find their elements, and interact as written. That is the loop to iterate in, because a real capture run is slow.
--delay pauses between shots so you can watch. --shot runs one.
Fixtures
A demo module can declare a fixed user, seed data, a frozen clock, and a quiet mode. These are exposed to the app rather than applied by the compiler: the app fetches them at boot and decides what to do with them. That is what makes a screenshot run reproducible instead of showing whatever happened to be in your development database.