Repository navigation
--computed: diff links' and controls' :hover and :focus-visible styles - #95
Merged
Merged
Conversation
After the resting walk, the first 500 links and controls per page are forced into :hover, then :focus+:focus-visible, over CDP (all at once), and their subtrees are read again under `key:hover` / `key:focus-visible`. A state only reports what differs from resting. The snapshot also reads outline and text-decoration-line (SNAP_PROPS); pixel mode's PROPS, and so accepted fingerprints, are unchanged. Fixes #51 Co-Authored-By: Claude Opus 5.5 <[email protected]>
…orcing in the cap test The global was set before the session existed, so a failed newCDPSession left it on the page. The cap test now checks the forced :hover value, so it fails when forcing doesn't happen. Co-Authored-By: Claude Opus 5.5 <[email protected]>
tmashara
force-pushed
the
claude/issue-51-computed-states
branch
from
October 29, 2026 19:55
a2f7f4d to
9e3e338
Compare
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.
What / why
--computedonly read the resting state, so a dead-CSS removal that dropped a hover colour or a focus ring passed silently (#51). Now, after the resting walk, links and controls (a[href], button, input, select, textarea, summary, [tabindex]) are read again in:hoverand:focus-visible, subtrees included, and diffed like any other key:Real output: the visual test's link (
a:hover{color:red} a:focus-visible{outline:2px solid blue}on the left only) at/, and 812 links at/docs,--width 1280 --computed:(
border-top-colorfollowscurrentColor, as it does for resting colour changes.)The snapshot also reads
outlineandtext-decoration-line(the usual focus ring and hover underline). These live in a newSNAP_PROPS; pixel mode'sPROPSis untouched, soElementDiff.changedand accepted fingerprints don't move.How states are forced
snapshotStatesinlocate.ts). The resting walk keeps the elements on a page global and returns their keys in order;Runtime.getProperties+DOM.requestNodeturn them into nodeIds with no DOM mutation (works for--selector:scoperoots too).CSS.forcePseudoStateon all of them at once (["hover"], then["focus","focus-visible"]; a new force replaces the last), then the in-page walk visits only those elements underkey:hover/key:focus-visible, reusingvisit(children…:hover > span,…:hover::before).finallydeletes the global and detaches, which clears every forced state, before it resolves; the page is resting for whatever runs next. Runs after the screenshots andlocate, so pixels never see a forced state.collapseInherited), so a resting change isn't repeated per state. State keys don't count towardsdomorunmatched.What forcing all at once misses: rules relating two forced elements (
ul:has(a:hover) a:not(:hover)dims siblings only when one is hovered),:hoveron ancestors (forcing never sets it, soli:hover > ulmenus aren't seen),:active,:focus-within, script hover handlers. Per-element forcing would catch the first but costs a style recalc each (~10 s at 2000 links). It never invents a finding.Caps
computed.unchecked, max of the two sides) and named on astates:line.<main tabindex=-1>would re-walk the page per state).Cost (M-series mac, one side; both sides run in parallel)
How tested
tests/visual/computed.test.ts: hover colour one side drops → onlya:hover color(+ currentColor border); a dropped focus ring →a:focus-visible outline;a:hover .icon→ keyeda:hover > span.icon; identical states → nothing, and a restingtext-decorationchange isn't repeated per state; 501 links →unchecked1, global gone and a resting re-read equals the one before.tests/unit/computed.test.ts: a one-sided state key isn't markup (dom,unmatched), the resting dedupe, thestates:line.CSS.forcePseudoStatestubbed out, or the state passes skipped, the hover, focus, child and cap tests fail; without the detach or the global's delete the cap test fails; without the resting dedupe the dedupe test fails. Full unit (354) and visual (385) tiers pass after rebasing on--aria(Add --aria: diff ARIA snapshots per route #93), includingaccepted.test.tsand the pixel-mode pins, unchanged. typecheck, lint, format:check clean.docs/output.md§ Computed styles, README and--helpflag rows, skill reference/SKILL wording on unshot states.Fixes #51
🤖 Generated with Claude Code