v4.6.2
Fixed
-
Content-length reflow no longer produces a blind visual-approval gate.
Captures now persist only each element's normalized own-text length, including
explicit zeroes (never its text), so the diff can distinguish content-driven
geometry drift from a real sizing-rule change. Geometry deltas paired with a
changed text length, or with a legacy map where length is unknown, now fail
closed asCERTIFICATION_FAILEDinstead of asking reviewers to approve an
empty or misleading CSS report; known same-length geometry remains reviewable. -
freezeClocknow pins the spec process's clock, not just the browser's.
A capture spec that computed a fixture at module level —
const GENERATED_AT = new Date().toISOString()— ran on the live Node clock,
outside the browser freeze, so each capture run baked its own wall clock into
the data it served. Any surface rendering that stamp as text drifted in width
between the base and head runs and was reported as computed-style changes on
PRs that never touched those surfaces. The in-run self-check cannot catch this
class: both of its captures share one spec process and therefore one stamp.
styleproof-mapnow setsSTYLEPROOF_FREEZE_SPEC_CLOCK=1for the Playwright
run it spawns, and importingstyleproofunder that env swapsglobalThis.Date
for a frozen twin (zero-argument construction,Date.now(), and bareDate()
report the fixed instant; explicit-argument construction,Date.parse/Date.UTC,
and instance methods stay real) before the spec's own constants evaluate.
The instant followsSTYLEPROOF_CLOCK_TIME(default2025-01-01T00:00:00Z,
matching the browser freeze);STYLEPROOF_FREEZE_SPEC_CLOCK=0or
freezeClock: falseopts out, and aclockTimethat disagrees with the
frozen instant is warned about rather than silently ignored. StyleProof's own
elapsed-time bookkeeping (settle windows, popup deadlines,createdAt
manifest stamps) reads the real clock throughout. -
styleproof-ci --spec-refnow overlays the spec's colocated test harness.
A head spec that imported a head-only fixture failed cold base capture with
Cannot find module, producing a degraded head-only receipt. The base render
now receives the head harness while application code and package metadata stay
pinned to the base commit, and every overlaid path is restored before head
capture. When the consumer command runs from a repository subdirectory, the
temporary harness allowance is normalized to repository-root coordinates so
git status --porcelaindoes not misclassify the intentional overlay as a
dirty base tree.