Repository navigation
test(inbox): pixel and DOM parity harness for the thread - #2222
Merged
Merged
Conversation
One command (bun run test:parity:inbox-thread) builds a dev binary of origin/main as the reference and one of this checkout as the candidate, seeds one scratch data dir with the reference binary, and captures every seeded thread with both, each project on its own copy of the seed: desktop light and dark, the thread pane at 360 px, an iPhone 15 in WebKit and a Pixel 7 in Chromium. Zero-pixel toHaveScreenshot plus a normalized outerHTML diff; report.md and report.json under .local/parity/. Test-only: no product code changes.
…ps and later clocks - Live delivery, last: the spec polls the bridge as three seeded sessions (Claude Code busy with Send now; Claude Code busy on an older plugin, with a plugin registry in the scratch HOME; Pi busy) and sets the page clock from the Inbox's own wait clock, so Undelivered, Send now and the restart line read the same minutes in both runs. - The list's rows (start, end with Quiet open, later clocks) are captured too. - Tooltips on a desktop: a time's whole moment, a folded line's time and answers, the thumbs-up pill, each delivery tick in the list. - The Files band open; a thumbs-up inside its Undo window (its real-clock times rewritten to 12:00 PM for the capture). - Later clocks: the list and each thread 3 and 400 days on. - Seed: a link choice answered (today's raw markdown) beside picture choices; the thumbs-up delivered to Pi. - Projects: + the pane at 360 px dark, at 320 px, iPhone 15 dark. - console.error is recorded (the sandboxed srcdoc's blocked-script line is the sandbox working and is left out); an actionTimeout so a blocked click fails with its reason; PLANNOTATOR_INBOX_NOTES=0 (the scratch HOME now has a ~/.claude); WebKit waits out its low-quality image repaint. main vs main: 708 screenshots and 828 DOM files, 0 differing.
…ure; names its clip-row noise WebKit can blend the one pixel row where the thread's scroller clips a picture tile a few colour levels differently from run to run (main against itself too). A full repaint of the scrollers after the image-quality wait makes it rarer; the guide says what it looks like (that row only, the DOM matching).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Slice 0 of the Inbox thread extract (plan record, not in this repo): a reproducible pixel and DOM parity harness for the thread. Test-only: no product code changes. Not part of
test:e2e:inboxor CI.One command
Binaries. The reference is a dev build (
__CLI_VERSION__="0.0.0-dev", built review then hook) of--base. It is built in a temporary git worktree and cached in.local/parity/bin/base-<sha>/plannotator. The candidate is a dev build of this checkout. Each binary must be namedplannotator, becauseprovenInboxrequires it.One seed. The reference binary seeds one scratch data dir (
tests/e2e/inbox-thread-parity-seed.ts) through the real routes, then stops. The seed has:The seed also records the sessions that asked, for the live captures (step 3).
Captures (
tests/e2e/inbox-thread-parity.config.ts). Every project copies the seed and starts its own Inbox on the copy. The projects:The page clock is fixed at the seed's
frozenAt. The locale isen-USand the time zone isAmerica/New_York. Motion is reduced, and animations and the caret are off. Fonts and images are loaded and decoded before each capture; WebKit also waits out its half-second high-quality image repaint. Chromium runs without the GPU and without partial raster.PLANNOTATOR_INBOX_NOTES=0keeps the note offer away, because the scratch HOME has a~/.claude(the plugin registry, for the restart line). In order, the harness captures:Comparison. Screenshots must match at zero pixels (
toHaveScreenshot,threshold: 0,maxDiffPixels: 0). TheouterHTMLof what each capture shows is normalized for the port, the server session, blob URLs, the HTML asset token and the scratch folder, and diffed file by file. Each step's page errors andconsole.errorlines are diffed too (the sandboxed HTML attachment's "Blocked script execution" line is the sandbox working, and is left out). AnactionTimeoutmakes a blocked click fail with its reason. The script writesreport.mdandreport.json, withdom-diff/and the actual, expected and diff PNGs. It exits 0 only when every capture is identical.The sandbox is the same as the e2e specs: scratch HOME and
PLANNOTATOR_DATA_DIR,NO_BROWSER,PLANNOTATOR_INBOX_CONNECT=0andPLANNOTATOR_UPDATE_CHECK=0, with phones, the relay and update URLs pointed nowhere. It never touches~/.plannotator. It is documented indocs/agent-guides/inbox-phones-and-security.md.Proof
.ib-newdivgap10px → 11px plus adata-parity-probeattribute on the divider): 91 screenshots differing (510 px each on desktop) and 133 DOM files differing. Exit 1. The first version caught 21 and 46.never-touch-the-real-inbox,no-browser-sentinel,child-env-guardandagents-md-size.