For AI agents: the complete documentation index is available at https://a3s-lab.github.io/Test/en/llms.txt, the full documentation bundle is available at https://a3s-lab.github.io/Test/en/llms-full.txt, and this page is available as Markdown at https://a3s-lab.github.io/Test/en/concepts/page-context.md.

Page Context fields and lifecycle

Page Context is a bounded fact record that Test Kit derives after the browser renders. It adds component ownership, source hints, stable locators, multi-space geometry, and UI-understanding evidence, then binds them to the browser accessibility snapshot as one observation.

Test Kit is an enhancement. Without it, A3S Test can still execute Web actions, assertions, and evidence capture from browser accessibility semantics. Add Page Context when a workflow needs components, geometry, a layout graph, rendered style evidence, or human marking.

Why Page Context exists

No single browser representation answers every question a coding agent must ask.

RepresentationWhat it knowsWhat it loses
Accessibility snapshotRoles, names, and native interaction stateComponent ownership, source, full layout, and visual system
ScreenshotFinal pixels in one viewportDOM identity, live state, stable locators, scroll structure, and source ownership
Framework internalsFramework-specific component implementationStable public contracts across versions and frameworks
Raw DOM serializationStructure and attributesBrowser-computed visibility, occlusion, geometry, layout relations, and revision safety

Page Context is the smallest shared record that fills those gaps without replacing the browser or depending on private framework state. It derives facts after rendering, limits their scope and size, binds them to one monotonic revision, and marks source information as evidence rather than edit authority.

How three browser fact sources work together

browser completes style and layout
        |
        +--> accessibility snapshot   roles, names, native state
        |
        +--> Page Context             components, locators, geometry, facts
        |
        +--> UI understanding         style, layout, clusters, state, motion
                                  |
                                  v
                    one observation and page revision
SourceBest question to answerFact it cannot replace
Accessibility snapshotWhich controls can a user understand and operate?Component source, full layout, and visual style
Page ContextWhich component owns a node, where is it, how is it located?Whether product requirements or model advice are correct
UI understandingHow do current layout, style, state, and motion render?Accessibility semantics, verdicts, and repair authority
A3S Test evidence layerWhat actually appeared after an action?Application-declared boundaries and product facts

UI understanding is an optional record nested inside Page Context. It does not create another accessibility tree and does not infer component types from class names.

What the bridge exposes

The page exposes a non-enumerable, Symbol-addressed a3s.test.page-context/1 bridge. Application code normally mounts the provider and lets the A3S Test browser driver probe and read snapshots. Framework-neutral access remains available for development inspection and custom integration.

import { getPageContextBridge } from '@a3s-lab/testkit';

const bridge = getPageContextBridge();
if (!bridge) throw new Error('Test Kit is not enabled');

const summary = bridge.snapshot({
  detail: 'summary',
  scope: { kind: 'page' },
  limits: { nodes: 300, uiNodes: 120 },
});

const diff = await bridge.waitForDiff({
  sinceRevision: summary.revision,
  timeoutMs: 5_000,
  ui: false,
});
MethodResult or operation
probe()Protocol, SDK version, and capabilities
snapshot(request)A bounded snapshot on the current revision
resolve(nodeId)The live DOM node for a current private ID, within the same-page bridge
waitForChange(revision, ms)Wait for the semantic revision to advance, or return null on timeout
waitForDiff(request)Wait for one newer revision and return its bounded exact delta
subscribe(listener)Subscribe to revision, quality, design-advice, and repair events
dispose()Remove observers, listeners, portals, and private state

The bridge exposes no eval, cookies, browser storage, arbitrary network request, filesystem, or shell access.

Choose a snapshot for the task

Detail levels

detailUse
summaryRegular observation with principal semantics, components, locators, and bounded UI evidence
scopedInspect one node, component, or region without unrelated page context
diffRequires sinceRevision; returns exact invalidation or an explicit reset
forensicRepair verification or design review with the fullest admitted record

Scopes

scope.kindRequired fieldsTypical use
pageNonePage-level observation
nodenodeIdInspect one current snapshot node
componentcomponentIdInspect roots, descendants, and component facts
regionSpace, x, y, width, and heightInspect a viewport or document rectangle

A scope can refer only to private identities on the current revision. A3S Test projects those identities as observation-bound @cN refs. Callers must not persist raw nodeId values.

Snapshot fields

Every response contains protocol, sdkVersion, revision, page, components, nodes, facts, optional ui, optional delta, removedNodeIds, truncated, and nextCursor.

Page fields

PathMeaning
page.idStable page ID declared at integration
page.url and routeCurrent full URL and route
page.readyCurrent readiness from the provider and component boundaries
page.viewportLayout viewport dimensions, DPR, and optional visual viewport
page.documentCurrent document dimensions
page.scrollCurrent document scroll offsets
page.languageCurrent <html lang>
page.themelight, dark, or unknown from an explicit declaration or preference

