Rendered Surface browser fixtures
These pages exercise Canvas discovery through a real browser DOMSnapshot and AX tree. They are deliberately framework- and site-independent.
Serve
From the repository root:
python3 -m http.server 4173 --bind 127.0.0.1 \
--directory apps/extension/test-fixtures/rendered-surfaces
Use an Agent Window large enough to keep the primary matrix visible:
bsk session start --width 1440 --height 1100
bsk navigate http://127.0.0.1:4173/index.html --session <id>
bsk observe --session <id>
Always stop the session after the run.
Pages
index.html
Expected individual Surface labels:
fixture-basic-largefixture-tiny-8pxfixture-pointer-events-nonefixture-partial-axfixture-contained-outerfixture-contained-innerfixture-different-parent-afixture-different-parent-b
Expected one grouped Surface:
fixture-layered-group, withlayers=2
Expected absent:
fixture-display-nonefixture-visibility-hiddenfixture-opacity-zerofixture-parent-opacity-zerofixture-hidden-attributefixture-inert-parentfixture-aria-hidden-parentfixture-zero-sizefixture-offscreen-rightfixture-fully-overflow-clipped
fixture-partially-overflow-clipped must remain present because part of it is visible. Its screenshot must contain only the browser's final composited view.
unlabeled.html
This page contains eight Canvas elements but must render seven generic Surface markers because the two coincident layers form one group.
- Every marker uses the stable fallback label
canvas visual surface. - Exactly one marker has
layers=2. - The two contained canvases remain separate markers.
id,class,data-testid, nearby prose, and fallback AX content never become a Surface label.- Blank
aria-labelandtitlevalues behave as no label. - Fallback AX content does not suppress the corresponding Surface.
frames.html
Expected Surface labels:
fixture-same-origin-framefixture-cross-origin-framefixture-nested-frame
The cross-origin frame uses http://localhost:4173 while the parent uses http://127.0.0.1:4173. With Chromium site isolation this exercises the OOPIF path without an external service.
viewport.html
Run with a 900x700 Agent Window.
fixture-partial-viewportis partly visible and must be represented.fixture-below-foldis absent initially.- After scrolling it into view and observing again,
fixture-below-foldmust be represented with a fresh ref.
dynamic.html
Use the normal DOM buttons and re-observe after each action:
- Initial state:
fixture-dynamicabsent. - After Insert canvas: present.
- After Resize to zero: absent.
- After Restore size: present with a fresh ref.
- After Remove canvas: absent.
Invariants
snapshotmust not emit any of these Surface markers.observemust emit only currently visible Canvas surfaces.- Existing DOM/AX controls remain readable alongside Surface markers.
- Missing labels never prevent discovery; naming and discovery are independent.
- A Surface ref allows
screenshot --refand rejects ordinary click/fill/hover/select. - No fixture URL, id, label, or layout constant may appear in production discovery code.