@progress/kendo-e2e
Version:
Kendo UI end-to-end test utilities.
250 lines (249 loc) • 8.91 kB
TypeScript
import { By, ThenableWebDriver } from "selenium-webdriver";
/**
* Configuration options for expect assertions.
*/
export interface ExpectOptions {
/** Maximum time to wait for condition in milliseconds (default: 3000) */
timeout?: number;
/** Custom error message to show if assertion fails */
message?: string;
/** Interval between retry attempts in milliseconds (default: 25) */
pollInterval?: number;
}
/**
* Configuration options for attribute/class expect assertions.
*/
export interface ExpectAttributeOptions extends ExpectOptions {
/** If true, requires exact match; if false, allows partial match (default: true) */
exactMatch?: boolean;
}
/**
* Modern, fluent API for asserting element states with automatic retry logic.
*
* Provides a Playwright-style expect API with built-in waiting and retry.
* All assertions automatically retry until they pass or timeout is reached,
* eliminating the need for manual waits.
*
* **Key features:**
* - Automatic retry with configurable timeout (default 3s)
* - Clear error messages showing what was expected vs actual
* - Support for regex patterns in text matching
* - Negative assertions via `.not` property
*
* @example
* ```typescript
* // Basic assertions
* await app.expect('#title').toHaveText('Welcome');
* await app.expect('.modal').toBeVisible();
* await app.expect('#input').toHaveValue('test');
*
* // With timeout
* await app.expect('#message').toHaveText('Success', { timeout: 5000 });
*
* // Regex matching
* await app.expect('#status').toHaveText(/complete|success/i);
*
* // Negative assertions
* await app.expect('.spinner').not.toBeVisible();
* await app.expect('#input').not.toHaveFocus();
*
* // Attribute checks
* await app.expect('#submit').toHaveAttribute('disabled', 'true');
* await app.expect('.item').toHaveClass('selected');
* ```
*/
export interface ExpectApi {
/**
* Asserts that element has specific text content.
*
* Continuously retries until text matches or timeout is reached.
* Supports both exact string match and regex patterns.
* Text is trimmed before comparison.
*
* @param text - Expected text (string for exact match or RegExp for pattern match)
* @param opts - Optional configuration (timeout, message, pollInterval)
* @throws Error if element doesn't have expected text within timeout
*
* @example
* ```typescript
* // Exact match
* await app.expect('#message').toHaveText('Operation completed');
*
* // Regex pattern
* await app.expect('#status').toHaveText(/success|complete/i);
*
* // With custom timeout
* await app.expect('#slow-load').toHaveText('Loaded', { timeout: 10000 });
* ```
*/
toHaveText(text: string | RegExp, opts?: ExpectOptions): Promise<void>;
/**
* Asserts that element is visible on the page.
*
* Element must be present in DOM and have CSS properties that make it visible.
* Continuously retries until visible or timeout is reached.
*
* @param opts - Optional configuration (timeout, message, pollInterval)
* @throws Error if element is not visible within timeout
*
* @example
* ```typescript
* // Wait for modal to appear
* await app.expect('.modal').toBeVisible();
*
* // With custom timeout and message
* await app.expect('#notification').toBeVisible({
* timeout: 5000,
* message: 'Notification did not appear'
* });
* ```
*/
toBeVisible(opts?: ExpectOptions): Promise<void>;
/**
* Asserts that input element has specific value.
*
* Checks the 'value' attribute of form inputs. Perfect for validating
* input fields, textareas, and other form elements.
*
* @param value - Expected value string
* @param opts - Optional configuration (timeout, message, pollInterval)
* @throws Error if element doesn't have expected value within timeout
*
* @example
* ```typescript
* // Check input value after typing
* await app.type('#username', 'testuser');
* await app.expect('#username').toHaveValue('testuser');
*
* // Verify auto-filled value
* await app.expect('#email').toHaveValue('user@example.com');
* ```
*/
toHaveValue(value: string, opts?: ExpectOptions): Promise<void>;
/**
* Asserts that element has keyboard focus.
*
* Verifies that the element is the currently active (focused) element.
* Useful for testing keyboard navigation and accessibility.
*
* @param opts - Optional configuration (timeout, message, pollInterval)
* @throws Error if element doesn't receive focus within timeout
*
* @example
* ```typescript
* // Verify focus after click
* await app.click('#search');
* await app.expect('#search').toHaveFocus();
*
* // Check focus after Tab navigation
* await app.sendKey(Key.TAB);
* await app.expect('#next-field').toHaveFocus();
* ```
*/
toHaveFocus(opts?: ExpectOptions): Promise<void>;
/**
* Asserts that element has specific attribute value.
*
* Can check for exact match or partial match (contains).
* Useful for validating data attributes, ARIA attributes, disabled state, etc.
*
* @param attribute - Attribute name (e.g., 'disabled', 'data-id', 'aria-label')
* @param value - Expected value
* @param opts - Optional configuration (timeout, message, pollInterval, exactMatch)
* @throws Error if attribute doesn't have expected value within timeout
*
* @example
* ```typescript
* // Check if button is disabled
* await app.expect('#submit').toHaveAttribute('disabled', 'true');
*
* // Verify data attribute
* await app.expect('.item').toHaveAttribute('data-id', '123');
*
* // Partial match for class
* await app.expect('#div').toHaveAttribute('class', 'active', { exactMatch: false });
* ```
*/
toHaveAttribute(attribute: string, value: string, opts?: ExpectAttributeOptions): Promise<void>;
/**
* Asserts that element has specific CSS class.
*
* Convenience method for checking the 'class' attribute.
* By default does partial match (class list contains the value).
*
* @param className - Class name to check for
* @param opts - Optional configuration (timeout, message, pollInterval, exactMatch)
* @throws Error if element doesn't have expected class within timeout
*
* @example
* ```typescript
* // Check if element has class (partial match)
* await app.expect('#button').toHaveClass('active');
*
* // Exact class match
* await app.expect('#div').toHaveClass('btn btn-primary', { exactMatch: true });
*
* // Wait for class to be added
* await app.click('#toggle');
* await app.expect('.panel').toHaveClass('expanded');
* ```
*/
toHaveClass(className: string, opts?: ExpectAttributeOptions): Promise<void>;
/**
* Negative assertions - opposite of the main assertions.
*/
not: {
/**
* Asserts that element is NOT visible.
*
* Waits for element to become hidden or be removed from DOM.
*
* @example
* ```typescript
* // Wait for spinner to disappear
* await app.expect('.spinner').not.toBeVisible();
*
* // Verify modal closed
* await app.click('.modal .close');
* await app.expect('.modal').not.toBeVisible();
* ```
*/
toBeVisible(opts?: ExpectOptions): Promise<void>;
/**
* Asserts that element does NOT have focus.
*
* Waits for element to lose keyboard focus.
*
* @example
* ```typescript
* // Verify focus moved away
* await app.sendKey(Key.TAB);
* await app.expect('#previous-field').not.toHaveFocus();
* ```
*/
toHaveFocus(opts?: ExpectOptions): Promise<void>;
};
}
/**
* Creates an ExpectApi instance for a specific element selector.
*
* This is the factory function that creates the fluent expect API.
* Typically called via `app.expect(selector)` rather than directly.
*
* @param driver - WebDriver instance
* @param by - By locator for the element to create expectations for
* @returns ExpectApi instance with assertion methods
*
* @example
* ```typescript
* // Usually used via app.expect()
* await app.expect('#title').toHaveText('Welcome');
*
* // But can be used directly
* const api = expectSelector(driver, By.css('#element'));
* await api.toBeVisible();
* ```
*
* @internal This is typically used internally by WebApp.expect()
*/
export declare function expectSelector(driver: ThenableWebDriver, by: By): ExpectApi;