/** * Capture Agent — Semantic Target Resolver * * Resolves a SemanticTarget to a concrete Playwright locator. * This is the core mechanism that allows opcodes to work WITHOUT CSS selectors. * * Resolution cascade: * 1. CSS selector (if provided, fast path) * 2. Playwright semantic locators (getByRole, getByText, getByLabel, getByPlaceholder) * 3. Selector alternates * 4. Composite: role + name + near (for disambiguation) * * All resolution happens via Playwright's built-in locator API — no AKTree needed. */ import type { Page, Locator } from 'playwright'; import type { SemanticTarget } from './execution-types.js'; export interface ResolvedTarget { locator: Locator; method: 'selector' | 'role' | 'text' | 'label' | 'placeholder' | 'alternate' | 'composite'; } export interface ResolveOptions { /** Primary CSS selector */ selector?: string; /** Semantic target description */ target?: SemanticTarget; /** Fallback selectors */ selectorAlternates?: string[]; /** Active variant locale used to resolve the target's `*ByLocale` maps */ locale?: string; /** Timeout for visibility check (ms). Default: 3000 */ timeoutMs?: number; } /** * Resolves an element on the page using the best available method. * Returns the first visible locator found, or null if nothing matches. */ export declare function resolveTarget(page: Page, options: ResolveOptions): Promise; /** * Projects a SemanticTarget onto a single locale: each `*ByLocale` map is * collapsed into its base field. Lookup order: exact locale tag → primary * language subtag → base field → first non-empty map value. */ export declare function localizeSemanticTarget(target: SemanticTarget, locale?: string): SemanticTarget; /** * Emits a one-line warning when the active locale has NO entry in any of the * target's `*ByLocale` maps, so the resolver is about to fall back to another * language's string. This is the failure mode behind captures that pass in * every language whose text was captured and fail in the ones that were only * guessed (or never translated): the fallback string doesn't match the * localized UI, and the CLICK/TYPE fails deep in the run instead of surfacing * the real cause. Silent otherwise — no maps or a matching entry logs nothing. */ export declare function warnOnMissingLocaleEntry(target: SemanticTarget, locale?: string): void;