Implementation:DevExpress Testcafe Selector Builder
| Knowledge Sources | |
|---|---|
| Domains | Testing, Web_Automation |
| Last Updated | 2026-02-12 04:00 GMT |
Overview
Concrete implementation of element selection in TestCafe through the `Selector()` factory function and `SelectorBuilder` class, providing CSS-based and function-based DOM element identification.
Description
The `Selector()` factory creates selectors that identify DOM elements for interaction and verification. It accepts either a CSS selector string or a filter function that executes in the browser context. The underlying `SelectorBuilder` class extends `ClientFunctionBuilder` to handle the compilation and execution of selector logic. Selectors return promise-like objects (SelectorPromise) that can be awaited or used directly in TestCafe actions, with lazy evaluation ensuring elements are queried at execution time.
Usage
Use `Selector()` to create element references in tests or page objects. Pass CSS strings for simple selections or functions for complex filtering logic. Configure options like timeout and visibility checking for specific scenarios.
Code Reference
Source Location
- Repository: testcafe
- File: src/client-functions/selectors/selector-builder.js
- Lines: 17-222
- Factory: src/api/exportable-lib/index.js lines 34-38
Signature
// Factory function
function Selector(
fn: string | Function,
options?: {
dependencies?: object,
visibilityCheck?: boolean,
timeout?: number,
boundTestRun?: TestRun
}
): SelectorPromise
// SelectorBuilder class
class SelectorBuilder extends ClientFunctionBuilder {
constructor(
fn: string | Function,
options?: object,
callsiteNames?: object,
callsite?: object
)
getFunction(): SelectorPromise
}
Import
import { Selector } from 'testcafe';
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| fn | Function | Yes | CSS selector string or filter function to identify elements |
| options.dependencies | object | No | Variables to pass into the selector function scope |
| options.visibilityCheck | boolean | No | Whether to filter out invisible elements (default: true) |
| options.timeout | number | No | Maximum time in milliseconds to wait for element (default: from config) |
| options.boundTestRun | TestRun | No | Internal: associates selector with specific test execution |
Outputs
| Name | Type | Description |
|---|---|---|
| selector | SelectorPromise | Promise-like object with Selector API methods and properties |
Usage Examples
CSS Selector
import { Selector } from 'testcafe';
fixture`Element Selection`
.page`https://example.com`;
test('Select by CSS', async t => {
const submitButton = Selector('#submit-button');
const emailInput = Selector('input[type="email"]');
const navLinks = Selector('.nav-menu a');
await t
.typeText(emailInput, 'user@example.com')
.click(submitButton);
});
Filter Function
import { Selector } from 'testcafe';
test('Select with function', async t => {
// Select first paragraph with more than 100 characters
const longParagraph = Selector(() => {
const paragraphs = document.querySelectorAll('p');
return Array.from(paragraphs).find(p => p.textContent.length > 100);
});
const text = await longParagraph.textContent;
console.log(text);
});
With Dependencies
import { Selector } from 'testcafe';
test('Selector with dependencies', async t => {
const minPrice = 100;
const maxPrice = 500;
const affordableProducts = Selector(() => {
const products = document.querySelectorAll('.product');
return Array.from(products).filter(product => {
const price = parseFloat(product.dataset.price);
return price >= minPrice && price <= maxPrice;
});
}, { dependencies: { minPrice, maxPrice } });
const count = await affordableProducts.count;
await t.expect(count).gt(0);
});
With Options
import { Selector } from 'testcafe';
test('Selector with custom options', async t => {
// Wait up to 10 seconds for element, include hidden elements
const delayedElement = Selector('#delayed-content', {
timeout: 10000,
visibilityCheck: false
});
await t.expect(delayedElement.exists).ok();
});
Reusable Selectors
import { Selector } from 'testcafe';
// Define once, use multiple times
const header = Selector('header');
const mainNav = Selector('.main-nav');
const userMenu = Selector('#user-menu');
fixture`Navigation Tests`
.page`https://example.com`;
test('Check header elements', async t => {
await t
.expect(header.exists).ok()
.expect(mainNav.visible).ok()
.expect(userMenu.visible).ok();
});