0
# Element Selection
1
2
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.
3
4
## Capabilities
5
6
### Selector Creation
7
8
Create selectors using CSS selectors, XPath expressions, or JavaScript functions.
9
10
```javascript { .api }
11
/**
12
* Creates a selector for DOM elements
13
* @param init - CSS selector string, XPath expression, or client function
14
* @param options - Selector options including dependencies and timeout
15
* @returns Selector API object with filtering and property access methods
16
*/
17
function Selector(init: string | Function, options?: SelectorOptions): SelectorAPI;
18
19
interface SelectorOptions {
20
visibilityCheck?: boolean;
21
timeout?: number;
22
boundTestRun?: object;
23
dependencies?: object;
24
}
25
26
interface SelectorAPI {
27
(): Promise<NodeSnapshot>;
28
count: Promise<number>;
29
exists: Promise<boolean>;
30
visible: Promise<boolean>;
31
focused: Promise<boolean>;
32
textContent: Promise<string>;
33
innerText: Promise<string>;
34
value: Promise<string>;
35
checked: Promise<boolean>;
36
selected: Promise<boolean>;
37
selectedIndex: Promise<number>;
38
id: Promise<string>;
39
className: Promise<string>;
40
classNames: Promise<string[]>;
41
tagName: Promise<string>;
42
attributes: Promise<object>;
43
style: Promise<object>;
44
boundingClientRect: Promise<object>;
45
hasChildNodes: Promise<boolean>;
46
hasChildElements: Promise<boolean>;
47
childElementCount: Promise<number>;
48
childNodeCount: Promise<number>;
49
namespaceURI: Promise<string>;
50
}
51
```
52
53
**Usage Examples:**
54
55
```javascript
56
import { Selector } from 'testcafe';
57
58
fixture('Selector Examples')
59
.page('https://example.com');
60
61
test('Basic selectors', async t => {
62
// CSS selector
63
const submitButton = Selector('#submit-button');
64
65
// XPath selector
66
const linkByText = Selector('//a[contains(text(), "Click here")]');
67
68
// Function-based selector
69
const firstVisibleDiv = Selector(() => {
70
const divs = document.querySelectorAll('div');
71
return Array.from(divs).find(div => div.offsetParent !== null);
72
});
73
74
// Use selectors
75
await t.click(submitButton);
76
77
// Access properties
78
const buttonText = await submitButton.innerText;
79
const isVisible = await submitButton.visible;
80
});
81
```
82
83
### Element Filtering
84
85
Filter elements using various criteria including text content, attributes, and position.
86
87
```javascript { .api }
88
/**
89
* Finds descendant elements matching CSS selector
90
* @param cssSelector - CSS selector to find within current elements
91
* @returns New selector with filtered elements
92
*/
93
find(cssSelector: string): SelectorAPI;
94
95
/**
96
* Filters elements by text content
97
* @param text - Exact text string or regular expression to match
98
* @returns New selector with elements containing matching text
99
*/
100
withText(text: string | RegExp): SelectorAPI;
101
102
/**
103
* Filters elements by attribute value
104
* @param attrName - Attribute name to check
105
* @param attrValue - Expected attribute value (optional, checks for presence if omitted)
106
* @returns New selector with elements having matching attribute
107
*/
108
withAttribute(attrName: string, attrValue?: string | RegExp): SelectorAPI;
109
110
/**
111
* Filters elements by exact text content
112
* @param text - Exact text content to match
113
* @returns New selector with elements having exact text match
114
*/
115
withExactText(text: string): SelectorAPI;
116
117
/**
118
* Gets element at specific index
119
* @param index - Zero-based index of element to select
120
* @returns New selector for element at specified index
121
*/
122
nth(index: number): SelectorAPI;
123
124
/**
125
* Gets first element from selection
126
* @returns New selector for first element
127
*/
128
first(): SelectorAPI;
129
130
/**
131
* Gets last element from selection
132
* @returns New selector for last element
133
*/
134
last(): SelectorAPI;
135
```
136
137
**Usage Examples:**
138
139
```javascript
140
test('Element filtering', async t => {
141
// Find specific elements
142
const menuItems = Selector('.menu').find('li');
143
const activeItem = menuItems.withAttribute('class', 'active');
144
const loginLink = Selector('a').withText('Login');
145
146
// Select by position
147
const firstItem = menuItems.first();
148
const lastItem = menuItems.last();
149
const thirdItem = menuItems.nth(2);
150
151
// Combine filters
152
const specificButton = Selector('button')
153
.withText(/Submit/)
154
.withAttribute('disabled', false);
155
156
await t.click(specificButton);
157
});
158
```
159
160
### DOM Traversal
161
162
Navigate the DOM tree using parent, child, and sibling relationships.
163
164
```javascript { .api }
165
/**
166
* Gets parent element
167
* @param cssSelector - Optional CSS selector to filter parent elements
168
* @returns New selector for parent element(s)
169
*/
170
parent(cssSelector?: string): SelectorAPI;
171
172
/**
173
* Gets child elements
174
* @param cssSelector - Optional CSS selector to filter child elements
175
* @returns New selector for child element(s)
176
*/
177
child(cssSelector?: string): SelectorAPI;
178
179
/**
180
* Gets sibling elements
181
* @param cssSelector - Optional CSS selector to filter sibling elements
182
* @returns New selector for sibling element(s)
183
*/
184
sibling(cssSelector?: string): SelectorAPI;
185
186
/**
187
* Gets next sibling element
188
* @param cssSelector - Optional CSS selector to filter next sibling
189
* @returns New selector for next sibling element
190
*/
191
nextSibling(cssSelector?: string): SelectorAPI;
192
193
/**
194
* Gets previous sibling element
195
* @param cssSelector - Optional CSS selector to filter previous sibling
196
* @returns New selector for previous sibling element
197
*/
198
prevSibling(cssSelector?: string): SelectorAPI;
199
```
200
201
**Usage Examples:**
202
203
```javascript
204
test('DOM traversal', async t => {
205
// Navigate up the DOM
206
const inputField = Selector('#username');
207
const formContainer = inputField.parent('form');
208
const parentDiv = inputField.parent();
209
210
// Navigate down the DOM
211
const table = Selector('#data-table');
212
const tableRows = table.child('tbody').child('tr');
213
const firstCell = tableRows.first().child('td').first();
214
215
// Navigate across siblings
216
const currentTab = Selector('.tab.active');
217
const nextTab = currentTab.nextSibling('.tab');
218
const prevTab = currentTab.prevSibling('.tab');
219
220
await t.click(nextTab);
221
});
222
```
223
224
### Element Properties
225
226
Access various DOM element properties and computed styles.
227
228
```javascript { .api }
229
// Properties available on selector instances
230
interface SelectorAPI {
231
/** Number of elements matching the selector */
232
count: Promise<number>;
233
234
/** Whether any elements exist */
235
exists: Promise<boolean>;
236
237
/** Whether element is visible */
238
visible: Promise<boolean>;
239
240
/** Whether element has focus */
241
focused: Promise<boolean>;
242
243
/** Element's text content including hidden text */
244
textContent: Promise<string>;
245
246
/** Element's visible text content */
247
innerText: Promise<string>;
248
249
/** Value property for form elements */
250
value: Promise<string>;
251
252
/** Checked state for checkboxes and radio buttons */
253
checked: Promise<boolean>;
254
255
/** Selected state for option elements */
256
selected: Promise<boolean>;
257
258
/** Selected index for select elements */
259
selectedIndex: Promise<number>;
260
261
/** Element's id attribute */
262
id: Promise<string>;
263
264
/** Element's class attribute */
265
className: Promise<string>;
266
267
/** Array of class names */
268
classNames: Promise<string[]>;
269
270
/** Element's tag name */
271
tagName: Promise<string>;
272
273
/** All element attributes as object */
274
attributes: Promise<{[key: string]: string}>;
275
276
/** Computed styles as object */
277
style: Promise<{[key: string]: string}>;
278
279
/** Element's bounding rectangle */
280
boundingClientRect: Promise<{
281
left: number;
282
top: number;
283
right: number;
284
bottom: number;
285
width: number;
286
height: number;
287
}>;
288
}
289
```
290
291
**Usage Examples:**
292
293
```javascript
294
test('Element properties', async t => {
295
const element = Selector('#my-element');
296
297
// Check element state
298
const exists = await element.exists;
299
const isVisible = await element.visible;
300
const hasFocus = await element.focused;
301
302
// Get text content
303
const text = await element.innerText;
304
const fullText = await element.textContent;
305
306
// Get form values
307
const inputValue = await Selector('#username').value;
308
const isChecked = await Selector('#agree').checked;
309
310
// Get element info
311
const elementId = await element.id;
312
const classes = await element.classNames;
313
const tagName = await element.tagName;
314
315
// Get computed styles
316
const styles = await element.style;
317
const backgroundColor = styles.backgroundColor;
318
319
// Get position and size
320
const rect = await element.boundingClientRect;
321
console.log(`Element is ${rect.width}x${rect.height} at (${rect.left}, ${rect.top})`);
322
});
323
```
324
325
### Custom Selectors
326
327
Create custom selectors using client-side JavaScript functions.
328
329
```javascript { .api }
330
/**
331
* Create selector using custom client function
332
* @param fn - Function to execute in browser context
333
* @param options - Selector options including dependencies
334
* @returns Selector API object
335
*/
336
function Selector(fn: Function, options?: {
337
dependencies?: {[key: string]: any};
338
}): SelectorAPI;
339
```
340
341
**Usage Examples:**
342
343
```javascript
344
test('Custom selectors', async t => {
345
// Select element by computed style
346
const redElements = Selector(() => {
347
const elements = document.querySelectorAll('*');
348
return Array.from(elements).filter(el => {
349
const style = getComputedStyle(el);
350
return style.color === 'red' || style.backgroundColor === 'red';
351
});
352
});
353
354
// Select element with custom logic
355
const firstVisibleButton = Selector(() => {
356
const buttons = document.querySelectorAll('button');
357
return Array.from(buttons).find(button => {
358
const rect = button.getBoundingClientRect();
359
return rect.width > 0 && rect.height > 0;
360
});
361
});
362
363
// Selector with dependencies
364
const searchTerm = 'testcafe';
365
const elementWithSearchTerm = Selector((term) => {
366
const elements = document.querySelectorAll('*');
367
return Array.from(elements).find(el =>
368
el.textContent && el.textContent.includes(term)
369
);
370
}, { dependencies: { term: searchTerm } });
371
372
await t.click(firstVisibleButton);
373
});
374
```
375
376
### Selector Snapshots
377
378
Get detailed element information using snapshots.
379
380
```javascript { .api }
381
/**
382
* Execute selector and return element snapshot
383
* @returns Promise resolving to detailed element information
384
*/
385
(): Promise<NodeSnapshot>;
386
387
interface NodeSnapshot {
388
tagName: string;
389
attributes: {[key: string]: string};
390
boundingClientRect: {
391
left: number;
392
top: number;
393
right: number;
394
bottom: number;
395
width: number;
396
height: number;
397
};
398
style: {[key: string]: string};
399
innerText: string;
400
textContent: string;
401
namespaceURI: string;
402
id: string;
403
className: string;
404
classNames: string[];
405
value: any;
406
checked: boolean;
407
selected: boolean;
408
selectedIndex: number;
409
childElementCount: number;
410
childNodeCount: number;
411
hasChildNodes: boolean;
412
hasChildElements: boolean;
413
visible: boolean;
414
focused: boolean;
415
exists: boolean;
416
}
417
```
418
419
**Usage Examples:**
420
421
```javascript
422
test('Element snapshots', async t => {
423
const button = Selector('#submit-button');
424
425
// Get complete element snapshot
426
const snapshot = await button();
427
428
console.log('Button details:', {
429
tag: snapshot.tagName,
430
text: snapshot.innerText,
431
classes: snapshot.classNames,
432
position: snapshot.boundingClientRect,
433
visible: snapshot.visible,
434
attributes: snapshot.attributes
435
});
436
437
// Use snapshot data in assertions
438
await t.expect(snapshot.visible).ok();
439
await t.expect(snapshot.tagName).eql('BUTTON');
440
});
441
```