@progress/kendo-e2e
Version:
Kendo UI end-to-end test utilities.
945 lines (944 loc) • 38.6 kB
TypeScript
import { By, ThenableWebDriver, WebElement, WebElementCondition } from "selenium-webdriver";
import { WaitCondition } from "./conditions";
import { ExpectApi } from "./expect";
/**
* Core class that provides automatic waiting and simplified interaction with web elements.
*
* **Key Features:**
* - **Automatic waiting** - No need to add manual waits, all methods wait for elements automatically
* - **Smart element location** - Accepts CSS selectors, By locators, or WebElement instances
* - **Fluent API** - Chain methods for readable test code
* - **Built-in retry logic** - Handles timing issues that cause flaky tests
*
* This eliminates the common Selenium pitfalls of StaleElementReferenceException and timing issues.
*
* @example
* ```typescript
* const app = new WebApp(driver);
*
* // Simple element interaction with automatic waiting
* await app.click('#submit-button');
* await app.type('#username', 'testuser');
*
* // Find and interact with elements
* const header = await app.find('.page-header');
* const text = await app.getText(header);
*
* // Wait for conditions
* await app.wait(EC.isVisible('#success-message'));
*
* // Modern expect API with retry logic
* await app.expect('#result').toHaveText('Success');
* await app.expect('.modal').toBeVisible();
* ```
*/
export declare class WebApp {
/** The underlying Selenium WebDriver instance */
driver: ThenableWebDriver;
/**
* Creates a WebApp instance wrapping a Selenium WebDriver.
*
* @param driver - Selenium WebDriver instance to wrap
*/
constructor(driver: ThenableWebDriver);
/**
* Finds a single element with automatic waiting.
*
* **Automatically waits** up to the specified timeout for the element to appear in the DOM.
* This eliminates the need for manual waits and handles dynamic content loading.
*
* @param locator - CSS selector string or Selenium By locator
* @param options - Optional configuration
* @param options.timeout - Maximum time to wait in milliseconds (default: 10000)
* @param options.pollTimeout - Interval between retry attempts in milliseconds (default: 25)
* @returns Promise resolving to the WebElement
* @throws Error if element is not found within the timeout period
*
* @example
* ```typescript
* // Using CSS selector (recommended)
* const button = await app.find('#submit-btn');
* const firstItem = await app.find('.list-item');
*
* // Using Selenium By locator
* const element = await app.find(By.xpath('//div[@data-test="value"]'));
*
* // With custom timeout
* const slowElement = await app.find('#async-content', { timeout: 20000 });
* ```
*/
find(locator: By | string, { timeout, pollTimeout }?: {
timeout?: number;
pollTimeout?: number;
}): Promise<WebElement>;
/**
* Finds all matching elements without waiting.
*
* Returns an empty array if no elements are found. For scenarios where you need to wait
* for at least one element, use {@link findAllWithTimeout} instead.
*
* @param locator - CSS selector string or Selenium By locator
* @returns Promise resolving to array of WebElements (empty if none found)
*
* @example
* ```typescript
* // Get all list items
* const items = await app.findAll('.list-item');
* console.log(`Found ${items.length} items`);
*
* // Iterate over elements
* for (const item of items) {
* const text = await item.getText();
* console.log(text);
* }
*
* // Using By locator
* const buttons = await app.findAll(By.css('button'));
* ```
*/
findAll(locator: By | string): Promise<WebElement[]>;
/**
* Finds all matching elements with automatic waiting for at least one element to appear.
*
* Waits until at least one element matching the locator appears, then returns all matching elements.
* Use this when you expect elements to load dynamically and need to ensure they're present.
*
* @param locator - CSS selector string or Selenium By locator
* @param options - Optional configuration
* @param options.timeout - Maximum time to wait in milliseconds (default: 10000)
* @param options.pollTimeout - Interval between retry attempts in milliseconds (default: 25)
* @returns Promise resolving to array of WebElements
*
* @example
* ```typescript
* // Wait for search results to load
* const results = await app.findAllWithTimeout('.search-result');
*
* // With custom timeout for slow-loading content
* const items = await app.findAllWithTimeout('.async-item', { timeout: 15000 });
* ```
*/
findAllWithTimeout(locator: By | string, { timeout, pollTimeout }?: {
timeout?: number;
pollTimeout?: number;
}): Promise<WebElement[]>;
/**
* Finds a child element within a parent element with automatic waiting.
*
* Useful for scoped element searches within a specific container. Automatically waits
* for both the parent and child elements to appear.
*
* @param rootElement - Parent element (WebElement, By locator, or CSS selector)
* @param locator - Child element selector (By locator or CSS selector)
* @param options - Optional configuration
* @param options.waitForChild - Whether to wait for child to appear (default: true)
* @param options.timeout - Maximum time to wait in milliseconds (default: 10000)
* @param options.pollTimeout - Interval between retry attempts in milliseconds (default: 25)
* @returns Promise resolving to the child WebElement
* @throws Error if child element is not found within the timeout period
*
* @example
* ```typescript
* // Find button within a specific dialog
* const dialog = await app.find('.modal-dialog');
* const closeBtn = await app.findChild(dialog, '.close-button');
*
* // Or find child directly using parent selector
* const button = await app.findChild('.modal-dialog', 'button.submit');
*
* // Without waiting for child (if you know it exists)
* const child = await app.findChild(parent, '.child', { waitForChild: false });
* ```
*/
findChild(rootElement: WebElement | By | string, locator: By | string, { waitForChild, timeout, pollTimeout }?: {
waitForChild?: boolean;
timeout?: number;
pollTimeout?: number;
}): Promise<WebElement>;
/**
* Finds all child elements within a parent element with automatic waiting.
*
* Similar to {@link findChild} but returns all matching children instead of just the first one.
* Waits for at least one child to appear before returning.
*
* @param rootElement - Parent element (WebElement, By locator, or CSS selector)
* @param locator - Child elements selector (By locator or CSS selector)
* @param options - Optional configuration
* @param options.waitForChild - Whether to wait for at least one child to appear (default: true)
* @param options.timeout - Maximum time to wait in milliseconds (default: 10000)
* @param options.pollTimeout - Interval between retry attempts in milliseconds (default: 25)
* @returns Promise resolving to array of child WebElements
*
* @example
* ```typescript
* // Find all rows in a specific table
* const table = await app.find('#data-table');
* const rows = await app.findChildren(table, 'tr');
*
* // Or find children directly using parent selector
* const items = await app.findChildren('.dropdown-menu', 'li');
*
* // Process all children
* for (const row of rows) {
* const text = await row.getText();
* console.log(text);
* }
* ```
*/
findChildren(rootElement: WebElement | By | string, locator: By | string, { waitForChild, timeout, pollTimeout }?: {
waitForChild?: boolean;
timeout?: number;
pollTimeout?: number;
}): Promise<WebElement[]>;
/**
* Clicks an element with automatic waiting and retry logic.
*
* **Handles common click issues automatically:**
* - Waits for element to appear in DOM
* - Waits for element to be visible
* - Waits for element to be enabled
* - Retries if click fails initially
*
* This eliminates flaky tests caused by timing issues.
*
* @param element - Element to click (WebElement, By locator, or CSS selector)
* @param options - Optional configuration
* @param options.timeout - Maximum time to wait in milliseconds (default: 10000)
* @param options.pollTimeout - Interval between retry attempts in milliseconds (default: 25)
* @returns Promise that resolves when click succeeds
* @throws Error if element cannot be clicked within timeout
*
* @example
* ```typescript
* // Simple click using CSS selector
* await app.click('#submit-button');
*
* // Click with custom timeout
* await app.click('.slow-loading-btn', { timeout: 15000 });
*
* // Click using By locator
* await app.click(By.xpath('//button[text()="Submit"]'));
*
* // Click a previously found element
* const button = await app.find('#my-button');
* await app.click(button);
* ```
*/
click(element: WebElement | By | string, { timeout, pollTimeout }?: {
timeout?: number;
pollTimeout?: number;
}): Promise<void>;
/**
* Moves the mouse cursor over an element (hover action).
*
* Useful for testing hover states, tooltips, dropdown menus, and other hover-triggered UI.
* Automatically waits for the element to be present before hovering.
*
* @param element - Element to hover over (WebElement, By locator, or CSS selector)
* @param options - Optional configuration
* @param options.timeout - Maximum time to wait for element in milliseconds (default: 10000)
* @param options.pollTimeout - Interval between retry attempts in milliseconds (default: 25)
* @returns Promise that resolves when hover completes
*
* @example
* ```typescript
* // Hover to reveal dropdown menu
* await app.hover('.menu-item');
* await app.click('.submenu-option');
*
* // Hover to show tooltip
* await app.hover('#info-icon');
* const tooltip = await app.find('.tooltip');
* const text = await app.getText(tooltip);
*
* // Hover on element found with By locator
* await app.hover(By.css('[data-test="hover-target"]'));
* ```
*/
hover(element: WebElement | By | string, { timeout, pollTimeout }?: {
timeout?: number;
pollTimeout?: number;
}): Promise<void>;
/**
* Sets focus on an element programmatically.
*
* Directly focuses the element using JavaScript, which is more reliable than clicking for focus.
* Useful for testing keyboard interactions, input fields, and focus-dependent behaviors.
*
* @param element - Element to focus (WebElement, By locator, or CSS selector)
* @param options - Optional configuration
* @param options.timeout - Maximum time to wait for element in milliseconds (default: 10000)
* @param options.pollTimeout - Interval between retry attempts in milliseconds (default: 25)
* @returns Promise that resolves when focus is set
*
* @example
* ```typescript
* // Focus an input field
* await app.focus('#username');
* await app.sendKey(Key.CONTROL, 'a'); // Select all
*
* // Focus before typing
* await app.focus('#search-box');
* await app.type('#search-box', 'test query');
*
* // Test focus-dependent behavior
* await app.focus('#email');
* await app.expect('.validation-hint').toBeVisible();
* ```
*/
focus(element: WebElement | By | string, { timeout, pollTimeout }?: {
timeout?: number;
pollTimeout?: number;
}): Promise<void>;
/**
* Performs a right-click (context menu click) on an element.
*
* Opens the context menu for the element, allowing you to test right-click menus and actions.
*
* @param element - Element to right-click (WebElement, By locator, or CSS selector)
* @param options - Optional configuration
* @param options.timeout - Maximum time to wait for element in milliseconds (default: 10000)
* @param options.pollTimeout - Interval between retry attempts in milliseconds (default: 25)
* @returns Promise that resolves when right-click completes
*
* @example
* ```typescript
* // Open context menu and select option
* await app.contextClick('.file-item');
* await app.click('.context-menu-delete');
*
* // Right-click on canvas element
* await app.contextClick('#drawing-canvas');
* await app.expect('.context-menu').toBeVisible();
* ```
*/
contextClick(element: WebElement | By | string, { timeout, pollTimeout }?: {
timeout?: number;
pollTimeout?: number;
}): Promise<void>;
/**
* Performs a double-click on an element.
*
* Useful for testing double-click interactions like selecting text, opening files, or
* triggering double-click-specific behaviors in your application.
*
* @param element - Element to double-click (WebElement, By locator, or CSS selector)
* @param options - Optional configuration
* @param options.timeout - Maximum time to wait for element in milliseconds (default: 10000)
* @param options.pollTimeout - Interval between retry attempts in milliseconds (default: 25)
* @returns Promise that resolves when double-click completes
*
* @example
* ```typescript
* // Double-click to open file
* await app.doubleClick('.file-icon');
*
* // Double-click to select word
* await app.doubleClick('.text-content');
*
* // Double-click with custom wait
* await app.doubleClick('#expandable-item', { timeout: 5000 });
* ```
*/
doubleClick(element: WebElement | By | string, { timeout, pollTimeout }?: {
timeout?: number;
pollTimeout?: number;
}): Promise<void>;
/**
* Waits for an element to stop animating, then clicks it.
*
* Perfect for clicking elements that are animating into view (slides, fades, etc.).
* Prevents clicks during animation which can cause missed clicks or wrong targets.
*
* @param element - Element to wait for and click (WebElement, By locator, or CSS selector)
* @param options - Optional configuration
* @param options.timeout - Maximum time to wait in milliseconds (default: 10000)
* @param options.pollTimeout - Interval between animation checks in milliseconds (default: 50)
* @returns Promise that resolves when element is stable and clicked
*
* @example
* ```typescript
* // Click button that slides into view
* await app.waitForAnimationAndClick('.animated-button');
*
* // Click element in animated modal
* await app.waitForAnimationAndClick('.modal .submit-btn', { timeout: 5000 });
* ```
*/
waitForAnimationAndClick(element: WebElement | By | string, { timeout, pollTimeout }?: {
timeout?: number;
pollTimeout?: number;
}): Promise<void>;
/**
* Scrolls element into view and then clicks it.
*
* Handles elements that are not initially in viewport. Scrolls the element to the center
* of the viewport before clicking, ensuring reliable clicks on off-screen elements.
*
* @param element - Element to scroll to and click (WebElement, By locator, or CSS selector)
* @param options - Optional configuration
* @param options.timeout - Maximum time to wait for element in milliseconds (default: 10000)
* @param options.pollTimeout - Interval between retry attempts in milliseconds (default: 25)
* @returns Promise that resolves when element is scrolled into view and clicked
*
* @example
* ```typescript
* // Click element at bottom of page
* await app.scrollAndClick('#footer-button');
*
* // Scroll and click in long form
* await app.scrollAndClick('.form-submit', { timeout: 5000 });
*
* // Click element in scrollable container
* await app.scrollAndClick('.list-item:last-child');
* ```
*/
scrollAndClick(element: WebElement | By | string, { timeout, pollTimeout }?: {
timeout?: number;
pollTimeout?: number;
}): Promise<void>;
/**
* Scrolls an element into the viewport without clicking it.
*
* Useful when you need an element visible for screenshots, visibility checks, or
* before performing other actions. Centers the element in the viewport.
*
* @param locator - Element to scroll to (By locator or CSS selector)
* @param options - Optional configuration
* @param options.timeout - Maximum time to wait for element in milliseconds (default: 10000)
* @param options.pollTimeout - Interval between retry attempts in milliseconds (default: 25)
* @returns Promise that resolves when element is scrolled into view
*
* @example
* ```typescript
* // Scroll to element for screenshot
* await app.scrollIntoView('#chart');
* const screenshot = await app.getScreenshot();
*
* // Scroll before checking visibility
* await app.scrollIntoView('.lazy-load-content');
* await app.expect('.lazy-load-content').toBeVisible();
* ```
*/
scrollIntoView(locator: By | string, { timeout, pollTimeout }?: {
timeout?: number;
pollTimeout?: number;
}): Promise<void>;
/**
* Drags a source element and drops it onto a target element.
*
* Performs a complete drag-and-drop operation, useful for testing sortable lists,
* drag-and-drop file uploads, kanban boards, and similar interactions.
*
* @param source - Element to drag (WebElement or By locator)
* @param target - Element to drop onto (WebElement or By locator)
* @returns Promise that resolves when drag-and-drop completes
*
* @example
* ```typescript
* // Drag list item to reorder
* await app.dragTo(
* By.css('.list-item:nth-child(1)'),
* By.css('.list-item:nth-child(3)')
* );
*
* // Drag file to upload area
* const file = await app.find('.file-icon');
* const dropzone = await app.find('.upload-dropzone');
* await app.dragTo(file, dropzone);
*
* // Drag card between columns (kanban)
* await app.dragTo('#card-1', '#column-done');
* ```
*/
dragTo(source: WebElement | By, target: WebElement | By): Promise<void>;
/**
* Drags an element by a specified pixel offset.
*
* Moves an element by dragging it a specific number of pixels in X and Y directions.
* Useful for testing sliders, resizable panels, draggable windows, and custom drag interactions.
*
* @param element - Element to drag (WebElement, By locator, or CSS selector)
* @param offsetX - Horizontal offset in pixels (positive = right, negative = left)
* @param offsetY - Vertical offset in pixels (positive = down, negative = up)
* @returns Promise that resolves when drag completes
*
* @example
* ```typescript
* // Drag slider to the right
* await app.dragByOffset('.slider-handle', 100, 0);
*
* // Drag element down and left
* await app.dragByOffset('.draggable-box', -50, 75);
*
* // Resize panel by dragging splitter
* await app.dragByOffset('.splitter', 0, -100);
* ```
*/
dragByOffset(element: WebElement | By | string, offsetX: number, offsetY: number): Promise<void>;
/**
* Types text into an input element.
*
* Automatically finds the element, optionally clears existing content, types the text,
* and can optionally press Enter after typing. Perfect for form filling and text input.
*
* @param element - Input element to type into (WebElement, By locator, or CSS selector)
* @param text - Text to type
* @param options - Optional configuration
* @param options.clear - Whether to clear existing content first (default: true)
* @param options.sendEnter - Whether to press Enter after typing (default: false)
* @returns Promise that resolves when typing completes
*
* @example
* ```typescript
* // Type into input (clears existing text by default)
* await app.type('#username', 'testuser');
*
* // Type and submit with Enter
* await app.type('#search', 'search query', { sendEnter: true });
*
* // Type without clearing existing text
* await app.type('#notes', 'additional text', { clear: false });
*
* // Fill form fields
* await app.type('#email', 'user@example.com');
* await app.type('#password', 'secret123');
* await app.click('#login-button');
* ```
*/
type(element: WebElement | By | string, text: string, { clear, sendEnter }?: {
clear?: boolean;
sendEnter?: boolean;
}): Promise<void>;
/**
* Sends a single keyboard key press.
*
* Simulates pressing a keyboard key. Use Selenium's Key constants for special keys.
*
* @param key - Key to press (use Key.ENTER, Key.TAB, Key.ESCAPE, etc.)
* @returns Promise that resolves when key press completes
*
* @example
* ```typescript
* import { Key } from '@kendo/kendo-e2e';
*
* // Press Enter
* await app.sendKey(Key.ENTER);
*
* // Press Tab to move focus
* await app.sendKey(Key.TAB);
*
* // Press Escape to close modal
* await app.sendKey(Key.ESCAPE);
*
* // Press Arrow Down
* await app.sendKey(Key.ARROW_DOWN);
* ```
*/
sendKey(key: string): Promise<void>;
/**
* Sends a two-key combination (e.g., Ctrl+C).
*
* Convenience method for common two-key combinations. For more keys, use {@link sendKeysCombination}.
*
* @param key1 - First key (typically a modifier like Key.CONTROL)
* @param key2 - Second key
* @returns Promise that resolves when key combination completes
*
* @example
* ```typescript
* import { Key } from '@kendo/kendo-e2e';
*
* // Copy text
* await app.sendKeyCombination(Key.CONTROL, 'c');
*
* // Paste text
* await app.sendKeyCombination(Key.CONTROL, 'v');
*
* // Open browser dev tools (F12 might not work in some contexts)
* await app.sendKeyCombination(Key.CONTROL, Key.SHIFT);
* ```
*/
sendKeyCombination(key1: string, key2: string): Promise<void>;
/**
* Sends a combination of multiple keyboard keys simultaneously.
*
* Holds down all keys in order, then releases them in reverse order, simulating
* a realistic key combination press.
*
* @param keys - Array of keys to press together
* @returns Promise that resolves when key combination completes
*
* @example
* ```typescript
* import { Key } from '@kendo/kendo-e2e';
*
* // Ctrl+Shift+Delete
* await app.sendKeysCombination([Key.CONTROL, Key.SHIFT, Key.DELETE]);
*
* // Select all (Ctrl+A)
* await app.sendKeysCombination([Key.CONTROL, 'a']);
*
* // Custom three-key combo
* await app.sendKeysCombination([Key.ALT, Key.SHIFT, 'F']);
* ```
*/
sendKeysCombination(keys: string[]): Promise<void>;
/**
* Sends Ctrl+key on Windows/Linux or Cmd+key on macOS automatically.
*
* Cross-platform helper that uses the appropriate modifier key for the current OS.
* Perfect for common shortcuts like copy, paste, save, etc.
*
* @param key - Key to combine with Ctrl/Cmd
* @returns Promise that resolves when key combination completes
*
* @example
* ```typescript
* // Copy (Ctrl+C on Windows/Linux, Cmd+C on macOS)
* await app.sendControlKeyCombination('c');
*
* // Paste (cross-platform)
* await app.sendControlKeyCombination('v');
*
* // Select all (cross-platform)
* await app.sendControlKeyCombination('a');
*
* // Save (cross-platform)
* await app.sendControlKeyCombination('s');
* ```
*/
sendControlKeyCombination(key: string): Promise<void>;
isVisible(element: WebElement | By | string, { timeout, pollTimeout }?: {
timeout?: number;
pollTimeout?: number;
}): Promise<boolean>;
isNotVisible(element: WebElement | By | string, { timeout, pollTimeout }?: {
timeout?: number;
pollTimeout?: number;
}): Promise<boolean>;
isInViewport(element: WebElement | By | string, { timeout, pollTimeout }?: {
timeout?: number;
pollTimeout?: number;
}): Promise<boolean>;
isNotInViewport(element: WebElement | By | string, { timeout, pollTimeout }?: {
timeout?: number;
pollTimeout?: number;
}): Promise<boolean>;
hasFocus(element: WebElement | By | string): Promise<boolean>;
hasNoFocus(element: WebElement | By | string): Promise<boolean>;
hasText(element: WebElement | By | string, text: string): Promise<boolean>;
hasValue(element: WebElement | By | string, value: string): Promise<boolean>;
hasAttribute(element: WebElement | By | string, attribute: string, value: string, exactMatch?: boolean): Promise<boolean>;
hasClass(element: WebElement | By | string, value: string, exactMatch?: boolean): Promise<boolean>;
sleep(milliseconds: number): Promise<void>;
/**
* Waits for a condition to become true.
*
* Core waiting method that polls a condition until it returns true or timeout is reached.
* Use predefined conditions from {@link EC} class or create custom conditions.
*
* @param condition - Condition function or WebElementCondition to wait for
* @param options - Optional configuration
* @param options.timeout - Maximum time to wait in milliseconds (default: 10000)
* @param options.message - Custom error message if condition times out (default: 'Failed to satisfy condition.')
* @param options.pollTimeout - Interval between condition checks in milliseconds (default: 25)
* @returns Promise that resolves when condition is met
* @throws Error with the specified message if condition is not met within timeout
*
* @example
* ```typescript
* // Wait for element to be visible
* await app.wait(EC.isVisible('#modal'));
*
* // Wait with custom timeout and message
* await app.wait(EC.hasText(element, 'Success'), {
* timeout: 15000,
* message: 'Success message did not appear'
* });
*
* // Wait for custom condition
* await app.wait(async () => {
* const count = await app.findAll('.item');
* return count.length > 5;
* }, { message: 'Less than 5 items found' });
* ```
*/
wait(condition: WebElementCondition | WaitCondition, { timeout, message, pollTimeout }?: {
timeout?: number;
message?: string;
pollTimeout?: number;
}): Promise<void>;
/**
* Waits for a condition without throwing an error if it fails.
*
* Returns true if condition is met, false if timeout is reached. Perfect for conditional
* logic in tests where you want to check if something happened without failing the test.
*
* @param condition - Condition function or WebElementCondition to wait for
* @param options - Optional configuration
* @param options.timeout - Maximum time to wait in milliseconds (default: 10000)
* @param options.pollTimeout - Interval between condition checks in milliseconds (default: 25)
* @returns Promise resolving to true if condition met, false if timeout reached
*
* @example
* ```typescript
* // Check if element appears (don't fail if it doesn't)
* const appeared = await app.waitSafely(EC.isVisible('.optional-message'));
* if (appeared) {
* console.log('Message was shown');
* }
*
* // Conditional test flow
* const hasModal = await app.waitSafely(EC.isVisible('.modal'), { timeout: 3000 });
* if (hasModal) {
* await app.click('.modal .close');
* }
*
* // Check if element has specific text
* const hasText = await app.waitSafely(EC.hasText('#status', 'Complete'));
* ```
*/
waitSafely(condition: WebElementCondition | WaitCondition, { timeout, pollTimeout }?: {
timeout?: number;
pollTimeout?: number;
}): Promise<boolean>;
/**
* Waits for an element to stop moving or resizing (animation to complete).
*
* Monitors element position and size, waiting until they remain stable for a poll interval.
* Essential for reliable interaction with animated elements.
*
* @param element - Element to monitor (WebElement, By locator, or CSS selector)
* @param options - Optional configuration
* @param options.timeout - Maximum time to wait in milliseconds (default: 10000)
* @param options.pollTimeout - Interval between stability checks in milliseconds (default: 50)
* @returns Promise that resolves when element is stable
* @throws Error if element doesn't stabilize within timeout
*
* @example
* ```typescript
* // Wait for sliding panel to stop
* await app.waitForAnimation('.slide-panel');
* await app.click('.slide-panel button');
*
* // Wait for expanding accordion
* await app.click('.accordion-header');
* await app.waitForAnimation('.accordion-content');
*
* // Use before taking screenshots of animated content
* await app.waitForAnimation('.chart');
* const screenshot = await app.getScreenshot();
* ```
*/
waitForAnimation(element: WebElement | By | string, { timeout, pollTimeout }?: {
timeout?: number;
pollTimeout?: number;
}): Promise<void>;
getScreenshot(): Promise<string>;
/**
* @deprecated Use executeScript with proper types instead
* @internal
*/
executeScript(script: string | ((...args: unknown[]) => unknown)): Promise<unknown>;
/**
* Gets the visible text content of an element.
*
* Returns the text that would be visible to a user, excluding hidden elements.
* Automatically finds the element if a locator is provided.
*
* @param element - Element to get text from (WebElement, By locator, or CSS selector)
* @returns Promise resolving to the element's text, or undefined if element has no text
*
* @example
* ```typescript
* // Get button text
* const buttonText = await app.getText('#submit-btn');
* console.log(buttonText); // 'Submit Form'
*
* // Get paragraph content
* const message = await app.getText('.success-message');
*
* // Get text from found element
* const element = await app.find('.label');
* const text = await app.getText(element);
* ```
*/
getText(element: WebElement | By | string): Promise<string>;
/**
* Gets the value of an HTML attribute from an element.
*
* Retrieves attribute values like 'href', 'src', 'disabled', 'data-*', etc.
* Returns null if the attribute doesn't exist.
*
* @param element - Element to get attribute from (WebElement, By locator, or CSS selector)
* @param attribute - Name of the attribute to retrieve
* @returns Promise resolving to the attribute value or null
*
* @example
* ```typescript
* // Get link href
* const url = await app.getAttribute('a.download', 'href');
*
* // Check if button is disabled
* const isDisabled = await app.getAttribute('#submit', 'disabled');
*
* // Get data attribute
* const userId = await app.getAttribute('.user', 'data-user-id');
*
* // Get input value
* const value = await app.getAttribute('#email', 'value');
* ```
*/
getAttribute(element: WebElement | By | string, attribute: string): Promise<string>;
/**
* Gets a JavaScript property value from an element.
*
* Different from {@link getAttribute} - this gets DOM properties (like 'value', 'checked')
* which may differ from HTML attributes. Properties reflect the current state.
*
* @param element - Element to get property from (WebElement, By locator, or CSS selector)
* @param property - Name of the property to retrieve
* @returns Promise resolving to the property value
*
* @example
* ```typescript
* // Get checkbox checked state (property, not attribute)
* const isChecked = await app.getProperty('#agree', 'checked');
*
* // Get input value (current value, not initial)
* const currentValue = await app.getProperty('#username', 'value');
*
* // Get element's innerHTML
* const html = await app.getProperty('.container', 'innerHTML');
*
* // Get computed style property
* const display = await app.getProperty('#element', 'style');
* ```
*/
getProperty(element: WebElement | By | string, property: string): Promise<string>;
/**
* Gets the text color (color CSS property) of an element as hex value.
*
* Converts the color from any format (rgb, rgba, named) to hex format (#RRGGBB).
* Useful for visual testing and theme verification.
*
* @param element - Element to get color from (WebElement, By locator, or CSS selector)
* @returns Promise resolving to hex color string (e.g., '#ff0000')
*
* @example
* ```typescript
* // Check error message color
* const errorColor = await app.getColor('.error-message');
* expect(errorColor).toBe('#ff0000'); // red
*
* // Verify link color
* const linkColor = await app.getColor('a.primary');
*
* // Check themed text color
* const textColor = await app.getColor('.themed-text');
* ```
*/
getColor(element: WebElement | By | string): Promise<string>;
/**
* Gets the background color (background-color CSS property) of an element as hex value.
*
* Converts the background color from any format to hex format (#RRGGBB).
* Useful for verifying button states, highlights, and theme colors.
*
* @param element - Element to get background color from (WebElement, By locator, or CSS selector)
* @returns Promise resolving to hex color string (e.g., '#ffffff')
*
* @example
* ```typescript
* // Check button background
* const btnBg = await app.getBackgroundColor('#primary-btn');
* expect(btnBg).toBe('#007bff'); // bootstrap primary
*
* // Verify selected item highlight
* const selectedBg = await app.getBackgroundColor('.selected');
*
* // Check alert background color
* const alertBg = await app.getBackgroundColor('.alert-warning');
* ```
*/
getBackgroundColor(element: WebElement | By | string): Promise<string>;
/**
* Hides the text cursor/caret for cleaner screenshots.
*
* When called without arguments, hides the cursor globally for all input/textarea elements.
* When called with an element, hides the cursor only for that specific element.
* Global hiding persists until page reload.
*
* @param element - Optional specific element to hide cursor for (WebElement, By locator, or CSS selector)
* @param options - Optional configuration
* @param options.timeout - Maximum time to wait for element in milliseconds (default: 10000)
* @param options.pollTimeout - Interval between retry attempts in milliseconds (default: 25)
* @returns Promise that resolves when cursor is hidden
*
* @example
* ```typescript
* // Hide cursor globally before screenshot
* await app.hideCursor();
* const screenshot = await app.getScreenshot();
*
* // Hide cursor for specific input
* await app.focus('#username');
* await app.hideCursor('#username');
* const inputScreenshot = await app.getScreenshot();
*
* // Hide cursor in focused field for visual test
* await app.type('#search', 'test');
* await app.hideCursor('#search');
* ```
*
* @see For more details, see [hideCursor documentation](../../docs/hideCursor.md)
*/
hideCursor(element?: WebElement | By | string, { timeout, pollTimeout }?: {
timeout?: number;
pollTimeout?: number;
}): Promise<void>;
/**
* Creates an expectation API for the specified element selector.
* This provides a fluent interface for asserting element states with automatic retry logic.
* The expect API will continuously retry finding the element and checking the condition
* until it passes or the timeout is reached (default: 3000ms).
*
* @param selector - CSS selector string or By locator to identify the element
* @returns ExpectApi object with assertion methods
*
* @example
* ```typescript
* // Assert element has specific text (default 3s timeout)
* await app.expect('#result').toHaveText('Welcome user');
*
* // Assert element is visible
* await app.expect('.modal').toBeVisible();
*
* // Assert element is not visible
* await app.expect('.spinner').not.toBeVisible();
*
* // Assert with custom timeout and message
* await app.expect('#message').toHaveText('Success', {
* timeout: 5000,
* message: 'Failed to load results.'
* });
*
* // Assert using regex pattern
* await app.expect('#status').toHaveText(/completed|success/i, { timeout: 10000 });
*
* // Assert element has value
* await app.expect('#input').toHaveValue('expected value', { timeout: 2000 });
*
* // Assert element has focus
* await app.expect('#activeInput').toHaveFocus();
*
* // Assert element has attribute
* await app.expect('#btn').toHaveAttribute('disabled', 'true');
*
* // Assert element has class (partial match)
* await app.expect('#div').toHaveClass('active', { exactMatch: false });
* ```
*/
expect(selector: string | By): ExpectApi;
}