Component fields

A3STestBoundary can add the following records.

FieldContent
idProject-declared component identity
nameA component name understandable by people and agents
parentIdOptional parent component
sourceOptional file, line, and column hint with no file-edit authority
readyWhether the component has completed its current render
factsExplicit JSON product facts after depth, key, string, and byte admission
boxesOne or more real root rectangles, without inventing one multi-root box

Boundaries are optional. Automatic DOM, open Shadow DOM, semantics, locator, and geometry collection still run without A3STestBoundary.

Node fields

FieldContent
id, parentIdPrivate relationships valid only on the current bridge revision
componentIdExplicit component boundary that owns the node
tagDOM tag
role, nameAccessible role and name
textVisible text after length bounds and redaction
statevisible, disabled, checked, selected, expanded, focused, and related state
locatorsOrdered semantic and CSS candidates
geometryThree coordinate spaces, visibility, occlusion, positioning, and scroll container
computedStylesBounded styles only at admitted detail and budget
sourceMappingOptional ranked source spans from explicit ownership declarations

Locator candidates prefer role and name, label, test ID, placeholder, text, and CSS in that order. Geometry is evidence and a final fallback, not a reason to skip semantic targeting.

Rendered-node source mapping

sourceMapping uses protocol a3s.test.source-mapping/1. It contains up to eight unique candidates sorted by descending confidence.

FieldMeaning
spanLikely original file with optional start and end line and column
generatedSpanDeclared generated location retained beside a direct or Source Map-derived original span
confidenceBounded routing confidence from 0 through 1; it is not a correctness verdict
originframework_adapter, source_map, boundary_hint, or raw generated
relationexact for the registered element or ancestor when an enclosing registered owner supplied the result
registrationIdStable ID of the explicit source, map-backed owner, or boundary declaration

Framework adapters declare ownership through registerSource and optionally registerSourceMap. An A3STestBoundary can provide a coarser source or generated hint. The selected node keeps the same mapping in explicitly submitted repair context, which can save a second browser discovery turn.

Test Kit does not inspect React Fiber, Vue instances, or other framework-private state. It does not discover or fetch maps. Only explicitly registered flat encoded Source Map v3 data is accepted, and sourcesContent is discarded before runtime storage. The Web driver independently rejects unsupported protocols, invalid spans or confidence, unsorted or duplicate candidates, and inconsistent truncation.

Geometry and zoom

Each node with a rendered box can contain three rectangles.

SpaceDerivationUseful for
viewportCSS pixels from getBoundingClientRect()Current viewport hit-testing and screenshot correlation
documentViewport rectangle plus current document scrollComparing a stable page location across scrolling
normalizedRatios against the current visual viewportCorrelating the zoomed image in one observation

Normalized values may be below 0 or above 1 when a box lies outside the visible zoomed region. page.viewport.width and height always describe layout-viewport CSS pixels. DPR and optional visual-viewport offset, size, and scale remain separate, so CSS pixels are never multiplied into device pixels.

Geometry also records visibleRatio, occluded, position, transformed, and the nearest scrollContainerNodeId. Fixed and sticky nodes retain their real positioning. Multi-root components use boxes instead of an invented union rectangle.

UI-understanding record

a3s.test.ui-understanding/1 contains visual facts that the browser has already computed.

BlockEvidence
styleColors, typography, spacing, radii, shadows, z-index, safe root custom properties, and same-origin responsive conditions
layoutFlex, Grid, normal flow, order, client and scroll extents, per-axis overflow and clipping, box model, and graph relations
componentsDeterministic repeated-structure fingerprints from tag, role, stable semantic state, bounded subtree shape, and style summary
stateDiffsNaturally observed hover, focus, focus-visible, checked, expanded, selected, and disabled differences
motionTransitions, CSS and Web Animations, keyframes, document, scroll, view, named timelines, and animation ranges

Layout nodes keep physical margin, border-width, and padding edges separate from boxSizing, writingMode, and direction. Those fields report browser results without inferring logical layout intent.

The UI record has its own observationId. Focus, hover, or a running animation may change computed state without advancing the semantic page revision. Its pageRevision, viewport, and scope must still exactly match the containing Page Context record.

Repeated structures never treat class names as component truth. State collection does not move focus or dispatch events. Cross-origin stylesheet rules remain inaccessible under browser policy and only increment inaccessibleStyleSheets.

Revisions, exact diffs, and public refs

MutationObserver, ResizeObserver, route, viewport, scroll, and relevant form changes advance a monotonic revision. An unchanged page is not polled. A3S Test atomically binds the browser accessibility snapshot to the Test Kit revision; if the page changes while that observation is assembled, the driver rejects the race.

The first-principles rule is smaller than “discard the page after every edit”: discard only evidence that can no longer be proved current. Test Kit 0.6.0 implements that rule with a3s.test.page-context-diff/1.

