0
# Element Queries
1
2
Complete set of query methods for finding elements using accessibility-focused selectors. React Testing Library re-exports all query methods from DOM Testing Library, providing three query variants (get*, query*, find*) for each selector type.
3
4
## Query Types
5
6
### Get Queries
7
8
Queries that throw an error if no element is found. Use for elements that should always be present.
9
10
```typescript { .api }
11
/**
12
* Find element by accessible role
13
* @param role - ARIA role or HTML element role
14
* @param options - Additional filtering options
15
* @returns HTMLElement (throws if not found)
16
*/
17
function getByRole(role: string, options?: ByRoleOptions): HTMLElement;
18
19
/**
20
* Find element by associated label text
21
* @param text - Label text content
22
* @param options - Text matching options
23
* @returns HTMLElement (throws if not found)
24
*/
25
function getByLabelText(text: string, options?: SelectorMatcherOptions): HTMLElement;
26
27
/**
28
* Find input element by placeholder text
29
* @param text - Placeholder text content
30
* @param options - Text matching options
31
* @returns HTMLElement (throws if not found)
32
*/
33
function getByPlaceholderText(text: string, options?: MatcherOptions): HTMLElement;
34
35
/**
36
* Find element by text content
37
* @param text - Text content to search for
38
* @param options - Text matching and selector options
39
* @returns HTMLElement (throws if not found)
40
*/
41
function getByText(text: string, options?: SelectorMatcherOptions): HTMLElement;
42
43
/**
44
* Find form element by current display value
45
* @param value - Current input/select/textarea value
46
* @param options - Text matching options
47
* @returns HTMLElement (throws if not found)
48
*/
49
function getByDisplayValue(value: string, options?: MatcherOptions): HTMLElement;
50
51
/**
52
* Find img element by alt text
53
* @param text - Alt attribute content
54
* @param options - Text matching options
55
* @returns HTMLElement (throws if not found)
56
*/
57
function getByAltText(text: string, options?: MatcherOptions): HTMLElement;
58
59
/**
60
* Find element by title attribute
61
* @param title - Title attribute content
62
* @param options - Text matching options
63
* @returns HTMLElement (throws if not found)
64
*/
65
function getByTitle(title: string, options?: MatcherOptions): HTMLElement;
66
67
/**
68
* Find element by test ID attribute
69
* @param testId - Test ID attribute value
70
* @param options - Text matching options
71
* @returns HTMLElement (throws if not found)
72
*/
73
function getByTestId(testId: string, options?: MatcherOptions): HTMLElement;
74
```
75
76
### Query Queries
77
78
Queries that return `null` if no element is found. Use for elements that may or may not be present.
79
80
```typescript { .api }
81
/**
82
* Find element by accessible role, returns null if not found
83
*/
84
function queryByRole(role: string, options?: ByRoleOptions): HTMLElement | null;
85
86
/**
87
* Find element by associated label text, returns null if not found
88
*/
89
function queryByLabelText(text: string, options?: SelectorMatcherOptions): HTMLElement | null;
90
91
/**
92
* Find input element by placeholder text, returns null if not found
93
*/
94
function queryByPlaceholderText(text: string, options?: MatcherOptions): HTMLElement | null;
95
96
/**
97
* Find element by text content, returns null if not found
98
*/
99
function queryByText(text: string, options?: SelectorMatcherOptions): HTMLElement | null;
100
101
/**
102
* Find form element by current display value, returns null if not found
103
*/
104
function queryByDisplayValue(value: string, options?: MatcherOptions): HTMLElement | null;
105
106
/**
107
* Find img element by alt text, returns null if not found
108
*/
109
function queryByAltText(text: string, options?: MatcherOptions): HTMLElement | null;
110
111
/**
112
* Find element by title attribute, returns null if not found
113
*/
114
function queryByTitle(title: string, options?: MatcherOptions): HTMLElement | null;
115
116
/**
117
* Find element by test ID attribute, returns null if not found
118
*/
119
function queryByTestId(testId: string, options?: MatcherOptions): HTMLElement | null;
120
```
121
122
### Find Queries
123
124
Async queries that wait for elements to appear in the DOM. Use for elements that appear after asynchronous operations.
125
126
```typescript { .api }
127
/**
128
* Wait for element with accessible role to appear
129
* @param role - ARIA role or HTML element role
130
* @param options - Role filtering options
131
* @param waitForOptions - Wait timing configuration
132
* @returns Promise<HTMLElement> (rejects if not found within timeout)
133
*/
134
function findByRole(
135
role: string,
136
options?: ByRoleOptions,
137
waitForOptions?: WaitForOptions
138
): Promise<HTMLElement>;
139
140
/**
141
* Wait for element with associated label text to appear
142
*/
143
function findByLabelText(
144
text: string,
145
options?: SelectorMatcherOptions,
146
waitForOptions?: WaitForOptions
147
): Promise<HTMLElement>;
148
149
/**
150
* Wait for input element with placeholder text to appear
151
*/
152
function findByPlaceholderText(
153
text: string,
154
options?: MatcherOptions,
155
waitForOptions?: WaitForOptions
156
): Promise<HTMLElement>;
157
158
/**
159
* Wait for element with text content to appear
160
*/
161
function findByText(
162
text: string,
163
options?: SelectorMatcherOptions,
164
waitForOptions?: WaitForOptions
165
): Promise<HTMLElement>;
166
167
/**
168
* Wait for form element with display value to appear
169
*/
170
function findByDisplayValue(
171
value: string,
172
options?: MatcherOptions,
173
waitForOptions?: WaitForOptions
174
): Promise<HTMLElement>;
175
176
/**
177
* Wait for img element with alt text to appear
178
*/
179
function findByAltText(
180
text: string,
181
options?: MatcherOptions,
182
waitForOptions?: WaitForOptions
183
): Promise<HTMLElement>;
184
185
/**
186
* Wait for element with title attribute to appear
187
*/
188
function findByTitle(
189
title: string,
190
options?: MatcherOptions,
191
waitForOptions?: WaitForOptions
192
): Promise<HTMLElement>;
193
194
/**
195
* Wait for element with test ID attribute to appear
196
*/
197
function findByTestId(
198
testId: string,
199
options?: MatcherOptions,
200
waitForOptions?: WaitForOptions
201
): Promise<HTMLElement>;
202
```
203
204
### Multiple Element Queries
205
206
Queries that return arrays of elements instead of single elements.
207
208
```typescript { .api }
209
// Get All queries - throw if none found
210
function getAllByRole(role: string, options?: ByRoleOptions): HTMLElement[];
211
function getAllByLabelText(text: string, options?: SelectorMatcherOptions): HTMLElement[];
212
function getAllByPlaceholderText(text: string, options?: MatcherOptions): HTMLElement[];
213
function getAllByText(text: string, options?: SelectorMatcherOptions): HTMLElement[];
214
function getAllByDisplayValue(value: string, options?: MatcherOptions): HTMLElement[];
215
function getAllByAltText(text: string, options?: MatcherOptions): HTMLElement[];
216
function getAllByTitle(title: string, options?: MatcherOptions): HTMLElement[];
217
function getAllByTestId(testId: string, options?: MatcherOptions): HTMLElement[];
218
219
// Query All queries - return empty array if none found
220
function queryAllByRole(role: string, options?: ByRoleOptions): HTMLElement[];
221
function queryAllByLabelText(text: string, options?: SelectorMatcherOptions): HTMLElement[];
222
function queryAllByPlaceholderText(text: string, options?: MatcherOptions): HTMLElement[];
223
function queryAllByText(text: string, options?: SelectorMatcherOptions): HTMLElement[];
224
function queryAllByDisplayValue(value: string, options?: MatcherOptions): HTMLElement[];
225
function queryAllByAltText(text: string, options?: MatcherOptions): HTMLElement[];
226
function queryAllByTitle(title: string, options?: MatcherOptions): HTMLElement[];
227
function queryAllByTestId(testId: string, options?: MatcherOptions): HTMLElement[];
228
229
// Find All queries - wait for elements to appear
230
function findAllByRole(role: string, options?: ByRoleOptions, waitForOptions?: WaitForOptions): Promise<HTMLElement[]>;
231
function findAllByLabelText(text: string, options?: SelectorMatcherOptions, waitForOptions?: WaitForOptions): Promise<HTMLElement[]>;
232
function findAllByPlaceholderText(text: string, options?: MatcherOptions, waitForOptions?: WaitForOptions): Promise<HTMLElement[]>;
233
function findAllByText(text: string, options?: SelectorMatcherOptions, waitForOptions?: WaitForOptions): Promise<HTMLElement[]>;
234
function findAllByDisplayValue(value: string, options?: MatcherOptions, waitForOptions?: WaitForOptions): Promise<HTMLElement[]>;
235
function findAllByAltText(text: string, options?: MatcherOptions, waitForOptions?: WaitForOptions): Promise<HTMLElement[]>;
236
function findAllByTitle(title: string, options?: MatcherOptions, waitForOptions?: WaitForOptions): Promise<HTMLElement[]>;
237
function findAllByTestId(testId: string, options?: MatcherOptions, waitForOptions?: WaitForOptions): Promise<HTMLElement[]>;
238
```
239
240
## Query Options
241
242
### Basic Matcher Options
243
244
```typescript { .api }
245
interface MatcherOptions {
246
/** Whether to match exact text or allow partial matches */
247
exact?: boolean;
248
/** Function to normalize text before matching */
249
normalizer?: (text: string) => string;
250
}
251
```
252
253
### Selector Matcher Options
254
255
```typescript { .api }
256
interface SelectorMatcherOptions extends MatcherOptions {
257
/** CSS selector to limit search scope */
258
selector?: string;
259
}
260
```
261
262
### By Role Options
263
264
```typescript { .api }
265
interface ByRoleOptions extends MatcherOptions {
266
/** Filter by checked state for checkboxes/radios */
267
checked?: boolean;
268
/** Filter by aria-current attribute */
269
current?: boolean | string;
270
/** Filter by expanded state */
271
expanded?: boolean;
272
/** Include elements hidden from accessibility tree */
273
hidden?: boolean;
274
/** Filter by heading level */
275
level?: number;
276
/** Filter by accessible name */
277
name?: string | RegExp;
278
/** Filter by pressed state */
279
pressed?: boolean;
280
/** Filter by selected state */
281
selected?: boolean;
282
}
283
```
284
285
### Wait For Options
286
287
```typescript { .api }
288
interface WaitForOptions {
289
/** Element container to search within */
290
container?: HTMLElement;
291
/** Timeout in milliseconds (default: 1000) */
292
timeout?: number;
293
/** Polling interval in milliseconds (default: 50) */
294
interval?: number;
295
/** Custom error message on timeout */
296
onTimeout?: (error: Error) => Error;
297
}
298
```
299
300
## Usage Examples
301
302
### Basic Query Usage
303
304
```typescript
305
import { render, screen } from "@testing-library/react";
306
307
function LoginForm() {
308
return (
309
<form>
310
<label htmlFor="username">Username</label>
311
<input id="username" placeholder="Enter username" />
312
313
<label htmlFor="password">Password</label>
314
<input id="password" type="password" />
315
316
<button type="submit">Log In</button>
317
</form>
318
);
319
}
320
321
render(<LoginForm />);
322
323
// Find by role (most preferred)
324
const submitButton = screen.getByRole('button', { name: 'Log In' });
325
326
// Find by label text
327
const usernameInput = screen.getByLabelText('Username');
328
329
// Find by placeholder
330
const usernameByPlaceholder = screen.getByPlaceholderText('Enter username');
331
332
// Find by text content
333
const loginButton = screen.getByText('Log In');
334
```
335
336
### Conditional Queries
337
338
```typescript
339
function ConditionalComponent({ showMessage }: { showMessage: boolean }) {
340
return (
341
<div>
342
<h1>App Title</h1>
343
{showMessage && <p>Welcome message</p>}
344
</div>
345
);
346
}
347
348
render(<ConditionalComponent showMessage={false} />);
349
350
// Element that should always be present
351
const title = screen.getByText('App Title');
352
353
// Element that may not be present
354
const message = screen.queryByText('Welcome message');
355
expect(message).toBe(null);
356
357
// Rerender with message
358
rerender(<ConditionalComponent showMessage={true} />);
359
const welcomeMessage = screen.getByText('Welcome message');
360
expect(welcomeMessage).toBeInTheDocument();
361
```
362
363
### Async Queries
364
365
```typescript
366
function AsyncComponent() {
367
const [loading, setLoading] = useState(true);
368
const [data, setData] = useState(null);
369
370
useEffect(() => {
371
setTimeout(() => {
372
setData('Loaded data');
373
setLoading(false);
374
}, 1000);
375
}, []);
376
377
return (
378
<div>
379
{loading ? (
380
<p>Loading...</p>
381
) : (
382
<p>Data: {data}</p>
383
)}
384
</div>
385
);
386
}
387
388
render(<AsyncComponent />);
389
390
// Initially shows loading
391
expect(screen.getByText('Loading...')).toBeInTheDocument();
392
393
// Wait for data to load
394
const dataElement = await screen.findByText('Data: Loaded data');
395
expect(dataElement).toBeInTheDocument();
396
397
// Loading message should be gone
398
expect(screen.queryByText('Loading...')).toBe(null);
399
```
400
401
### Multiple Element Queries
402
403
```typescript
404
function TodoList({ todos }: { todos: string[] }) {
405
return (
406
<ul>
407
{todos.map((todo, index) => (
408
<li key={index}>
409
<span>{todo}</span>
410
<button>Delete</button>
411
</li>
412
))}
413
</ul>
414
);
415
}
416
417
const todos = ['Buy milk', 'Walk dog', 'Write code'];
418
render(<TodoList todos={todos} />);
419
420
// Get all todo items
421
const todoItems = screen.getAllByRole('listitem');
422
expect(todoItems).toHaveLength(3);
423
424
// Get all delete buttons
425
const deleteButtons = screen.getAllByText('Delete');
426
expect(deleteButtons).toHaveLength(3);
427
428
// Get specific todo
429
const milkTodo = screen.getByText('Buy milk');
430
```
431
432
### Advanced Role Queries
433
434
```typescript
435
function DataTable() {
436
return (
437
<table>
438
<thead>
439
<tr>
440
<th>Name</th>
441
<th>Age</th>
442
<th>Active</th>
443
</tr>
444
</thead>
445
<tbody>
446
<tr>
447
<td>John</td>
448
<td>25</td>
449
<td>
450
<input type="checkbox" checked aria-label="John is active" />
451
</td>
452
</tr>
453
<tr>
454
<td>Jane</td>
455
<td>30</td>
456
<td>
457
<input type="checkbox" aria-label="Jane is active" />
458
</td>
459
</tr>
460
</tbody>
461
</table>
462
);
463
}
464
465
render(<DataTable />);
466
467
// Find table
468
const table = screen.getByRole('table');
469
470
// Find column headers
471
const nameHeader = screen.getByRole('columnheader', { name: 'Name' });
472
473
// Find checkboxes by state
474
const checkedBox = screen.getByRole('checkbox', {
475
checked: true,
476
name: 'John is active'
477
});
478
479
const uncheckedBox = screen.getByRole('checkbox', {
480
checked: false,
481
name: 'Jane is active'
482
});
483
```
484
485
### Scoped Queries with within
486
487
```typescript
488
import { within } from "@testing-library/react";
489
490
function UserCard({ user }: { user: { name: string; email: string; role: string } }) {
491
return (
492
<div data-testid="user-card">
493
<h3>{user.name}</h3>
494
<p>{user.email}</p>
495
<span>{user.role}</span>
496
<button>Edit</button>
497
<button>Delete</button>
498
</div>
499
);
500
}
501
502
function UserList({ users }) {
503
return (
504
<div>
505
{users.map(user => (
506
<UserCard key={user.id} user={user} />
507
))}
508
</div>
509
);
510
}
511
512
const users = [
513
{ id: 1, name: 'John', email: 'john@example.com', role: 'Admin' },
514
{ id: 2, name: 'Jane', email: 'jane@example.com', role: 'User' }
515
];
516
517
render(<UserList users={users} />);
518
519
// Get all user cards
520
const userCards = screen.getAllByTestId('user-card');
521
522
// Query within specific card
523
const johnCard = userCards[0];
524
const johnName = within(johnCard).getByText('John');
525
const johnEditButton = within(johnCard).getByText('Edit');
526
527
// Find specific user's card and interact with it
528
const janeCard = screen.getByText('Jane').closest('[data-testid="user-card"]');
529
const janeDeleteButton = within(janeCard).getByText('Delete');
530
```