overlap-check: a text sliver at a scroll pane's edge is scrolled away, not covered (the miner's Earnings ladder under the closed log drawer's 1 px bar at c3fb95e3 read as covered); the clean fixture now carries that shape (7 October 2026, 16:1x UK)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
igneum-labs 2026-10-07 14:03:28 +00:00
parent b8e295076a
commit 9cffa3492c

View file

@ -141,7 +141,7 @@ async function measureInPage(opts) {
const ellipsis = (ccs.textOverflow === 'ellipsis' || cs.textOverflow === 'ellipsis') && (ccs.whiteSpace === 'nowrap' || cs.whiteSpace === 'nowrap');
add(ellipsis ? 'truncated' : 'clipped', el, clipper, text, q, Math.round(cut) + ' px cut by ' + sel(clipper));
}
if (vis.r - vis.l < 2 || vis.b - vis.t < 2) continue;
if (vis.r - vis.l < 2 || vis.b - vis.t < Math.min(q.height * 0.5, 8)) continue; // a sliver at a scroll pane's edge is scrolled away, not covered (the 1 px drawer bar under the miner's Earnings page, 7 Oct 2026)
const ym = (vis.t + vis.b) / 2; if (ym < 0 || ym > vh) continue;
const w = vis.r - vis.l; let covered = 0, by = null, pts = 0;
for (const f of [0.08, 0.3, 0.5, 0.7, 0.92]) {
@ -319,7 +319,9 @@ const FIXTURE_GOOD = `<!doctype html><meta charset=utf-8><style>body{margin:0;fo
</style>
<div class=scene><div class=cap><strong>03 / Locking</strong><br>Two thirds of the weight sign. The checkpoint locks.</div><div class=pill>01 Mine 02 Prove 03 Lock</div><a class=behind href=#></a></div>
<div class=card><h2>A card</h2><p>Some words with <a href=#>a link</a> and <strong>bold</strong> inline.</p><p class=ell>A long single line that ends in an ellipsis by design</p></div>
<button>A button</button> <span>beside text</span>`;
<button>A button</button> <span>beside text</span>
<div style="position:fixed;left:0;right:0;bottom:0;height:120px;overflow:auto"><p style="margin:0;line-height:20px">line 1<br>line 2<br>line 3<br>line 4<br>line 5<br>line 6<br>line 7 scrolled half under the pane's edge<br>line 8<br>line 9</p></div>
<div style="position:fixed;left:0;right:0;bottom:0;height:0;border-top:1px solid #777;box-shadow:0 -12px 30px #000"></div>`;
async function selfTest(pw) {
const srv = http.createServer((req, rs) => { rs.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); rs.end(req.url.includes('good') ? FIXTURE_GOOD : FIXTURE_BAD); });
await new Promise((r) => srv.listen(0, '127.0.0.1', r)); const port = srv.address().port;
@ -340,7 +342,8 @@ async function selfTest(pw) {
if (!k.has('covered') || !k.has('clipped') || !k.has('outside')) problems.push('kinds found on the bad fixture: ' + [...k].join(','));
}
if (!good || good.error) problems.push('the good fixture did not render: ' + (good && good.error));
else { const f = good.findings.filter((x) => !allowed(x) && x.kind !== 'truncated'); if (f.length) problems.push('the clean fixture was flagged: ' + f.map((x) => x.kind + ' ' + JSON.stringify(x.text) + ' by ' + x.by).join('; ')); if (!good.findings.some((x) => x.kind === 'truncated')) problems.push('the ellipsis line was not noted as truncated'); }
else { const f = good.findings.filter((x) => !allowed(x) && x.kind !== 'truncated'); if (f.length) problems.push('the clean fixture was flagged: ' + f.map((x) => x.kind + ' ' + JSON.stringify(x.text) + ' by ' + x.by).join('; ')); if (!good.findings.some((x) => x.kind === 'truncated')) problems.push('the ellipsis line was not noted as truncated');
if (good.findings.some((x) => /line [67]/.test(x.text) && x.kind === 'covered')) problems.push('a line scrolled under a pane edge with a 1 px bar was flagged as covered'); }
if (problems.length) { console.error('overlap-check self-test FAILED:\n ' + problems.join('\n ')); if (bad) console.error(JSON.stringify(bad.findings, null, 1)); return false; }
console.log(`overlap-check self-test passed: the pill over the caption, the clipped line, the label over the value and the text past the edge are flagged; the clean page passes, its ellipsis noted (${run.secs.toFixed(1)} s)`);
return true;