CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-testcafe

Automated browser testing for the modern web development stack.

Pending
Overview
Eval results
Files

element-selection.mddocs/

Element Selection

TestCafe's Selector API provides powerful DOM element identification and inspection capabilities with CSS and XPath selectors, filtering methods, and automatic waiting for elements to appear.

Capabilities

Selector Creation

Create selectors using CSS selectors, XPath expressions, or JavaScript functions.

/**
 * Creates a selector for DOM elements
 * @param init - CSS selector string, XPath expression, or client function
 * @param options - Selector options including dependencies and timeout
 * @returns Selector API object with filtering and property access methods
 */
function Selector(init: string | Function, options?: SelectorOptions): SelectorAPI;

interface SelectorOptions {
    visibilityCheck?: boolean;
    timeout?: number;
    boundTestRun?: object;
    dependencies?: object;
}

interface SelectorAPI {
    (): Promise<NodeSnapshot>;
    count: Promise<number>;
    exists: Promise<boolean>;
    visible: Promise<boolean>;
    focused: Promise<boolean>;
    textContent: Promise<string>;
    innerText: Promise<string>;
    value: Promise<string>;
    checked: Promise<boolean>;
    selected: Promise<boolean>;
    selectedIndex: Promise<number>;
    id: Promise<string>;
    className: Promise<string>;
    classNames: Promise<string[]>;
    tagName: Promise<string>;
    attributes: Promise<object>;
    style: Promise<object>;
    boundingClientRect: Promise<object>;
    hasChildNodes: Promise<boolean>;
    hasChildElements: Promise<boolean>;
    childElementCount: Promise<number>;
    childNodeCount: Promise<number>;
    namespaceURI: Promise<string>;
}

Usage Examples:

import { Selector } from 'testcafe';

fixture('Selector Examples')
    .page('https://example.com');

test('Basic selectors', async t => {
    // CSS selector
    const submitButton = Selector('#submit-button');
    
    // XPath selector
    const linkByText = Selector('//a[contains(text(), "Click here")]');
    
    // Function-based selector
    const firstVisibleDiv = Selector(() => {
        const divs = document.querySelectorAll('div');
        return Array.from(divs).find(div => div.offsetParent !== null);
    });
    
    // Use selectors
    await t.click(submitButton);
    
    // Access properties
    const buttonText = await submitButton.innerText;
    const isVisible = await submitButton.visible;
});

Element Filtering

Filter elements using various criteria including text content, attributes, and position.

/**
 * Finds descendant elements matching CSS selector
 * @param cssSelector - CSS selector to find within current elements
 * @returns New selector with filtered elements
 */
find(cssSelector: string): SelectorAPI;

/**
 * Filters elements by text content
 * @param text - Exact text string or regular expression to match
 * @returns New selector with elements containing matching text
 */
withText(text: string | RegExp): SelectorAPI;

/**
 * Filters elements by attribute value
 * @param attrName - Attribute name to check
 * @param attrValue - Expected attribute value (optional, checks for presence if omitted)
 * @returns New selector with elements having matching attribute
 */
withAttribute(attrName: string, attrValue?: string | RegExp): SelectorAPI;

/**
 * Filters elements by exact text content
 * @param text - Exact text content to match
 * @returns New selector with elements having exact text match
 */
withExactText(text: string): SelectorAPI;

/**
 * Gets element at specific index
 * @param index - Zero-based index of element to select
 * @returns New selector for element at specified index
 */
nth(index: number): SelectorAPI;

/**
 * Gets first element from selection
 * @returns New selector for first element
 */
first(): SelectorAPI;

/**
 * Gets last element from selection
 * @returns New selector for last element
 */
last(): SelectorAPI;

Usage Examples:

test('Element filtering', async t => {
    // Find specific elements
    const menuItems = Selector('.menu').find('li');
    const activeItem = menuItems.withAttribute('class', 'active');
    const loginLink = Selector('a').withText('Login');
    
    // Select by position
    const firstItem = menuItems.first();
    const lastItem = menuItems.last();
    const thirdItem = menuItems.nth(2);
    
    // Combine filters
    const specificButton = Selector('button')
        .withText(/Submit/)
        .withAttribute('disabled', false);
    
    await t.click(specificButton);
});

DOM Traversal

Navigate the DOM tree using parent, child, and sibling relationships.

/**
 * Gets parent element
 * @param cssSelector - Optional CSS selector to filter parent elements
 * @returns New selector for parent element(s)
 */
parent(cssSelector?: string): SelectorAPI;

/**
 * Gets child elements
 * @param cssSelector - Optional CSS selector to filter child elements
 * @returns New selector for child element(s)
 */
child(cssSelector?: string): SelectorAPI;

/**
 * Gets sibling elements
 * @param cssSelector - Optional CSS selector to filter sibling elements
 * @returns New selector for sibling element(s)
 */
sibling(cssSelector?: string): SelectorAPI;

/**
 * Gets next sibling element
 * @param cssSelector - Optional CSS selector to filter next sibling
 * @returns New selector for next sibling element
 */
nextSibling(cssSelector?: string): SelectorAPI;

/**
 * Gets previous sibling element
 * @param cssSelector - Optional CSS selector to filter previous sibling
 * @returns New selector for previous sibling element
 */
prevSibling(cssSelector?: string): SelectorAPI;

Usage Examples:

