/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License", destination); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { WebDriver, WebElement, Locator } from 'selenium-webdriver'; export interface WaitOptions { /** Maximum time to wait in milliseconds */ timeout?: number; /** Interval between condition checks in milliseconds */ pollInterval?: number; /** Custom error message when timeout is reached */ message?: string; } export interface RetryOptions { /** Maximum number of retry attempts */ maxRetries?: number; /** Delay between retries in milliseconds */ retryDelay?: number; /** Multiplier for exponential backoff (default: 1 = linear) */ backoffMultiplier?: number; /** Function to determine if error is retryable */ isRetryable?: (error: Error) => boolean; } export interface StabilityOptions extends WaitOptions { /** Number of consecutive stable checks required */ stableChecks?: number; /** Interval between stability checks in milliseconds */ stabilityInterval?: number; } /** * Utility class for condition-based waiting operations. * Replaces arbitrary sleep() calls with intelligent waiting strategies. */ export declare class WaitHelper { private readonly driver; private readonly defaultTimeout; private readonly defaultPollInterval; constructor(driver: WebDriver, defaultTimeout?: number, defaultPollInterval?: number); /** * Wait for a condition to become truthy. * @param condition Async function that returns a value - waiting stops when value is truthy * @param options Wait configuration options * @returns The truthy value returned by the condition */ forCondition(condition: () => Promise, options?: WaitOptions): Promise; /** * Wait for an element's attribute to have a specific value. * @param element The WebElement to check * @param attribute Name of the attribute * @param value Expected value * @param options Wait configuration options */ forAttributeValue(element: WebElement, attribute: string, value: string, options?: WaitOptions): Promise; /** * Wait for an element's attribute to contain a specific value. * @param element The WebElement to check * @param attribute Name of the attribute * @param value Value to search for * @param options Wait configuration options */ forAttributeContains(element: WebElement, attribute: string, value: string, options?: WaitOptions): Promise; /** * Wait for an element to become stable (position/size stops changing). * Useful for waiting after animations or dynamic content loading. * * Note: If the element becomes stale (removed from DOM), this method returns * successfully since element removal is a form of "stability". * * @param element The WebElement to monitor * @param options Stability configuration options */ forStable(element: WebElement, options?: StabilityOptions): Promise; /** * Wait for an element to become visible. * @param element The WebElement to check * @param options Wait configuration options */ forVisible(element: WebElement, options?: WaitOptions): Promise; /** * Wait for an element to become invisible. * @param element The WebElement to check * @param options Wait configuration options */ forNotVisible(element: WebElement, options?: WaitOptions): Promise; /** * Wait for an element to become enabled. * @param element The WebElement to check * @param options Wait configuration options */ forEnabled(element: WebElement, options?: WaitOptions): Promise; /** * Wait for the number of elements matching a condition to stabilize. * Useful for lists that are loading items dynamically. * @param getCount Function that returns the current count * @param options Stability configuration options */ forCountStable(getCount: () => Promise, options?: StabilityOptions): Promise; /** * Wait for text content to be present in an element. * @param element The WebElement to check * @param text Expected text (partial match) * @param options Wait configuration options */ forTextPresent(element: WebElement, text: string, options?: WaitOptions): Promise; /** * Wait for an element's class list to contain a specific class. * @param element The WebElement to check * @param className Class name to look for * @param options Wait configuration options */ forClass(element: WebElement, className: string, options?: WaitOptions): Promise; /** * Wait for an element's class list to NOT contain a specific class. * @param element The WebElement to check * @param className Class name that should not be present * @param options Wait configuration options */ forNoClass(element: WebElement, className: string, options?: WaitOptions): Promise; /** * Wait for an element to be clickable (visible AND enabled). * @param element The WebElement to check * @param options Wait configuration options */ forClickable(element: WebElement, options?: WaitOptions): Promise; /** * Wait for text content to match exactly or a regex pattern. * @param element The WebElement to check * @param expected Expected text string or RegExp pattern * @param options Wait configuration options */ forTextContent(element: WebElement, expected: string | RegExp, options?: WaitOptions): Promise; /** * Wait for a specific number of elements to be present. * @param parent Parent element or driver to search within * @param locator Locator for the elements * @param expectedCount Expected number of elements * @param options Wait configuration options */ forElementCount(parent: WebElement | WebDriver, locator: Locator, expectedCount: number, options?: WaitOptions): Promise; /** * Wait for at least one element matching the locator to be present. * @param parent Parent element or driver to search within * @param locator Locator for the element * @param options Wait configuration options * @returns The first matching element */ forElementLocated(parent: WebElement | WebDriver, locator: Locator, options?: WaitOptions): Promise; /** * Wait for no elements matching the locator to be present (element removed). * @param parent Parent element or driver to search within * @param locator Locator for the element * @param options Wait configuration options */ forNoElement(parent: WebElement | WebDriver, locator: Locator, options?: WaitOptions): Promise; /** * Wait for element to be removed from DOM or become stale. * @param element The WebElement to monitor * @param options Wait configuration options */ forElementRemoved(element: WebElement, options?: WaitOptions): Promise; /** * Wait for any of the conditions to be met (OR logic). * @param conditions Array of condition functions * @param options Wait configuration options * @returns Index of the first condition that was met */ forAnyCondition(conditions: Array<() => Promise>, options?: WaitOptions): Promise; /** * Execute a function with automatic retry on failure. * @param fn The function to execute * @param options Retry configuration options * @returns The result of the function */ withRetry(fn: () => Promise, options?: RetryOptions): Promise; /** * Simple sleep helper - use sparingly and prefer condition-based waits. * @param ms Milliseconds to sleep */ sleep(ms: number): Promise; /** * Move the virtual pointer to a quiet spot: the title-bar drag region at the * top-center of the window (the command center is disabled by the framework's * default settings, and unlike the status bar the area has no hover targets). * * A WebDriver session has no OS mouse - the pointer rests wherever the last * interaction left it. VS Code hovers appear while the pointer rests on an * element and are torn down only when it moves away, so parking delivers the * mouseout an open hover is waiting for and disarms pending hover timers. */ parkPointer(): Promise; /** * Click an element, recovering when a transient overlay intercepts the click. * * VS Code renders rich hovers/tooltips as DOM overlays that appear while the * pointer rests on the last click point and never auto-hide. A W3C click * hit-tests the click point BEFORE dispatching any event, so a resting hover * over the target fails every attempt until the pointer actually moves - * waiting alone can never resolve it. On interception this actively parks * the pointer (dismissing pointer-rest overlays), waits for hover teardown * and retries the native click. As a last resort it falls back to a * JS-executor click, which bypasses hit-testing but also mousedown semantics * (Monaco lists select on mousedown) - the fallback is logged so the call * site's true blocker can be root-caused instead of silently papered over. * * @param element the element to click * @param nativeClick override for the native click action (used by * AbstractElement.click() to reach WebElement.prototype.click through its * own override) */ clickThroughInterception(element: WebElement, nativeClick?: () => Promise): Promise; /** * Get the WebDriver instance. */ getDriver(): WebDriver; private rectsEqual; } /** * Create a WaitHelper instance bound to a WebDriver. * Convenience factory function for quick access. */ export declare function createWaitHelper(driver: WebDriver, defaultTimeout?: number): WaitHelper;