Page annotation with ref labels, bounding boxes, and dimensions.
Injects CSS overlays directly into the page DOM. Overlays persist until
explicitly removed with remove-overlays!. No AWT dependency — works in
GraalVM native-image without any java.awt configuration.
Usage: (def snap (snapshot/capture-snapshot page)) (inject-overlays! page (:refs snap)) ;; overlays now visible on page ;; ... inspect, screenshot, etc. ... (remove-overlays! page) ;; clean up
Page annotation with ref labels, bounding boxes, and dimensions. Injects CSS overlays directly into the page DOM. Overlays persist until explicitly removed with `remove-overlays!`. No AWT dependency — works in GraalVM native-image without any java.awt configuration. Usage: (def snap (snapshot/capture-snapshot page)) (inject-overlays! page (:refs snap)) ;; overlays now visible on page ;; ... inspect, screenshot, etc. ... (remove-overlays! page) ;; clean up
(annotated-screenshot page refs)(annotated-screenshot page refs opts)Takes a screenshot with annotation overlays (convenience function).
Injects CSS overlays into the page, takes a screenshot, then removes them. Only annotates elements visible in the current viewport. No AWT dependency — everything is done in the browser.
Params:
page - Playwright Page instance.
refs - Map from capture-snapshot.
opts - Map, optional.
:scope - String. CSS selector or snapshot ref (@e1, e1) to restrict
annotations to a subtree.
:show-dimensions - Boolean (default true). Show width x height in labels.
:show-badges - Boolean (default true). Show compact labels.
:show-boxes - Boolean (default true). Show bounding box outlines.
:full-page - Boolean (default false). Capture full scrollable page.
Returns: byte[] of the annotated PNG.
Takes a screenshot with annotation overlays (convenience function).
Injects CSS overlays into the page, takes a screenshot, then removes them.
Only annotates elements visible in the current viewport.
No AWT dependency — everything is done in the browser.
Params:
`page` - Playwright Page instance.
`refs` - Map from capture-snapshot.
`opts` - Map, optional.
:scope - String. CSS selector or snapshot ref (@e1, e1) to restrict
annotations to a subtree.
:show-dimensions - Boolean (default true). Show width x height in labels.
:show-badges - Boolean (default true). Show compact labels.
:show-boxes - Boolean (default true). Show bounding box outlines.
:full-page - Boolean (default false). Capture full scrollable page.
Returns:
byte[] of the annotated PNG.(audit-screenshot page caption)(audit-screenshot page caption opts)Takes a screenshot with an optional caption bar at the bottom.
Can also include annotation overlays and/or action markers. The caption is injected as a fixed-position bar, captured in the screenshot, then removed — page state is not modified.
Params:
page - Playwright Page instance.
caption - String. Caption text to display at the bottom of the screenshot.
opts - Map, optional.
:refs - Snapshot refs map. When provided, annotation overlays are included.
:markers - Collection of ref IDs to mark (e.g. ["e5"]). Action markers are included.
:full-page - Boolean (default false). Capture full scrollable page.
Returns: byte[] of the PNG.
Takes a screenshot with an optional caption bar at the bottom. Can also include annotation overlays and/or action markers. The caption is injected as a fixed-position bar, captured in the screenshot, then removed — page state is not modified. Params: `page` - Playwright Page instance. `caption` - String. Caption text to display at the bottom of the screenshot. `opts` - Map, optional. :refs - Snapshot refs map. When provided, annotation overlays are included. :markers - Collection of ref IDs to mark (e.g. ["e5"]). Action markers are included. :full-page - Boolean (default false). Capture full scrollable page. Returns: byte[] of the PNG.
(check-visible-refs page refs)Runs JavaScript in the page to determine which refs are truly visible.
Two-phase check for each ref:
Returns a set of ref IDs that are actually visible.
Runs JavaScript in the page to determine which refs are truly visible. Two-phase check for each ref: 1. Multi-point elementFromPoint (center + 4 inset corners) — pierces invisible overlays (opacity:0, visibility:hidden, pointer-events:none). Walks up from hit element checking for matching data-pw-ref. 2. Fallback: direct style check — queries the element by data-pw-ref and verifies computed display/visibility/opacity. Catches elements under transparent containers (e.g., a logo under a transparent navbar). Returns a set of ref IDs that are actually visible.
(filter-annotatable refs)Filters refs to only those worth rendering as overlays.
Two-step process:
Returns a subset of refs suitable for build-inject-js.
Filters refs to only those worth rendering as overlays. Two-step process: 1. Remove structural roles (paragraph, list, span, etc.) 2. Remove containers whose bbox fully wraps a smaller ref Returns a subset of refs suitable for `build-inject-js`.
(inject-action-markers! page ref-ids)Injects prominent pre-action markers on specific snapshot refs.
Markers are visually distinct from annotation overlays: bright red/orange pulsing border with a '→ eN' label. Used to highlight elements before interacting with them, making screenshots self-documenting.
Markers use data-spel-action-marker attribute and are independent of
annotation overlays (data-spel-annotate).
Params:
page - Playwright Page instance.
ref-ids - Collection of ref ID strings (e.g. ["e5" "e12"]).
Accepts both "e5" and "@e5" formats (@ is stripped).
Returns: Count of successfully created markers (long).
Injects prominent pre-action markers on specific snapshot refs.
Markers are visually distinct from annotation overlays: bright red/orange
pulsing border with a '→ eN' label. Used to highlight elements before
interacting with them, making screenshots self-documenting.
Markers use `data-spel-action-marker` attribute and are independent of
annotation overlays (`data-spel-annotate`).
Params:
`page` - Playwright Page instance.
`ref-ids` - Collection of ref ID strings (e.g. ["e5" "e12"]).
Accepts both "e5" and "@e5" formats (@ is stripped).
Returns:
Count of successfully created markers (long).(inject-overlays! page refs)(inject-overlays! page refs opts)Injects annotation overlays into the page DOM for visible elements only.
Four-phase filtering pipeline: 0. Scope filter: restrict to refs within a CSS selector's DOM subtree
Params:
page - Playwright Page instance.
refs - Map from capture-snapshot. {"e1" {:role :name :bbox {:x :y :width :height}} ...}
opts - Map, optional.
:scope - String. CSS selector or snapshot ref (@e1, e1) to restrict
annotations to a subtree. Only elements that are descendants
of the matched element will be annotated. Requires prior
snapshot (elements tagged with data-pw-ref).
:full-page - Boolean (default false). Annotate all elements on the page,
not just those visible in the current viewport.
:show-dimensions - Boolean (default true). Show width x height in labels.
:show-badges - Boolean (default true). Show compact labels.
:show-boxes - Boolean (default true). Show bounding box outlines.
Returns: count of annotated elements (long).
Injects annotation overlays into the page DOM for visible elements only.
Four-phase filtering pipeline:
0. Scope filter: restrict to refs within a CSS selector's DOM subtree
1. Annotation filter: skip structural roles + remove containers
2. Clojure-side: bbox-in-viewport pre-filter (fast, no JS roundtrip)
3. JS-side: elementFromPoint check at each center (detects occlusion,
hidden CSS, aria-hidden, and verifies semantic role match)
Params:
`page` - Playwright Page instance.
`refs` - Map from capture-snapshot. {"e1" {:role :name :bbox {:x :y :width :height}} ...}
`opts` - Map, optional.
:scope - String. CSS selector or snapshot ref (@e1, e1) to restrict
annotations to a subtree. Only elements that are descendants
of the matched element will be annotated. Requires prior
snapshot (elements tagged with data-pw-ref).
:full-page - Boolean (default false). Annotate all elements on the page,
not just those visible in the current viewport.
:show-dimensions - Boolean (default true). Show width x height in labels.
:show-badges - Boolean (default true). Show compact labels.
:show-boxes - Boolean (default true). Show bounding box outlines.
Returns: count of annotated elements (long).(remove-action-markers! page)Removes all pre-action markers from the page DOM.
Returns: nil.
Removes all pre-action markers from the page DOM. Returns: nil.
(remove-containers refs)Removes refs whose bbox fully contains another ref's bbox.
When a parent element fully wraps a child (e.g., paragraph around a link), the parent is suppressed to avoid overlapping boxes and labels. Ties on identical-size bboxes are broken by ref ID (lower ID kept).
Removes refs whose bbox fully contains another ref's bbox. When a parent element fully wraps a child (e.g., paragraph around a link), the parent is suppressed to avoid overlapping boxes and labels. Ties on identical-size bboxes are broken by ref ID (lower ID kept).
(remove-overlays! page)Removes all annotation overlays from the page DOM.
Returns: nil.
Removes all annotation overlays from the page DOM. Returns: nil.
(report->html entries)(report->html entries opts)Builds a rich HTML report from a sequence of typed entries.
Each entry is a map with a :type key that determines rendering:
:screenshot — {:type :screenshot :image byte[] :caption str :page-break bool} :section — {:type :section :text str :level (1|2|3) :page-break bool} :observation — {:type :observation :text str :items [str...]} :issue — {:type :issue :text str :items [str...]} :good — {:type :good :text str :items [str...]} :table — {:type :table :headers [str...] :rows [[str...]...]} :meta — {:type :meta :fields [[label value]...]} :text — {:type :text :text str} :html — {:type :html :content str} (raw HTML, no escaping)
Params:
entries - Sequence of typed entry maps.
opts - Map, optional.
:title - String. Document title and h1 heading.
Returns: String of the HTML document.
Builds a rich HTML report from a sequence of typed entries.
Each entry is a map with a :type key that determines rendering:
:screenshot — {:type :screenshot :image byte[] :caption str :page-break bool}
:section — {:type :section :text str :level (1|2|3) :page-break bool}
:observation — {:type :observation :text str :items [str...]}
:issue — {:type :issue :text str :items [str...]}
:good — {:type :good :text str :items [str...]}
:table — {:type :table :headers [str...] :rows [[str...]...]}
:meta — {:type :meta :fields [[label value]...]}
:text — {:type :text :text str}
:html — {:type :html :content str} (raw HTML, no escaping)
Params:
`entries` - Sequence of typed entry maps.
`opts` - Map, optional.
:title - String. Document title and h1 heading.
Returns:
String of the HTML document.(report->pdf page entries)(report->pdf page entries opts)Renders a rich HTML report to PDF via Playwright's page.pdf().
Same entry types as report->html. Requires a Chromium headless page.
Params:
page - Playwright Page instance (Chromium headless only).
entries - Sequence of typed entry maps (see report->html).
opts - Map, optional.
:title - String. Document title and h1 heading.
:path - String. Output file path. If nil, returns byte[].
:format - String. Page format (default "A4").
:margin - Map with :top :bottom :left :right (default 20px each).
Returns: byte[] of the PDF, or nil if :path was provided.
Renders a rich HTML report to PDF via Playwright's page.pdf(). Same entry types as `report->html`. Requires a Chromium headless page. Params: `page` - Playwright Page instance (Chromium headless only). `entries` - Sequence of typed entry maps (see `report->html`). `opts` - Map, optional. :title - String. Document title and h1 heading. :path - String. Output file path. If nil, returns byte[]. :format - String. Page format (default "A4"). :margin - Map with :top :bottom :left :right (default 20px each). Returns: byte[] of the PDF, or nil if :path was provided.
(save-annotated-screenshot! page refs path)(save-annotated-screenshot! page refs path opts)Takes an annotated screenshot and saves it to a file.
Params:
page - Playwright Page instance.
refs - Map from capture-snapshot.
path - String. File path for the output PNG.
opts - Map, optional. Same as annotated-screenshot (supports :scope).
Returns: nil.
Takes an annotated screenshot and saves it to a file. Params: `page` - Playwright Page instance. `refs` - Map from capture-snapshot. `path` - String. File path for the output PNG. `opts` - Map, optional. Same as annotated-screenshot (supports :scope). Returns: nil.
(save-audit-screenshot! page caption path)(save-audit-screenshot! page caption path opts)Takes an audit screenshot and saves it to a file.
Params:
page - Playwright Page instance.
caption - String. Caption text for the screenshot.
path - String. File path for the output PNG.
opts - Map, optional. Same as audit-screenshot.
Returns: nil.
Takes an audit screenshot and saves it to a file. Params: `page` - Playwright Page instance. `caption` - String. Caption text for the screenshot. `path` - String. File path for the output PNG. `opts` - Map, optional. Same as audit-screenshot. Returns: nil.
(visible-refs viewport refs)Filters refs to only those whose bbox is at least partially visible within the given viewport dimensions.
viewport — {:width N :height N}
refs — snapshot refs map
Filters refs to only those whose bbox is at least partially visible
within the given viewport dimensions.
`viewport` — {:width N :height N}
`refs` — snapshot refs mapcljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |