import type { Fixtures, Locator, Page, PlaywrightTestArgs, PlaywrightTestOptions, PlaywrightWorkerArgs } from '@playwright/test'; import { type DeclarationReader } from '@variance-authority/playwright'; import { type RasterStore, type Renderer } from '@variance-authority/raster'; import type { MaterializationOptions, VarianceOptions } from './options.js'; import { type VarianceRun } from './run.js'; import { type VarianceCompletedFixtures } from './completed.js'; import { type SnapshotCase } from './arranged.js'; import { type Observed } from './evidence.js'; import { type ExecutionRecorder, type ExecutionRecording } from './execution.js'; import { type VarianceEventFixtures, type VarianceEventWorkerFixtures } from './events.js'; import type { VarianceDesk, VarianceVantageFixtures, VarianceVantageWorkerFixtures } from './vantage.js'; import { type VarianceWireFixtures } from './wire.js'; import { type VarianceDriveFixtures } from './drive.js'; import { type VarianceRendererFixtures, type VarianceRendererWorkerFixtures } from './renderers.js'; /** * The optional Playwright fixture parts, for a suite that already owns a shared * extension module. * * What makes this cheaper than the CLI's collector is that **the adopter's test * body already is the collector.** `variance run` needs one because it has to * mount a project's components and cannot know how; a Playwright test has * navigated, mounted and waited before this fixture is reached. What is left is * the half this project does own — acquire, render, compare, attribute. * * Two decisions here are load-bearing rather than plumbing. * * **The subject is a `Locator`, never a `Page`.** A subject is a subtree, and * pruning is what makes the comparison affordable and the report assignable * (ADR-0003: 1010 rules parsed, 1 reached the normalizer). Handed a page, pruning * has nothing bounded to prune against and every rule the application loaded is * in the comparison. * * **The renderer paints the acquired document; `locator.screenshot()` is not * used.** The browser is right there and screenshotting it is one line, which is * exactly why the turn is marked. A live-page screenshot has no * {@link Renderer.identityFor} behind it — nothing painted it that can say which * machine, which scale, which font stack — and deriving a store key caller-side * is the drift that interface exists to prevent. The cost is that the subject is * painted twice, once by the application and once from its document; what is * bought is a baseline any machine can reproduce from the document, including one * two networks away. */ export interface VarianceFixtures extends VarianceEventFixtures, VarianceVantageFixtures, VarianceCompletedFixtures, VarianceDriveFixtures, VarianceRendererFixtures { /** * Observe one subtree against its stored baseline — and, on the same name, the * two calls that let a test be looked at while it runs. * * One identifier rather than two, because a test author asking to be seen is * not doing a second kind of thing: `variance(heading)` is what this suite * checks, `variance.snapshot()` and `await variance.observe()` are what it * says while checking it. A second fixture would mean a second thing to * destructure before writing the one line somebody needs at two in the * morning. */ readonly variance: ((locator: Locator, options?: VarianceOptions) => Promise) & VarianceDesk; } export interface VarianceWorkerFixtures extends VarianceEventWorkerFixtures, VarianceWireFixtures, VarianceVantageWorkerFixtures, VarianceRendererWorkerFixtures { /** * Record what each spec executed, for the next run's `--since`. * * Off by default, and useless unless the application this suite drives was * built with `testSelectionProbes()` from `@variance-authority/sense/journal` * — without a collector in the page there is nothing to drain, and the worker * says so on stderr rather than writing an index that would exclude specs it * never watched. */ readonly varianceExecution: boolean | ExecutionRecording; /** The worker's accumulation. Written once, at worker teardown. */ readonly varianceRecorder: ExecutionRecorder | undefined; readonly varianceBundle: string; readonly varianceStore: RasterStore; readonly varianceBaselines: string; /** * Where each baseline goes under `varianceBaselines`, as `baselines.path` * spells it: `{title}/{name}-{engine}` when unset, and * `{dir}/__baselines__/{file}/{name}-{engine}` beside each spec. */ readonly varianceBaselinePath: string | undefined; } export interface VarianceRuntime { readonly page: Page; readonly run: VarianceRun; readonly renderer?: Renderer; readonly store: RasterStore; readonly materialization?: MaterializationOptions; /** * Where the components this page rendered are declared, asked of the engine. * Laid over `options.source` for the artifact; absent when nobody opened one. */ readonly declared?: DeclarationReader; /** * Directory to write the compared images into, for a subject a person will * stop on. Absent means write nothing, which is what a suite that never looks * at pixels should pay. */ readonly evidence?: string; /** * The case this observation is made in, read the moment its document is * captured: a precondition said while the observation is still comparing is * not one the document was taken under. Absent outside a runner's case. */ readonly arranged?: () => SnapshotCase; /** The driver tricks set on this page before it loaded, by id. Absent is none. */ readonly driven?: readonly string[]; } /** * Every fixture this package has, as a value rather than as a `test`. * * A suite extends its own base with it — `base.extend(varianceFixtures)` — which * is the only shape that composes with the extension module a project already * owns. The worker fixtures below are options: a suite names one in `use` when * it supplies its own renderers, store, agent bundle or listening arrangement. */ export declare const varianceFixtures: Fixtures; export declare function observeLocator(runtime: VarianceRuntime, locator: Locator, options?: VarianceOptions): Promise; //# sourceMappingURL=fixture.d.ts.map