import { WebElement } from '@civitas-cerebrum/element-repository'; import { Verifications } from '../interactions/Verification'; /** * Snapshot of an element's state at a single point in time. * * Passed to predicates in `steps.expect(el, page).satisfy(predicate)` and * `steps.on(el, page).satisfy(predicate)`. All fields are primitives or plain * data — no async methods, no Playwright types. */ export interface ElementSnapshot { readonly text: string; readonly value: string; readonly attributes: Readonly>; readonly visible: boolean; readonly enabled: boolean; readonly count: number; } /** * Surface the matcher tree needs from its host (typically an `ElementAction`). * Decouples matchers from `ElementAction` so the builder can be constructed * from either the fluent entry or the top-level `Steps.expect()` call. */ export interface ExpectContext { readonly elementName: string; readonly pageName: string; readonly timeout: number; readonly conditionalVisible: boolean; readonly visibilityTimeout: number; /** Resolves the element with the current strategy (may be `.first()`-narrowed). */ resolveElement(): Promise; /** Resolves the element with the ALL strategy — no narrowing, used by count matchers. */ resolveAll(): Promise; captureSnapshot(): Promise; /** The shared Verifications facade — the single implementation source for all matcher assertions. */ readonly verify: Verifications; } /** One assertion queued on an `ExpectBuilder`. Executes when the builder is awaited. */ interface QueuedAssertion { /** Ctx captured when enqueued; mutable so `.timeout()` / `.throws()` can retroactively update it. */ ctx: ExpectContext; /** Runs the assertion; may throw on failure. Replaced with a concrete executor at enqueue time. */ run(): Promise; /** Optional custom message that replaces the default failure header. */ messageOverride?: string; } declare abstract class BaseMatcher { protected builder: ExpectBuilder; protected ctx: ExpectContext; protected negated: boolean; constructor(builder: ExpectBuilder, ctx: ExpectContext, negated: boolean); /** * Override the chain-level timeout. Mutates the matcher AND propagates to * the parent builder so subsequent matchers on the same chain see the new * value. Does NOT retroactively patch already-queued assertions — use * `builder.timeout()` (e.g. `.satisfy(pred).timeout(ms)`) for that. */ timeout(ms: number): this; /** Shortcut: build the options object that Verifications methods accept. */ protected opts(): { negated: boolean; timeout: number; }; /** * Build the standard failure message + VerifyOptions for a given verb + expected value. * Accepts the execution-time ctx so trailing `.timeout()` updates flow through. */ protected msgOpts(ctx: ExpectContext, field: string, verb: string, expected: unknown): { negated: boolean; timeout: number; errorMessage: string; }; } declare abstract class StringMatcher extends BaseMatcher { protected abstract fieldLabel(): string; /** Subclasses identify which Verifications family handles their field. */ protected abstract verifyEq(target: WebElement, expected: string, opts: VerifyOpts): Promise; protected abstract verifyContains(target: WebElement, expected: string, opts: VerifyOpts): Promise; protected abstract verifyMatches(target: WebElement, re: RegExp, opts: VerifyOpts): Promise; protected abstract verifyStartsWith(target: WebElement, prefix: string, opts: VerifyOpts): Promise; protected abstract verifyEndsWith(target: WebElement, suffix: string, opts: VerifyOpts): Promise; toBe(expected: string): ExpectBuilder; toContain(expected: string): ExpectBuilder; toMatch(re: RegExp): ExpectBuilder; toStartWith(prefix: string): ExpectBuilder; toEndWith(suffix: string): ExpectBuilder; } /** Short alias for the opts shape Verifications methods accept. */ type VerifyOpts = { negated?: boolean; timeout?: number; errorMessage?: string; }; /** Asserts on the visible text content of the resolved element. Reached via `.text` on `ExpectBuilder` or `ElementAction`. Supports `.toBe`, `.toContain`, `.toMatch`, `.toStartWith`, `.toEndWith`. */ export declare class TextMatcher extends StringMatcher { get not(): TextMatcher; protected fieldLabel(): string; protected verifyEq(t: WebElement, v: string, o: VerifyOpts): Promise; protected verifyContains(t: WebElement, v: string, o: VerifyOpts): Promise; protected verifyMatches(t: WebElement, re: RegExp, o: VerifyOpts): Promise; protected verifyStartsWith(t: WebElement, p: string, o: VerifyOpts): Promise; protected verifyEndsWith(t: WebElement, s: string, o: VerifyOpts): Promise; } /** Asserts on the `value` of an input-like element. Reached via `.value`. Supports `.toBe`, `.toContain`, `.toMatch`, `.toStartWith`, `.toEndWith`. */ export declare class ValueMatcher extends StringMatcher { get not(): ValueMatcher; protected fieldLabel(): string; protected verifyEq(t: WebElement, v: string, o: VerifyOpts): Promise; protected verifyContains(t: WebElement, v: string, o: VerifyOpts): Promise; protected verifyMatches(t: WebElement, re: RegExp, o: VerifyOpts): Promise; protected verifyStartsWith(t: WebElement, p: string, o: VerifyOpts): Promise; protected verifyEndsWith(t: WebElement, s: string, o: VerifyOpts): Promise; } /** Asserts on a specific HTML attribute. Reached via `.attributes.get(name)`. Supports `.toBe`, `.toContain`, `.toMatch`, `.toStartWith`, `.toEndWith`. */ export declare class AttributeMatcher extends StringMatcher { private attrName; constructor(builder: ExpectBuilder, ctx: ExpectContext, attrName: string, negated: boolean); get not(): AttributeMatcher; protected fieldLabel(): string; protected verifyEq(t: WebElement, v: string, o: VerifyOpts): Promise; protected verifyContains(t: WebElement, v: string, o: VerifyOpts): Promise; protected verifyMatches(t: WebElement, re: RegExp, o: VerifyOpts): Promise; protected verifyStartsWith(t: WebElement, p: string, o: VerifyOpts): Promise; protected verifyEndsWith(t: WebElement, s: string, o: VerifyOpts): Promise; } /** Asserts on how many elements match the locator. Reached via `.count`. Always uses the un-narrowed element, so `.first().count.toBe(5)` still counts all matches. Supports `.toBe`, `.toBeGreaterThan`, `.toBeLessThan`, and the `OrEqual` variants. */ export declare class CountMatcher extends BaseMatcher { get not(): CountMatcher; private delegate; toBe(expected: number): ExpectBuilder; toBeGreaterThan(n: number): ExpectBuilder; toBeLessThan(n: number): ExpectBuilder; toBeGreaterThanOrEqual(n: number): ExpectBuilder; toBeLessThanOrEqual(n: number): ExpectBuilder; } type BooleanField = 'visible' | 'enabled'; /** Asserts on a boolean element state (`visible` or `enabled`). Reached via `.visible` / `.enabled`. Supports `.toBe(true|false)`, `.toBeTrue`, `.toBeFalse`. */ export declare class BooleanMatcher extends BaseMatcher { private field; constructor(builder: ExpectBuilder, ctx: ExpectContext, field: BooleanField, negated: boolean); get not(): BooleanMatcher; toBe(expected: boolean): ExpectBuilder; toBeTrue(): ExpectBuilder; toBeFalse(): ExpectBuilder; } /** Asserts on the element's attribute map. Reached via `.attributes`. Use `.get(name)` to drill into a specific attribute or `.toHaveKey(name)` to assert presence. */ export declare class AttributesMatcher extends BaseMatcher { get not(): AttributesMatcher; /** Navigate into a specific attribute. Returns a StringMatcher scoped to that attribute. */ get(name: string): AttributeMatcher; toHaveKey(name: string): ExpectBuilder; } /** * Asserts on the element's HTML — `innerHTML` by default, `outerHTML` when * constructed with `outer: true`. Reached via `.html` / `.outerHtml` on either * `ExpectBuilder` or `ElementAction`. Supports the full `StringMatcher` surface * (`toBe`, `toContain`, `toMatch`, `toStartWith`, `toEndWith`) plus `.not`. * * Useful for security probes (escape verification), template scaffolding * assertions, and any case where text content alone misses tag/attribute * structure. */ export declare class HtmlMatcher extends StringMatcher { private outer; constructor(builder: ExpectBuilder, ctx: ExpectContext, outer: boolean, negated: boolean); get not(): HtmlMatcher; protected fieldLabel(): "outerHtml" | "html"; protected verifyEq(t: WebElement, v: string, o: VerifyOpts): Promise; protected verifyContains(t: WebElement, v: string, o: VerifyOpts): Promise; protected verifyMatches(t: WebElement, re: RegExp, o: VerifyOpts): Promise; protected verifyStartsWith(t: WebElement, p: string, o: VerifyOpts): Promise; protected verifyEndsWith(t: WebElement, s: string, o: VerifyOpts): Promise; } /** Asserts on a computed CSS property value. Reached via `.css(propertyName)`. Supports `.toBe`, `.toContain`, `.toMatch`. */ export declare class CssMatcher extends BaseMatcher { private property; constructor(builder: ExpectBuilder, ctx: ExpectContext, property: string, negated: boolean); get not(): CssMatcher; private label; toBe(expected: string): ExpectBuilder; toContain(expected: string): ExpectBuilder; toMatch(re: RegExp): ExpectBuilder; } /** * Root of the matcher tree and the queue-backed chain builder. * * Every matcher call enqueues an assertion and returns the builder so chains * of multiple verifications are expressed in one await-able expression: * * ```ts * await steps.on('submitBtn', 'CheckoutPage') * .text.toBe('Place Order') * .enabled.toBeTrue() * .attributes.get('data-variant').toBe('primary') * .visible.toBeTrue(); * ``` * * Under the hood each matcher call delegates to `Verifications` — the single * source of truth for assertion implementation (retry mechanics, web-first * behavior, error formatting, negation). The matcher tree is presentation * only. The predicate escape hatch (`satisfy(predicate)`) is the exception — it * uses a snapshot-based poll so user lambdas can access plain data. */ export declare class ExpectBuilder implements PromiseLike { private ctx; private queue; private pendingNot; constructor(ctx: ExpectContext, initialNegated?: boolean); get not(): this; /** * Override the chain-level timeout. Mutates the builder AND retroactively * patches the most-recently queued assertion, so * `.satisfy(pred).timeout(500)` applies 500ms to that predicate even though * `.timeout()` was called after it. Subsequent matchers also pick up the * new value. */ timeout(ms: number): this; /** * Internal: replace the chain-level timeout for subsequent matchers without * touching queued entries. Called by matcher-level `.timeout()` so * `.count.timeout(500)` doesn't retroactively rewrite a prior matcher's * queued entry. */ _setCtxTimeout(ms: number): void; get text(): TextMatcher; get value(): ValueMatcher; get count(): CountMatcher; get visible(): BooleanMatcher; get enabled(): BooleanMatcher; get attributes(): AttributesMatcher; get html(): HtmlMatcher; get outerHtml(): HtmlMatcher; css(property: string): CssMatcher; /** * Predicate escape hatch. Queues a custom predicate assertion on this * builder. Chain further matchers or finish with `.throws(message)` to * override the failure message. * * Named `satisfy` (not `toBe`) to avoid overloading the matcher-tree * equality verb — `.text.toBe('x')` asserts equality on a field, while * `.satisfy(predicate)` asserts a user-supplied boolean expression. */ satisfy(predicate: (el: ElementSnapshot) => boolean): this; /** Replace the failure message of the most recently queued assertion. */ throws(message: string): this; /** * Enqueue an assertion. Matchers call this with the context they captured * at matcher-creation time and a runner that reads `entry.ctx` and * `entry.messageOverride` at run time so later modifications by * `.timeout()` / `.throws()` flow through. */ enqueue(ctx: ExpectContext, run: (entry: QueuedAssertion) => Promise): this; then(onfulfilled?: ((value: void) => TResult1 | PromiseLike) | null | undefined, onrejected?: ((reason: unknown) => TResult2 | PromiseLike) | null | undefined): PromiseLike; private consumeNot; private flush; } export {};