Screenery × Pheidi

Screenshots that
fail the build
when they lie.

Every doc page, store listing, and product page wants a picture of the app. The app changes daily. The pictures change whenever somebody remembers, which is never. So now CI takes them, Screenery hosts them, and a test makes sure the two can't quietly drift apart.

This picture is live

It's Pheidi's "today" screen, straight from Screenery. When Pheidi ships a change to that screen, this image changes. Nobody touches this page.

Pheidi's today screen: today's run with pace and heart-rate targets, above this week's schedule.
cdn.screenery.dev/jfreal/pheidi/desktop/plan/today@latest.png

How the pictures get made

Pheidi's end-to-end tests already drive the real app in a real browser. Two of them just stop and take pictures: one set for the docs, one set for the Google Play listing. On every merge, CI pushes them to Screenery with screenery/push@v1. The Play listing video goes the same way.

There's no API key sitting in the repo. The push step trades GitHub's OIDC token for a five-minute credential. (The best secret is the one you never stored.)

Each picture gets a name like plan/today and a URL ending in @latest. Pull request builds publish to their own channel, so a half-done branch never replaces what the docs show. A merge to master does. The doc pages embed the URL once and never think about it again.

The failure nobody would notice

Here's the trap. The test that takes a picture says plan/today. The doc page that shows it also says plan/today. Nothing connects those two strings except a URL loading in a stranger's browser. Rename one, and a doc page serves a broken image forever. No build fails. No test fails. No deploy fails.

So Pheidi has a test just for that. It reads the list of names the doc pages use, reads every name the capture tests take, and fails if they don't match. It also checks the site's security policy still allows the Screenery CDN.

The fun detail: it reads the C# as a syntax tree, not with a regex. A regex would count a commented-out capture as real, so the check would pass while guarding nothing. That was checked on purpose: a commented-out capture passes the regex version and fails this one.

Pheidi paid it back

Pheidi was Screenery's proving ground. It's the worked example in Screenery's own CI-setup tests, and one of Screenery's regression tests is named after a real Pheidi setup that made an empty log look broken. Same deal as with Merge & Tell: Pheidi goes first, finds the weird edges, and the tool gets better for everyone after.

Everyone after, so far: Merge & Tell reshoots its screens on every merge, Auspex Fatalis gets a screenshot gallery on every pull request, and every live screenshot on this site comes from Screenery too.