{
  "delta": {
    "protocol": "a3s.test.page-context-diff/1",
    "fromRevision": 42,
    "toRevision": 43,
    "status": "complete",
    "invalidated": {
      "all": false,
      "page": false,
      "facts": false,
      "ui": true,
      "nodeIds": ["n12"],
      "componentIds": ["checkout-form"]
    }
  }
}
  • complete contains only changed nodes and components, lists every changed or removed private node ID, and marks page or facts independently. A newer revision always invalidates UI evidence because geometry, style, state, and motion belong to that revision.
  • A same-revision complete delta is an empty no-op.
  • reset_required means the exact baseline is no longer retained or complete invalidation metadata cannot fit the byte budget. It invalidates everything, carries no misleading partial IDs, and tells the caller to capture a fresh non-diff baseline.

The runtime keeps at most eight normalized projection shapes and twelve revisions per shape. A projection includes semantic versus forensic detail, normalized scope, and string budget. Diff pages retain one baseline. Their opaque cursor also binds detail, scope, baseline, UI choice, every normalized limit, and the current revision; a mismatch or stale cursor is rejected instead of restarting from page one. timeoutMs for waitForDiff must be an integer from 0 through 300,000. Invalid values and future revisions are rejected rather than clamped.

The Web adapter validates protocol, revision order, UTF-8 ID order, uniqueness, size, changed/removed disjointness, and complete invalidation coverage again in Rust. This lets Core keep the stable locator behind an unaffected @cN while refusing any uncertain target.

RefSourceLifetime and authority
@eNBrowser accessibility snapshotActionable only in its current browser observation; never retained by a Page Context diff
@cNUniquely actionable Page Context nodeBound to one observation and private node ID; may cross revision drift only when a complete delta excludes it
@uNSupplemental UI-understanding nodeRead-only in the current observation and always invalid after revision drift

A3S Test still rejects refs from an older A3S observation. Within the latest observation, a missing delta, reset_required, legacy binding, changed target, removed target, or revision regression clears or rejects the affected @cN before input. This is a narrow targeting optimization, not permission to reuse screenshots, coordinates, or UI evidence.

Budgets, truncation, and pagination

Installation options set ceilings. Each snapshot() request may only lower them.

BudgetDefaultHard ceiling
Page Context nodes5005,000
Bytes per string4 KiB16 KiB
Encoded Page Context1 MiB8 MiB
UI sampled nodes2001,000
UI state candidates2001,000
UI capture duration32 ms100 ms
Encoded UI record256 KiB1 MiB

When a response returns truncated: true, inspect nextCursor and continue with the exact same request and revision. A cursor cannot be reused after the page changes or with different detail, scope, baseline, UI choice, or limits.

The UI record has its own budget.used, truncation flag, and reasons. If UI projection cannot preserve graph integrity within its encoded budget, A3S Test omits that optional record and keeps the outer semantic observation. It never returns broken edges, cyclic containment, or a leaked private identity to fit a budget.

Use snapshot({ ui: false }) when one request does not need UI evidence. Set uiUnderstanding={false} when an installation never needs the projection.

Privacy and host boundaries

The runtime never serializes the following data.

  • Password or hidden input values.
  • Cookies, localStorage, sessionStorage, request headers, or tokens.
  • Arbitrary React, Vue, or Svelte props, state, fibers, closures, or internals.
  • Text covered by a configured redact selector.
  • Cross-origin frame content or stylesheet rules.
  • Full computed styles in summary mode.

Private node IDs live in a WeakMap side table. Test Kit does not write IDs, coordinates, component ownership, or source paths into application DOM attributes. facts accepts only JSON values explicitly returned by the application and applies the same depth, key, string, and encoded-size bounds.

Troubleshooting

SymptomLikely causeAction
getPageContextBridge() is nullProvider disabled, SSR, or already unmountedCall only in the browser and pass enabled={true} explicitly
Component has no sourceNo boundary or no source hintAdd A3STestBoundary; keep source as a hint, not authority
Snapshot expires immediatelyLoading, animation, or hot reload keeps changing the pageWait for page.ready, observe again, and do not reuse refs
Shadow DOM node is missingIts Shadow Root is closedUse an open root or expose necessary context through semantics and a boundary
truncated remains truePage exceeds installation or request budgetsNarrow scope, reduce detail, paginate, or raise the installation ceiling with evidence
UI understanding is absentRequest disabled it, installation disabled it, or admission failedInspect UI configuration and budgets; outer Page Context remains usable
A @cN action is rejectedThe ref is stale or no longer uniquely actionableObserve again and prefer a fresh semantic locator
Diff returns reset_requiredBaseline was evicted or exact invalidation exceeded the byte budgetDiscard old evidence and capture a fresh non-diff snapshot

Continue with Add Web Test Kit for integration or Human review and repair to see how Page Context accompanies an explicitly submitted finding into verification.