/** * Affordance harvest: enumerate what a route renders that a person could * click. One page.evaluate collects raw candidates; everything downstream of * the browser (selector choice, exclusion, naming, the signature) is pure and * unit-tested without one. * * The selector vocabulary is platform knowledge (what the web calls a * button), never project knowledge; anything project-specific arrives through * config.navigation.include/exclude. */ import type { Page } from "playwright"; import type { Affordance, RouteHarvest } from "./store.js"; /** What the web platform calls an interactive affordance. */ export declare const GENERIC_AFFORDANCES: string; /** What the in-page collector hands back, before any judgement. */ export interface RawAffordance { tag: string; role: string; name: string; id: string | null; testid: string | null; cssPath: string; href: string | null; inForm: boolean; submit: boolean; /** Matched a config exclude entry as a CSS selector, in-page. */ excluded: boolean; box: { x: number; y: number; w: number; h: number; }; } /** Stable selector, most durable form first. */ export declare function chooseSelector(raw: Pick): string; /** * Exclusion has two spellings: a CSS selector (matched in-page, arriving as * raw.excluded) and an accessible-name substring, matched here * case-insensitively so "Sign out" covers "sign out of workspace". */ export declare function normalizeRaw(raws: RawAffordance[], exclude: string[]): Affordance[]; /** * The staleness key: what the route offers, not where it sits. Layout jitter * (box) and DOM churn (selector) must not re-plan; a control appearing, * disappearing, or renaming must. */ export declare function signatureOf(affordances: Affordance[]): string; export declare function harvestRoute(page: Page, opts?: { exclude?: string[]; include?: string[]; }): Promise;