Repository navigation
Run robustness from the #59 feedback: heartbeat, mid-run origin abort, CSP-proof CSS, selector-aware ceiling - #96
Merged
Conversation
- Piped runs print `renderdiff: n/N shots` to stderr every tenth of the run. - An origin that stops responding mid-run aborts with exit 2, before any report or --cache-right recording is written. - Inject renderdiff's CSS as an adopted constructed stylesheet: addStyleTag rejects on any CSP violation logged during injection, and a <style> is subject to style-src. - The area ceiling tests what is shot, so a selector on a very long page compares. - Block get.geojs.io by default; say results.json is one JSON document. Part of #59. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…st comment Co-Authored-By: Claude Opus 5.5 <[email protected]>
This was referenced Oct 30, 2026
Merged
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.
Part of #59. This PR takes the remaining small, root-cause items from that feedback. The rest is either already fixed on main or should be split out (lists at the end).
Changes
renderdiff: n/N shotsevery tenth of the run, plus one at the end. Stdout's compact summary is unchanged. SKILL.md now says to run long runs in the background and watch these lines.--help, README and reference.md are updated.ERR_CONNECTION_REFUSED, renderdiff checks both origins again with the preflight'salive(), which moved toconfig.tsso cli and run share it.downflag stops every worker's loop. Aqueue.pushretry can't revive the run, because the loop checks the flag, not the queue.✗ right (<url>) stopped responding mid-run.saveRecording, so no partial--cache-rightHAR is saved, and before any report is written.addStyleTagruns inside_raceWithCSPError, so it rejects on any "Content Security Policy" console error logged while it injects. A site's own blocked analytics script is enough (docs/case-study.md); that's why these errors moved between routes and widths from run to run. A<style>is also subject tostyle-src.document.adoptedStyleSheets, through one helper used at both injection sites. CSP doesn't govern constructed sheets, and adopted sheets sort after the document's own.@importinextraCssis ignored. That's noted on the option.clip ?? page), so--selectoror@selon a very long page compares that element. An element that is itself past the ceiling is still refused (element is …).get.geojs.iois now in the default blocklist. It's a geo-IP lookup that decides whether a consent banner shows.results.jsondocs (reference.md and docs/output.md) say the per-line results sit inside one JSON document, with trailing commas.Tests
guardrails:/csp: both sides sendstyle-src 'self'and are styled only via/shared/base.css, and a consent banner is on the left only. The shot must compare with 0 diff pixels, which shows the hide selectors applied./long @h1at 1440 must compare./hangfixture now wedges on theadoptedStyleSheetssetter instead of a<style>mutation.controls: the piped run's stderr must end withrenderdiff: 25/25 shots(the total), with 2–10 heartbeat lines.capture.tschange stashed, the CSP and selector-ceiling tests fail.Verification:
npm run typecheck,npm run lintandnpm run format:checkare clean.npm testpasses 357/357 andnpm run test:visualpasses 389/389, both on macOS.Already fixed on main since 0.5.0
--computedorigin normalization.gototimeout.variesrecheck (Recheck differing shots for load-to-load variation #47),probe(renderdiff probe: list elements whose box varies between loads #73) and grouped findings (Group identical pixel findings across routes and widths #48).--sitemap(--sitemap: take routes from the reference's sitemap.xml #46) and the serve docs (Docs: serve static builds with serve.json (clean URLs, trailing slash, rewrites) #52).beforeShot(beforeShot hook: run after the scroll pass, right before the shot #71) andmerge(renderdiff merge: fold a partial rerun into a full results.json #76).evidence.htmlis self-contained.Left for separate issues
beforechaining the global one (changes documented semantics).nameorstatefield.waitForand pinned iframe heights.report --compact, WebP and gh-pages.--openover HTTP;renderdiff serve.--routes-file.--rerun-failedacross config changes.🤖 Generated with Claude Code