"""S2 of the anti-slop fix slices, read off the browser's COMPUTED style. The string tests in test_antislop.py read the stylesheet; a later rule in the cascade (`font-size:1px`, `color:transparent`, `filter:grayscale`, a placeholder at `opacity:0`) passes them and is still illegible (heid bug-hunt guard grid). These open the pages in the real uvicorn + Chromium harness and read what the browser will actually paint. Skips, never fails, when no usable Chromium exists. """ import pathlib import sys sys.path.insert(0, str(pathlib.Path(__file__).resolve().parent)) from test_flow_browser import _png, browser, live # noqa: E402,F401 (fixtures) WIDE = {"width": 1280, "height": 800} def _seed(root: pathlib.Path): from booth.benches import set_bench_state, upsert_bench from booth.links import LINKS_FILE from booth.marks import answer_pick, declare_pick, marks_for g = root / "g" g.mkdir() for n in ("a.png", "b.png"): (g / n).write_bytes(_png(64, 48)) from booth.marks import set_flag set_flag(g, "a.png", True) # the tray's number, the tile's stamp declare_pick(g, "p1", {"prompt": "Which?", "options": ["North", "South"]}) answer_pick(g, "p1", "North", who="127.0.0.1") r = root / "r" r.mkdir() (r / "index.html").write_text("r

R

body

") declare_pick(r, "p2", {"title": "Round one", "prompt": "Which gate?", "notes": True, "options": [{"id": "n", "label": "North", "detail": "the gate by the road"}, {"id": "s", "label": "South", "detail": "the loading dock"}]}) answer_pick(r, "p2", marks_for(r)[0].options[0]["id"], who="127.0.0.1") board = root / "links" board.mkdir() (board / LINKS_FILE).write_text("- [x](http://x.example/) · infra-ops · 2026-09-06 23:35\n") bench, _ = upsert_bench(root, "http://10.100.10.50:7788/talk", "talk demo", "booth") set_bench_state(root, bench.id, "retired") def _size(page, sel): return page.locator(sel).first.evaluate("e => parseFloat(getComputedStyle(e).fontSize)") def test_labels_and_sentences_render_at_their_floors(browser, live): base, root = live _seed(root) page = browser.new_page(viewport=WIDE) checks = [("/b/g/view?f=a.png", ".film-ord", 11), ("/b/g/marks", ".mark-state", 11), ("/", ".desk-rule", 12), ("/b/links/", ".board-note", 12), ("/b/links/", ".bench-note", 12)] for url, sel, floor in checks: page.goto(base + url, wait_until="load") assert _size(page, sel) >= floor, (url, sel, _size(page, sel)) # folded after the S2 gate: three labels the report's list did not name for url, sel in (("/b/g/", ".tray-ord"), ("/b/g/compare?a=a.png&b=b.png", ".film-ab")): page.goto(base + url, wait_until="load") assert _size(page, sel) >= 11, (url, sel, _size(page, sel)) page.goto(base + "/b/g/", wait_until="load") stamp = page.locator(".item.is-flagged").first.evaluate( "e => parseFloat(getComputedStyle(e, '::before').fontSize)") assert stamp >= 11, ("the tile's 'flagged' stamp", stamp) page.goto(base + "/b/r/", wait_until="load") page.wait_for_selector(".bk-ask-tag") assert _size(page, ".bk-ask-tag") >= 11 page.close() _FADE = """e => { const cs = getComputedStyle(e), parent = getComputedStyle(e.parentElement); const a = c => { const m = c.match(/rgba?\\(([^)]+)\\)/); if (!m) return 1; const p = m[1].split(','); return p.length > 3 ? parseFloat(p[3]) : 1; }; return {opacity: parseFloat(cs.opacity), filter: cs.filter, alpha: a(cs.color), color: cs.color, parent: parent.color}; }""" def test_nothing_fades(browser, live): base, root = live _seed(root) page = browser.new_page(viewport=WIDE) page.goto(base + "/b/r/", wait_until="load") page.wait_for_selector(".bk-ask-det") for sel in (".bk-ask-det", ".bk-ask-was", ".bk-ask-title"): got = page.locator(sel).first.evaluate(_FADE) assert got["opacity"] == 1 and got["filter"] == "none" and got["alpha"] == 1, (sel, got) det = page.locator(".bk-ask-det").first.evaluate(_FADE) assert det["color"] == det["parent"], ("details take the host's own colour", det) ph = page.locator(".bk-ask-notes").first.evaluate("""e => { const p = getComputedStyle(e, '::placeholder'); return {opacity: parseFloat(p.opacity), color: p.color, field: getComputedStyle(e).color}; }""") assert ph["opacity"] >= 0.7 and ph["color"] == ph["field"], ph page.goto(base + "/b/links/", wait_until="load") row = page.locator(".bench-row.is-retired").first.evaluate(_FADE) assert row["opacity"] == 1 and row["filter"] == "none", row page.close()