import type { DeclaredComponents, SuspenseSettlement } from '@variance-authority/react'; import type { Digest, PageRegion, RawCapture, RenderDocument, SubjectRef, Tier, Viewport } from '@variance-authority/core/format'; /** * The page half, bundled as an IIFE and installed on `window`. * * Same obligation as `packages/storybook-collector/src/page-agent.ts` — acquire a * document, collect a capture, from one mount — with one difference that is most * of why this surface is cheaper than a collector: **the root arrives as an * element, not as a selector.** Playwright resolves a locator and hands the node * into `evaluate`, so nothing here searches for the subject, and the `rootOf` * fallback chain the Storybook collector needs does not exist. * * `acquire` returns a JSON **string**. Playwright would structured-clone the * object happily, and that would hide the property the transport story rests on: * a capture that picked up a `Map`, a DOM handle or a cycle has to fail at this * boundary rather than three hops later. */ /** * Deliberately not a `window.__va`-style short name. The agent shares a global * namespace with whatever application the page already loaded, and a collision * would be discovered as a confusing capture rather than as an error. */ export declare const AGENT = "__variance_authority_playwright_test__"; export declare const ACCESSIBILITY_ROOT_ATTRIBUTE = "data-variance-authority-accessibility-root"; /** What a reading asks of the agent. Its region is the one the page runs in, for the environment key. */ export interface AcquireRequest extends PageRegion { readonly subject: SubjectRef; readonly viewport: Viewport; /** Engine identity for the environment key, e.g. `chromium@131.0.6778.33`. */ readonly engine: string; /** * Fonts this machine is asserted to have, as `family/weight/style/hash`. * * Passed through rather than sniffed in-page: a document can see that `Inter` * is in use and not which Inter, and a substitution moves every rect without * moving a line of code. */ readonly fonts?: readonly string[]; /** * Stabilization tricks to hold the page still with, by id. * * Absent means `COLLECT_RECIPE` — the default is *on*, because a suite that * has to ask for determinism is a suite that discovers it needed it from a * red build. Ids rather than interventions because this value crosses a * `page.evaluate`, and a trick with a `settle` step is a closure that does * not survive the trip; the page holds the same registry and resolves them. */ readonly stabilize?: readonly string[]; /** * The driver tricks the driver applied to this page, by id. * * `no-hover` before each reading, and `reduced-motion` and `freeze-clock` * when the `variance` fixture set them before the test's page loaded. A trick * nobody drove is left out of the recorded recipe. Absent is none. */ readonly driven?: readonly string[]; /** * `'raster'` when this reading is followed by a screenshot of the same live * document, so the recipe's raster-tier holds are worth installing. * * A collection is charged for the rung it stands on, and `tierOfProfile` caps * that at `layout` because pixels are not what a reading produces. In-place * capture is the exception: the screenshot is taken off this very document, * moments after this call, and the caret it would photograph is held by this * call's sheet or by nothing at all. */ readonly tier?: Tier; /** * How long to wait for the subject's Suspense boundaries, in milliseconds. * * A test body that has awaited its own assertions has waited for what it knows * to look for, and a boundary is what it does not: `expect(locator).toBeVisible()` * passes against a skeleton. `0` waits for nothing, which is what a * deliberately-captured loading state sends. */ readonly suspense?: { readonly timeoutMs?: number; }; /** * Read the framework wiring band. Absent means *on*. * * Absent-means-on rather than a plain boolean because a suite reaches this * through `variance(locator)` with no options at all, and a band every run * wants should not be missing from the shortest call anyone writes. */ readonly wiring?: boolean; /** * Read held state as evidence. Absent means *off*, and that asymmetry is the * point rather than an oversight. * * A node carrying a holding suppresses the inert-wrapper collapse, so the same * subtree read with holdings and without hashes to two different structures. * That is a decision about both sides of a comparison at once, which is why * nothing here makes it by default. */ readonly holdings?: boolean; } export interface Acquired { readonly document: RenderDocument; readonly capture: RawCapture; readonly stabilization: { readonly ids: readonly string[]; readonly digest?: Digest; }; /** * Whether the subject had finished arriving, and what was still waiting. * * Reported rather than acted on here. The page can see the boundary; only the * test knows whether this subject is one somebody meant to capture mid-flight. */ readonly suspense: SuspenseSettlement; /** Temporary portal locators used by the Node half, then removed or restored. */ readonly accessibilityPortals: readonly { readonly marker: string; readonly previous?: string; }[]; /** * What changed in the subject since `watch` was called on it, outside the * regions it marks ignored. Absent when nothing was watching. */ readonly mutated?: readonly string[]; } export declare function acquire(root: Element, request: AcquireRequest): Promise; /** * Give focus back to the element the acquisitions since the last call took it * from. * * Not part of `acquire`, because the in-place path photographs the live * document after it, and a focus ring given back before the photograph is in * it. The Node half calls this once the observation is done. */ export declare function refocus(): void; export interface InstalledAgent { readonly acquire: (root: Element, request: AcquireRequest) => Promise; /** {@link refocus}. */ readonly refocus: () => void; /** Record changes to the subject until the next `acquire` or `unwatch`. */ readonly watch: (root: Element) => void; readonly unwatch: () => void; readonly version: string; /** What `createDeclarationReader` reads, keyed on `AGENT` rather than `AGENT_GLOBAL`. */ readonly declared: DeclaredComponents; } /** * Installing is a separate module (`page-agent-entry.ts`), not a side effect * here. This file is imported by the Node half for its types, and a module that * writes to `globalThis` on import would do it in a process that has no page. */ /** * The components this bundle has met, kept for the engine to be asked where * each is declared (`createDeclarationReader` on the Node side). One per * bundle installation: the reader keys its progress on `id`, and a page that * installs the bundle again is a page whose functions are new objects. */ export declare const declared: import("@variance-authority/react").DeclarationRegistry; export declare const AGENT_VERSION = "playwright-test@0"; //# sourceMappingURL=page-agent.d.ts.map