28 lines
2.6 KiB
Markdown
28 lines
2.6 KiB
Markdown
---
|
|
name: static-page-headless-verify-traps
|
|
description: "Verify a static HTML artifact headlessly after writing it: serve on a scratch port, assert structure, screenshot — with the omp JS-eval/browser API traps (browser.open options object, no tab.wait, tab.run is Node-isolated, log() swallowed in JS cells)."
|
|
---
|
|
|
|
# Headless verify of a static HTML file — traps that cost cells
|
|
|
|
Use after writing/rewriting a self-contained HTML artifact (guide, report, landing page) that must be proven to render before commit.
|
|
|
|
## Loop
|
|
|
|
1. Serve: `Bun.spawn(["python3","-m","http.server","<port>","-d","<dir>"])` inside the eval cell; kill at cell end (`proc.kill(9)`), or `pkill -f "http.server <port>"` first if a prior cell died mid-run.
|
|
2. Open + assert + screenshot in ONE cell; also cross-check anchors statically with node (regex `href="#x"` vs `id="x"`) — no browser needed for that half.
|
|
3. Entity/markup contamination sweep with grep on the FILE (`"`, `&#`, raw `<` inside text): what renders small can hide real damage; conversely a suspicious screenshot is often just low-res misread — settle label text via `tab.text("svg")`/`tab.text(selector)` before "fixing" markup.
|
|
|
|
## Eval/browser API traps (all hit live 2026-10-21)
|
|
|
|
- `browser.open({ url })` — options OBJECT; `browser.open(url)` is a TypeError.
|
|
- `tab.wait(...)` does NOT exist — use `await Bun.sleep(ms)` or better `tab.waitForSelector/waitForText`.
|
|
- `tab.run(fnOrString)` executes in the isolated Node-side runtime: `document` is undefined there. For page-world expressions use `tab.evaluate("...string...")` (expression, no top-level `return`; wrap a function IIFE when you need one) or the direct helpers (`tab.text(sel)`, `tab.count`, `tab.attr`).
|
|
- **`log()` output from JS eval cells is silently swallowed** — even after successful browser calls. Extract data by `return`-ing the value from the cell (Python cells log fine; JS cells must return). A cell that "ran but printed nothing" usually means it printed via `log()` — re-run returning the payload.
|
|
- Screenshots come back as webp images in the tool result AND save via `screenshot({path})`; image text under ~13px is unreliable to read — verify exact strings via `tab.text()` instead of squinting.
|
|
|
|
## Static anchor/claim audit before rendering
|
|
|
|
- Counts, schema/table names, endpoint bodies: re-grep the SOURCE per claim; never trust numbers carried in from conversation memory (this caught "public vs franksign schema", "OR signer_user_id join that doesn't exist", wrong test-counts pre-commit).
|
|
- `git diff --stat` regenerated binary fixtures (PDF CreationDate churn) before committing docs — don't commit fixture noise the setup script wrote.
|