Hover capture via forced pseudo-state, text-wrap support, per-viewport video source re-selection, svg paint recovery, semantic tokens & section naming
Capture: - Hover/focus states are driven with CDP CSS.forcePseudoState instead of moving the real cursor - transparent full-viewport overlay layers were swallowing every pointer hover, silently capturing zero hover states on hover-rich sites - text-wrap (balance/pretty) captured and emitted (Tailwind text-balance/ text-pretty, arbitrary fallback) - Videos re-run <source> selection per viewport before frame-0 normalization: resize-without-reload kept aspect-gated variants stuck on the load-time choice, poisoning mobile ground-truth screenshots - svg roots capture their computed paint; fill="none" with a computed paint (the fill-current pattern) recovers the real color instead of rendering blank Tokens & naming: - Full CSS-Color-4 parsing (oklab/oklch/lab/lch/hsl) so modern colors cluster and earn semantic roles; visually-equal literals share one token; decoration/gradient/shadow colors consult the palette before minting opaque tokens (ridge: 45 opaque tokens -> 15, anthropic: 12 -> 7) - Expanded role vocabulary (background/foreground/primary/accent/border/ surface/muted) with deterministic tiebreaks and a chroma guard - Section names mine CMS section ids and js-* hooks with hashy-suffix stripping (split_callout_JtTWTt -> split-callout-section) 364 tests pass (42 new), typecheck clean; determinism verified by double-regen byte-comparison on two reference runs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
db0054e43b
commit
6e4921884c
@@ -317,3 +317,35 @@ describe("walker sizing probe: circular authored-height guard", () => {
|
||||
assert.equal(pct.sizing!.hAuto, false, "percentage fill is not content-sized");
|
||||
});
|
||||
});
|
||||
|
||||
describe("walker text-wrap capture", () => {
|
||||
let browser: Browser;
|
||||
let page: Page;
|
||||
before(async () => {
|
||||
browser = await chromium.launch();
|
||||
page = await browser.newPage({ viewport: { width: 1280, height: 800 } });
|
||||
});
|
||||
after(async () => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
const capture = async (html: string) => {
|
||||
await page.setContent(html);
|
||||
await page.evaluate("globalThis.__name = globalThis.__name || ((fn) => fn);");
|
||||
return page.evaluate(collectPage);
|
||||
};
|
||||
|
||||
it("captures text-wrap:balance on a heading (modern line-balancing)", async () => {
|
||||
// Real case: a hero heading authored `text-wrap:balance` wraps its two lines evenly; without
|
||||
// capturing the prop the clone wraps it lopsidedly.
|
||||
const snap = await capture(`<h1 style="text-wrap:balance">BUILT RUGGED. WORN DAILY.</h1>`);
|
||||
const h1 = findByTag(snap.root, "h1")!;
|
||||
assert.equal(h1.computed.textWrap, "balance", "text-wrap:balance is captured");
|
||||
});
|
||||
|
||||
it("captures text-wrap:pretty", async () => {
|
||||
const snap = await capture(`<p style="text-wrap:pretty">Some flowing paragraph text here.</p>`);
|
||||
const p = findByTag(snap.root, "p")!;
|
||||
assert.equal(p.computed.textWrap, "pretty", "text-wrap:pretty is captured");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user