A scene per state, asserted, and the manual generated from it #12
No reviewers
Labels
No labels
⏳in-progress
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Grey.ooo/someones.computer_tray!12
Loading…
Reference in a new issue
No description provided.
Delete branch "feature/capture-suite-per-scene"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes nothing automatically — this is the tray half of the platform repo's
#627, whose other half is a pin bump in that repo. A cross-repo
Closeswill not fire, so #627 gets closed by hand once both land.Rebased on merged #11 and #6; #6's VM-capture plan in
hack/screenshot/README.mdis kept in full, with the dressing paragraph reconciled by hand.hack/screenshothad one scene, one walk and one golden. It now has nine scenes — one per state a user actually meets — each asserted as text and each illustrated in a manual that is generated from the same run.What is here
hack/screenshot/scenes/<name>/scene.json: what the platform answers, and the walk that photographs it. Merged overscenes/defaults.json, so a scene says only what makes it that scenephasesreplaces the listing N seconds in, which is the only way to capture a state that exists as a change — an application vanishing between two pollscheck.sh. Blessing is--blessand the diff is the reviewdocs/manual.md, assembled bymanual.pyout of the scenes and what they captured. CI fails a manual that is not what a rebuild produces, so it cannot driftThe nine, in the order the manual meets them: signed out · nothing deployed · the tree and its gestures · an activation followed to its outcome · an activation refused for credit · a deployment that can do neither · an application that went away · one that turned up · the platform not answering.
Three things about the harness that had to change
The walk names rows now; it does not count keypresses.
menudump --to 'shop · #12|main · running'reads the exported tree, skips exactly what GTK's keyboard skips, and prints the keystrokes that reach that row — so a row that moved is still reached, a row that is gone fails the run naming the labels it did find, and an ambiguous name fails rather than photographing whichever matched first. This is not tidying: the counted walk had been wrong for two commits.docs/images/*/tray-activate.pngonmainis a photograph ofOpen in browser, andtray-gestures.pngis billing'sActivaterather than the confirming stop it claims — both because the organization became a heading and every walk below it went one row too far. One of them was embedded in the README.The shutter waits for the screen to stop moving. Two identical consecutive frames, then keep that one. A third-level submenu under a compositor takes an unpredictable moment to paint and the difference between a good capture and a photograph of a half-drawn menu was about half a second, in either direction depending on the scene.
Some rows are clicked over the bus.
menudump --clicksends dbusmenu's ownEvent— the same call a real desktop's host makes. The scenes that are about a toggle's consequences use it, because the toggles live one level deeper than this host draws reliably (see #844 below), and what those scenes photograph is the consequence anyway.cmd/menudumpgrew tests for all of that: the label→keystroke arithmetic is exactly the kind of logic whose bugs are silent, and it took the package from 0% to 48.2% (floor bumped).What the captures found — read, not just attached
Policy point 2, doing its job. Five issues filed in the platform repo, none fixed here:
sc-traysays so only on a stderr nobody is reading — it refuses to start, and the user-visible state is an empty panelN new application(s) — restart sc-traybranch is unreachable dead code, overwritten two statements later in the same functionmenudumpproves it — and the host draws an empty stripupdateretitles the row andcontinues past the code that would have hidden them#844 is the one worth a reviewer's attention. It is unresolved whether it is the app or the harness's host — the honest answer needs a second host (KDE's, or an XFCE panel) and I have not run one. Until it is answered the suite works around it visibly rather than quietly:
gotomay go deeper than two levels, andscene.pyrefuses one that tries, naming the issue;inertscene deliberately has no photograph of its empty submenu, because such a picture is indistinguishable from #844;Two goldens (
in-flight,refused) record the wrong-but-current status row, with anormalise.sedbeside them explaining why and saying what to delete when #841 is fixed. A golden records what the app does; the issue records what it should do.Also fixed here, being in the way
run.shnever builtmenudump, sodocker buildfailed on a fresh checkout — fixed by #11, now merged, which this branch is rebased on.README.mdembeddeddocs/images/macos/tray-menu.pngcaptioned "The tray menu": a macOS-dressed Linux capture presented as the thing itself, which is policy point 5 broken in the most visible place in the repo. It now shows an undressed Linux capture, says so, and links the manual.docs/images/<theme>/tray-*.pngtodocs/images/<theme>/<scene>/. PR #9 also touches these paths (and commits a 4.4MBhack/screenshot/menudumpbinary by accident — worth dropping before it merges); whichever of us lands second re-runs./run.sh --bless.Dressing, still labelled as dressing
The suite captures undressed Linux and that is what the manual illustrates. One scene is additionally captured dressed for macOS and Windows, shown together at the end of the manual under one plain caveat.
check.shdiffs the dressed dumps against the same goldens, which turns the caveat into an assertion: the dressing provably changes nothing about the menu. Genuine captures still need #648.Verified
hack/screenshot/run.sh— two full runs, the second with nothing blessed, both green. All nine scenes plus the two dressed reproduce their goldens exactly.hack/lint.sh— 0 issues.hack/coverage.sh— green, floors bumped (cmd/menudump0.0 → 48.2).manual.py check— green.actionlint— clean.Evidence
Every capture in this PR is committed to the repo and quoted by docs/manual.md — the manual is the evidence, and it is version-controlled rather than pasted into a comment. The two that show most of what changed:
The tree, undressed, with the row order the first capture ever found wrong:
An unreachable platform, and #841's raw transport error making the menu 946px wide:
hack/screenshot had one scene, one walk and one golden. It now has nine scenes — one per state a user actually meets — each asserted as text, and each illustrated in docs/manual.md, which is assembled from the same run and so cannot drift from it. The scenes: signed out, nothing deployed, the tree and its gestures, an activation followed to its outcome, one refused for credit, a deployment that can do neither, an application that went away, one that turned up, and the platform not answering. Several are whole-process states that one container cannot share, and several exist only as a change over time, so a scene owns its own run and `phases` lets it change its answer partway through while the walk waits out the tray's poll. Three things about the harness had to change to make that honest: * The walk names rows rather than counting keypresses. menudump --to reads the exported tree, skips exactly what GTK's keyboard skips, and prints the keystrokes that reach a named row — so a row that moved is still reached, and one that is gone fails the run naming what it did find. This is not tidying: the counted walk had been wrong for two commits, and docs/images/*/tray-activate.png was a photograph of "Open in browser". * The shutter waits for two identical consecutive frames. A third-level submenu under a compositor takes an unpredictable moment to paint, and a fixed sleep either wastes time on every shot or quietly photographs a half-drawn menu. * Rows a scene needs pressed are clicked over dbusmenu's own Event, the same call a real host makes, because the toggles sit one level deeper than this host draws reliably. cmd/menudump grew tests for the label-to-keystroke arithmetic, whose bugs are silent by nature; its floor rises from 0.0 to 48.2. CI gains a job that takes the captures for real and fails if they differ from the commit. check.sh on its own diffs two committed files, which is how a golden reached main asserting a row main did not draw (#11). What reading the captures found is filed rather than fixed: platform #838, is worked around visibly rather than quietly: no goto may go deeper than two levels, scene.py refuses one that tries, the gestures are asserted as text instead, and the inert scene deliberately has no photograph of its empty submenu, because such a picture cannot be told apart from the bug. Two goldens record a wrong-but-current status row, with a normalise.sed beside them explaining why and naming what to delete when #841 is fixed. Also: README.md embedded a macOS-dressed Linux capture captioned "The tray menu", which is policy point 5 broken in the most visible place in the repo. It now shows an undressed Linux capture and says so. Refs: Grey.ooo/Someones.Computer#627The captures job could not run a single scene. `docker build -t sc-tray-shot` says the tag exists; on the house runner it does not. buildx's default builder there is the `docker-container` driver, which leaves the result in the build cache unless told otherwise — it warns about it, and the warning scrolls past — so `docker run sc-tray-shot` a line later went looking for a registry: docker: Error response from daemon: pull access denied for sc-tray-shot `--load` gives the daemon the tag. It is harmless where the builder is already the daemon's own, which is why this passed on a laptop. Two things found alongside it: * The tag and the container names now carry a per-run discriminator. That daemon is the runner host's, shared with every other job and worktree on it, and a fixed `sc-tray-shot` is a name two concurrent runs would clobber. CI passes the run id. * The "committed captures describe this binary" step is gone. It diffed the captured menu dumps, and every dump carries the wall-clock time of its sync — so the raw files differ on every run by construction and the step could only ever have been red. The assertion it was reaching for already exists one line up: run.sh ends by running check.sh against what it just captured, with the time normalised, which is exactly "the goldens still describe the binary".The captures job ran the whole suite green — eleven captures, every golden as recorded — and then failed on the last step, uploading the pictures: :⚠️:Artifact upload failed with error: GHESNotSupportedError: @actions/artifact v2.0.0+, upload-artifact@v4+ and download-artifact@v4+ are not currently supported on GHES Forgejo identifies as GHES and does not implement the v2 artifact API that upload-artifact@v4 requires, so a seven-minute run that proved the menu was reported as a red job because a convenience upload at the end of it could not work. The platform repo already pins v3 at every call site for exactly this reason; this repo now does the same, documented at the call site. Adds .github/actionlint.yaml with the matching suppression, since actionlint judges action versions against GitHub's hosted runners and will call a deliberate v3 pin too old. Same file and same reasoning as the platform repo's.WIP: A scene per state, asserted, and the manual generated from itto A scene per state, asserted, and the manual generated from it