test('DOM traversal', async t => {
    // Navigate up the DOM
    const inputField = Selector('#username');
    const formContainer = inputField.parent('form');
    const parentDiv = inputField.parent();
    
    // Navigate down the DOM
    const table = Selector('#data-table');
    const tableRows = table.child('tbody').child('tr');
    const firstCell = tableRows.first().child('td').first();
    
    // Navigate across siblings
    const currentTab = Selector('.tab.active');
    const nextTab = currentTab.nextSibling('.tab');
    const prevTab = currentTab.prevSibling('.tab');
    
    await t.click(nextTab);
});

Element Properties

Access various DOM element properties and computed styles.

// Properties available on selector instances
interface SelectorAPI {
    /** Number of elements matching the selector */
    count: Promise<number>;
    
    /** Whether any elements exist */
    exists: Promise<boolean>;
    
    /** Whether element is visible */
    visible: Promise<boolean>;
    
    /** Whether element has focus */
    focused: Promise<boolean>;
    
    /** Element's text content including hidden text */
    textContent: Promise<string>;
    
    /** Element's visible text content */
    innerText: Promise<string>;
    
    /** Value property for form elements */
    value: Promise<string>;
    
    /** Checked state for checkboxes and radio buttons */
    checked: Promise<boolean>;
    
    /** Selected state for option elements */
    selected: Promise<boolean>;
    
    /** Selected index for select elements */
    selectedIndex: Promise<number>;
    
    /** Element's id attribute */
    id: Promise<string>;
    
    /** Element's class attribute */
    className: Promise<string>;
    
    /** Array of class names */
    classNames: Promise<string[]>;
    
    /** Element's tag name */
    tagName: Promise<string>;
    
    /** All element attributes as object */
    attributes: Promise<{[key: string]: string}>;
    
    /** Computed styles as object */
    style: Promise<{[key: string]: string}>;
    
    /** Element's bounding rectangle */
    boundingClientRect: Promise<{
        left: number;
        top: number;
        right: number;
        bottom: number;
        width: number;
        height: number;
    }>;
}

Usage Examples:

test('Element properties', async t => {
    const element = Selector('#my-element');
    
    // Check element state
    const exists = await element.exists;
    const isVisible = await element.visible;
    const hasFocus = await element.focused;
    
    // Get text content
    const text = await element.innerText;
    const fullText = await element.textContent;
    
    // Get form values
    const inputValue = await Selector('#username').value;
    const isChecked = await Selector('#agree').checked;
    
    // Get element info
    const elementId = await element.id;
    const classes = await element.classNames;
    const tagName = await element.tagName;
    
    // Get computed styles
    const styles = await element.style;
    const backgroundColor = styles.backgroundColor;
    
    // Get position and size
    const rect = await element.boundingClientRect;
    console.log(`Element is ${rect.width}x${rect.height} at (${rect.left}, ${rect.top})`);
});

Custom Selectors

Create custom selectors using client-side JavaScript functions.

/**
 * Create selector using custom client function
 * @param fn - Function to execute in browser context
 * @param options - Selector options including dependencies
 * @returns Selector API object
 */
function Selector(fn: Function, options?: {
    dependencies?: {[key: string]: any};
}): SelectorAPI;

Usage Examples:

test('Custom selectors', async t => {
    // Select element by computed style
    const redElements = Selector(() => {
        const elements = document.querySelectorAll('*');
        return Array.from(elements).filter(el => {
            const style = getComputedStyle(el);
            return style.color === 'red' || style.backgroundColor === 'red';
        });
    });
    
    // Select element with custom logic
    const firstVisibleButton = Selector(() => {
        const buttons = document.querySelectorAll('button');
        return Array.from(buttons).find(button => {
            const rect = button.getBoundingClientRect();
            return rect.width > 0 && rect.height > 0;
        });
    });
    
    // Selector with dependencies
    const searchTerm = 'testcafe';
    const elementWithSearchTerm = Selector((term) => {
        const elements = document.querySelectorAll('*');
        return Array.from(elements).find(el => 
            el.textContent && el.textContent.includes(term)
        );
    }, { dependencies: { term: searchTerm } });
    
    await t.click(firstVisibleButton);
});

Selector Snapshots

Get detailed element information using snapshots.

/**
 * Execute selector and return element snapshot
 * @returns Promise resolving to detailed element information
 */
(): Promise<NodeSnapshot>;

interface NodeSnapshot {
    tagName: string;
    attributes: {[key: string]: string};
    boundingClientRect: {
        left: number;
        top: number; 
        right: number;
        bottom: number;
        width: number;
        height: number;
    };
    style: {[key: string]: string};
    innerText: string;
    textContent: string;
    namespaceURI: string;
    id: string;
    className: string;
    classNames: string[];
    value: any;
    checked: boolean;
    selected: boolean;
    selectedIndex: number;
    childElementCount: number;
    childNodeCount: number;
    hasChildNodes: boolean;
    hasChildElements: boolean;
    visible: boolean;
    focused: boolean;
    exists: boolean;
}

Usage Examples:

test('Element snapshots', async t => {
    const button = Selector('#submit-button');
    
    // Get complete element snapshot
    const snapshot = await button();
    
    console.log('Button details:', {
        tag: snapshot.tagName,
        text: snapshot.innerText,
        classes: snapshot.classNames,
        position: snapshot.boundingClientRect,
        visible: snapshot.visible,
        attributes: snapshot.attributes
    });
    
    // Use snapshot data in assertions
    await t.expect(snapshot.visible).ok();
    await t.expect(snapshot.tagName).eql('BUTTON');
});

Install with Tessl CLI

npx tessl i tessl/npm-testcafe

docs

assertions.md

browser-automation.md

client-functions.md

element-selection.md

index.md

programmatic-api.md

request-interception.md

user-roles.md

tile.json