0
# Element Queries
1
2
Comprehensive system for finding elements in the rendered component tree using various strategies including text content, accessibility properties, test IDs, and component roles. All queries follow the getBy/getAllBy/queryBy/queryAllBy/findBy/findAllBy pattern.
3
4
## Query Types Overview
5
6
- **getBy***: Returns single element, throws if not found or multiple found
7
- **getAllBy***: Returns array of elements, throws if none found
8
- **queryBy***: Returns single element or null, doesn't throw
9
- **queryAllBy***: Returns array of elements (empty if none found), doesn't throw
10
- **findBy***: Async version of getBy* with waiting capability
11
- **findAllBy***: Async version of getAllBy* with waiting capability
12
13
## Capabilities
14
15
### Text Queries
16
17
Find elements by their text content - the most user-centric way to locate elements.
18
19
```typescript { .api }
20
/**
21
* Find elements by text content
22
* @param text - Text content to search for (string or RegExp)
23
* @param options - Text matching options
24
* @returns Single element or array of elements
25
*/
26
function getByText(text: string | RegExp, options?: TextMatchOptions): ReactTestInstance;
27
function getAllByText(text: string | RegExp, options?: TextMatchOptions): ReactTestInstance[];
28
function queryByText(text: string | RegExp, options?: TextMatchOptions): ReactTestInstance | null;
29
function queryAllByText(text: string | RegExp, options?: TextMatchOptions): ReactTestInstance[];
30
function findByText(text: string | RegExp, options?: TextMatchOptions & WaitForOptions): Promise<ReactTestInstance>;
31
function findAllByText(text: string | RegExp, options?: TextMatchOptions & WaitForOptions): Promise<ReactTestInstance[]>;
32
33
interface TextMatchOptions {
34
/** Whether to match exact text (default: true) */
35
exact?: boolean;
36
/** Function to normalize text before matching */
37
normalizer?: NormalizerFn;
38
/** Include elements hidden from accessibility (default: false) */
39
includeHiddenElements?: boolean;
40
}
41
42
type NormalizerFn = (text: string) => string;
43
```
44
45
**Usage Examples:**
46
47
```typescript
48
import { render, screen } from "@testing-library/react-native";
49
50
test("text queries", () => {
51
render(
52
<View>
53
<Text>Hello World</Text>
54
<Text>Welcome User</Text>
55
<Text>Submit</Text>
56
</View>
57
);
58
59
// Exact text match
60
const hello = screen.getByText("Hello World");
61
62
// Partial text match
63
const welcome = screen.getByText("Welcome", { exact: false });
64
65
// RegExp match
66
const submit = screen.getByText(/submit/i);
67
68
// Get all elements with text
69
const allTexts = screen.getAllByText(/Hello|Welcome/);
70
71
// Query without throwing
72
const missing = screen.queryByText("Not Found"); // returns null
73
74
// Async finding
75
const asyncText = await screen.findByText("Loaded Content");
76
});
77
```
78
79
### TestID Queries
80
81
Find elements by their testID prop - reliable for testing purposes.
82
83
```typescript { .api }
84
/**
85
* Find elements by testID prop
86
* @param testId - TestID to search for (string or RegExp)
87
* @param options - TestID matching options
88
* @returns Single element or array of elements
89
*/
90
function getByTestId(testId: string | RegExp, options?: TestIdOptions): ReactTestInstance;
91
function getAllByTestId(testId: string | RegExp, options?: TestIdOptions): ReactTestInstance[];
92
function queryByTestId(testId: string | RegExp, options?: TestIdOptions): ReactTestInstance | null;
93
function queryAllByTestId(testId: string | RegExp, options?: TestIdOptions): ReactTestInstance[];
94
function findByTestId(testId: string | RegExp, options?: TestIdOptions & WaitForOptions): Promise<ReactTestInstance>;
95
function findAllByTestId(testId: string | RegExp, options?: TestIdOptions & WaitForOptions): Promise<ReactTestInstance[]>;
96
97
interface TestIdOptions {
98
exact?: boolean;
99
normalizer?: NormalizerFn;
100
includeHiddenElements?: boolean;
101
}
102
```
103
104
**Usage Examples:**
105
106
```typescript
107
test("testID queries", () => {
108
render(
109
<View>
110
<Pressable testID="submit-button">
111
<Text>Submit</Text>
112
</Pressable>
113
<TextInput testID="email-input" placeholder="Email" />
114
<View testID="user-card-1">
115
<Text>User 1</Text>
116
</View>
117
</View>
118
);
119
120
// Find by exact testID
121
const button = screen.getByTestId("submit-button");
122
const input = screen.getByTestId("email-input");
123
124
// Find by RegExp
125
const userCard = screen.getByTestId(/user-card-\d+/);
126
127
// Get all matching testIDs
128
const allUserCards = screen.getAllByTestId(/user-card/);
129
});
130
```
131
132
### Role Queries
133
134
Find elements by their accessibility role - follows ARIA patterns adapted for React Native.
135
136
```typescript { .api }
137
/**
138
* Find elements by accessibility role
139
* @param role - Accessibility role to search for
140
* @param options - Role matching options
141
* @returns Single element or array of elements
142
*/
143
function getByRole(role: string, options?: RoleOptions): ReactTestInstance;
144
function getAllByRole(role: string, options?: RoleOptions): ReactTestInstance[];
145
function queryByRole(role: string, options?: RoleOptions): ReactTestInstance | null;
146
function queryAllByRole(role: string, options?: RoleOptions): ReactTestInstance[];
147
function findByRole(role: string, options?: RoleOptions & WaitForOptions): Promise<ReactTestInstance>;
148
function findAllByRole(role: string, options?: RoleOptions & WaitForOptions): Promise<ReactTestInstance[]>;
149
150
interface RoleOptions {
151
/** Filter by accessible name */
152
name?: string | RegExp;
153
/** Include elements hidden from accessibility */
154
includeHiddenElements?: boolean;
155
/** Whether to match name exactly */
156
exact?: boolean;
157
/** Function to normalize accessible name */
158
normalizer?: NormalizerFn;
159
}
160
```
161
162
**Usage Examples:**
163
164
```typescript
165
test("role queries", () => {
166
render(
167
<View>
168
<Pressable role="button" accessibilityLabel="Submit Form">
169
<Text>Submit</Text>
170
</Pressable>
171
<TextInput
172
role="textbox"
173
accessibilityLabel="Email Address"
174
placeholder="Email"
175
/>
176
<View role="alert">
177
<Text>Error: Invalid email</Text>
178
</View>
179
</View>
180
);
181
182
// Find by role
183
const button = screen.getByRole("button");
184
const textbox = screen.getByRole("textbox");
185
const alert = screen.getByRole("alert");
186
187
// Find by role with name
188
const submitButton = screen.getByRole("button", { name: "Submit Form" });
189
const emailInput = screen.getByRole("textbox", { name: /email/i });
190
191
// Get all buttons
192
const allButtons = screen.getAllByRole("button");
193
});
194
```
195
196
### Label Text Queries
197
198
Find elements by their accessibility label - essential for accessible testing.
199
200
```typescript { .api }
201
/**
202
* Find elements by accessibility label
203
* @param text - Label text to search for (string or RegExp)
204
* @param options - Label text matching options
205
* @returns Single element or array of elements
206
*/
207
function getByLabelText(text: string | RegExp, options?: LabelTextOptions): ReactTestInstance;
208
function getAllByLabelText(text: string | RegExp, options?: LabelTextOptions): ReactTestInstance[];
209
function queryByLabelText(text: string | RegExp, options?: LabelTextOptions): ReactTestInstance | null;
210
function queryAllByLabelText(text: string | RegExp, options?: LabelTextOptions): ReactTestInstance[];
211
function findByLabelText(text: string | RegExp, options?: LabelTextOptions & WaitForOptions): Promise<ReactTestInstance>;
212
function findAllByLabelText(text: string | RegExp, options?: LabelTextOptions & WaitForOptions): Promise<ReactTestInstance[]>;
213
214
interface LabelTextOptions {
215
exact?: boolean;
216
normalizer?: NormalizerFn;
217
includeHiddenElements?: boolean;
218
}
219
```
220
221
**Usage Examples:**
222
223
```typescript
224
test("label text queries", () => {
225
render(
226
<View>
227
<TextInput
228
accessibilityLabel="Email Address"
229
placeholder="Enter email"
230
/>
231
<Pressable accessibilityLabel="Submit Form">
232
<Text>Submit</Text>
233
</Pressable>
234
<Switch accessibilityLabel="Enable Notifications" />
235
</View>
236
);
237
238
// Find by accessibility label
239
const emailInput = screen.getByLabelText("Email Address");
240
const submitButton = screen.getByLabelText("Submit Form");
241
const toggle = screen.getByLabelText("Enable Notifications");
242
243
// Partial label match
244
const emailField = screen.getByLabelText("Email", { exact: false });
245
246
// RegExp match
247
const formButton = screen.getByLabelText(/submit/i);
248
});
249
```
250
251
### Hint Text Queries
252
253
Find elements by their accessibility hint with multiple aliases for convenience.
254
255
```typescript { .api }
256
/**
257
* Find elements by accessibility hint
258
* @param text - Hint text to search for (string or RegExp)
259
* @param options - Hint text matching options
260
* @returns Single element or array of elements
261
*/
262
function getByHintText(text: string | RegExp, options?: HintTextOptions): ReactTestInstance;
263
function getAllByHintText(text: string | RegExp, options?: HintTextOptions): ReactTestInstance[];
264
function queryByHintText(text: string | RegExp, options?: HintTextOptions): ReactTestInstance | null;
265
function queryAllByHintText(text: string | RegExp, options?: HintTextOptions): ReactTestInstance[];
266
function findByHintText(text: string | RegExp, options?: HintTextOptions & WaitForOptions): Promise<ReactTestInstance>;
267
function findAllByHintText(text: string | RegExp, options?: HintTextOptions & WaitForOptions): Promise<ReactTestInstance[]>;
268
269
// Convenience aliases
270
function getByA11yHint(text: string | RegExp, options?: HintTextOptions): ReactTestInstance;
271
function getAllByA11yHint(text: string | RegExp, options?: HintTextOptions): ReactTestInstance[];
272
function queryByA11yHint(text: string | RegExp, options?: HintTextOptions): ReactTestInstance | null;
273
function queryAllByA11yHint(text: string | RegExp, options?: HintTextOptions): ReactTestInstance[];
274
function findByA11yHint(text: string | RegExp, options?: HintTextOptions & WaitForOptions): Promise<ReactTestInstance>;
275
function findAllByA11yHint(text: string | RegExp, options?: HintTextOptions & WaitForOptions): Promise<ReactTestInstance[]>;
276
277
function getByAccessibilityHint(text: string | RegExp, options?: HintTextOptions): ReactTestInstance;
278
function getAllByAccessibilityHint(text: string | RegExp, options?: HintTextOptions): ReactTestInstance[];
279
function queryByAccessibilityHint(text: string | RegExp, options?: HintTextOptions): ReactTestInstance | null;
280
function queryAllByAccessibilityHint(text: string | RegExp, options?: HintTextOptions): ReactTestInstance[];
281
function findByAccessibilityHint(text: string | RegExp, options?: HintTextOptions & WaitForOptions): Promise<ReactTestInstance>;
282
function findAllByAccessibilityHint(text: string | RegExp, options?: HintTextOptions & WaitForOptions): Promise<ReactTestInstance[]>;
283
284
interface HintTextOptions {
285
exact?: boolean;
286
normalizer?: NormalizerFn;
287
includeHiddenElements?: boolean;
288
}
289
```
290
291
**Usage Examples:**
292
293
```typescript
294
test("hint text queries", () => {
295
render(
296
<View>
297
<TextInput
298
accessibilityHint="Enter your email address for login"
299
placeholder="Email"
300
/>
301
<Pressable accessibilityHint="Tap to submit the form">
302
<Text>Submit</Text>
303
</Pressable>
304
</View>
305
);
306
307
// All three forms are equivalent
308
const emailInput1 = screen.getByHintText("Enter your email address for login");
309
const emailInput2 = screen.getByA11yHint("Enter your email address for login");
310
const emailInput3 = screen.getByAccessibilityHint("Enter your email address for login");
311
312
// Partial hint match
313
const submitButton = screen.getByHintText("Tap to submit", { exact: false });
314
315
// RegExp match
316
const formButton = screen.getByHintText(/submit.*form/i);
317
});
318
```
319
320
### Placeholder Text Queries
321
322
Find form elements by their placeholder text.
323
324
```typescript { .api }
325
/**
326
* Find elements by placeholder text
327
* @param text - Placeholder text to search for (string or RegExp)
328
* @param options - Placeholder text matching options
329
* @returns Single element or array of elements
330
*/
331
function getByPlaceholderText(text: string | RegExp, options?: PlaceholderTextOptions): ReactTestInstance;
332
function getAllByPlaceholderText(text: string | RegExp, options?: PlaceholderTextOptions): ReactTestInstance[];
333
function queryByPlaceholderText(text: string | RegExp, options?: PlaceholderTextOptions): ReactTestInstance | null;
334
function queryAllByPlaceholderText(text: string | RegExp, options?: PlaceholderTextOptions): ReactTestInstance[];
335
function findByPlaceholderText(text: string | RegExp, options?: PlaceholderTextOptions & WaitForOptions): Promise<ReactTestInstance>;
336
function findAllByPlaceholderText(text: string | RegExp, options?: PlaceholderTextOptions & WaitForOptions): Promise<ReactTestInstance[]>;
337
338
interface PlaceholderTextOptions {
339
exact?: boolean;
340
normalizer?: NormalizerFn;
341
includeHiddenElements?: boolean;
342
}
343
```
344
345
**Usage Examples:**
346
347
```typescript
348
test("placeholder text queries", () => {
349
render(
350
<View>
351
<TextInput placeholder="Enter your email" />
352
<TextInput placeholder="Password" />
353
<TextInput placeholder="Search users..." />
354
</View>
355
);
356
357
// Find by exact placeholder
358
const emailInput = screen.getByPlaceholderText("Enter your email");
359
const passwordInput = screen.getByPlaceholderText("Password");
360
361
// Partial match
362
const searchInput = screen.getByPlaceholderText("Search", { exact: false });
363
364
// RegExp match
365
const userSearch = screen.getByPlaceholderText(/search.*users/i);
366
367
// Get all inputs with placeholders
368
const allInputs = screen.getAllByPlaceholderText(/.+/);
369
});
370
```
371
372
### Display Value Queries
373
374
Find form elements by their current display value.
375
376
```typescript { .api }
377
/**
378
* Find elements by their current display value
379
* @param value - Display value to search for (string or RegExp)
380
* @param options - Display value matching options
381
* @returns Single element or array of elements
382
*/
383
function getByDisplayValue(value: string | RegExp, options?: DisplayValueOptions): ReactTestInstance;
384
function getAllByDisplayValue(value: string | RegExp, options?: DisplayValueOptions): ReactTestInstance[];
385
function queryByDisplayValue(value: string | RegExp, options?: DisplayValueOptions): ReactTestInstance | null;
386
function queryAllByDisplayValue(value: string | RegExp, options?: DisplayValueOptions): ReactTestInstance[];
387
function findByDisplayValue(value: string | RegExp, options?: DisplayValueOptions & WaitForOptions): Promise<ReactTestInstance>;
388
function findAllByDisplayValue(value: string | RegExp, options?: DisplayValueOptions & WaitForOptions): Promise<ReactTestInstance[]>;
389
390
interface DisplayValueOptions {
391
exact?: boolean;
392
normalizer?: NormalizerFn;
393
includeHiddenElements?: boolean;
394
}
395
```
396
397
**Usage Examples:**
398
399
```typescript
400
test("display value queries", () => {
401
render(
402
<View>
403
<TextInput value="john@example.com" />
404
<TextInput value="123-456-7890" />
405
<Text>Current User: John Doe</Text>
406
</View>
407
);
408
409
// Find by exact value
410
const emailInput = screen.getByDisplayValue("john@example.com");
411
const phoneInput = screen.getByDisplayValue("123-456-7890");
412
413
// Find text by display value
414
const userText = screen.getByDisplayValue("Current User: John Doe");
415
416
// Partial match
417
const emailField = screen.getByDisplayValue("john", { exact: false });
418
419
// RegExp match
420
const phoneField = screen.getByDisplayValue(/\d{3}-\d{3}-\d{4}/);
421
});
422
```
423
424
### Unsafe Queries (Advanced)
425
426
Advanced queries for finding elements by component type or props - use with caution as they test implementation details.
427
428
```typescript { .api }
429
/**
430
* Find elements by component type - UNSAFE: tests implementation details
431
* @param type - Component type or string
432
* @param options - Type matching options
433
* @returns Single element or array of elements
434
*/
435
function UNSAFE_getByType(type: React.ComponentType | string, options?: TypeOptions): ReactTestInstance;
436
function UNSAFE_getAllByType(type: React.ComponentType | string, options?: TypeOptions): ReactTestInstance[];
437
function UNSAFE_queryByType(type: React.ComponentType | string, options?: TypeOptions): ReactTestInstance | null;
438
function UNSAFE_queryAllByType(type: React.ComponentType | string, options?: TypeOptions): ReactTestInstance[];
439
440
/**
441
* Find elements by props - UNSAFE: tests implementation details
442
* @param props - Props object to match
443
* @param options - Props matching options
444
* @returns Single element or array of elements
445
*/
446
function UNSAFE_getByProps(props: object, options?: PropsOptions): ReactTestInstance;
447
function UNSAFE_getAllByProps(props: object, options?: PropsOptions): ReactTestInstance[];
448
function UNSAFE_queryByProps(props: object, options?: PropsOptions): ReactTestInstance | null;
449
function UNSAFE_queryAllByProps(props: object, options?: PropsOptions): ReactTestInstance[];
450
451
interface TypeOptions {
452
includeHiddenElements?: boolean;
453
}
454
455
interface PropsOptions {
456
includeHiddenElements?: boolean;
457
}
458
```
459
460
**Usage Examples (Use Sparingly):**
461
462
```typescript
463
import { View, Text, TextInput } from "react-native";
464
465
test("unsafe queries - use with caution", () => {
466
render(
467
<View>
468
<TextInput style={{ fontSize: 16 }} />
469
<Text>Hello</Text>
470
<MyCustomComponent customProp="value" />
471
</View>
472
);
473
474
// Find by component type
475
const textInput = screen.UNSAFE_getByType(TextInput);
476
const textElement = screen.UNSAFE_getByType(Text);
477
const customComponent = screen.UNSAFE_getByType(MyCustomComponent);
478
479
// Find by props
480
const styledInput = screen.UNSAFE_getByProps({ style: { fontSize: 16 } });
481
const customPropComponent = screen.UNSAFE_getByProps({ customProp: "value" });
482
483
// Get all of specific type
484
const allTexts = screen.UNSAFE_getAllByType(Text);
485
});
486
```
487
488
## Within - Scoped Queries
489
490
Scope queries to a specific element subtree for more targeted testing.
491
492
```typescript { .api }
493
/**
494
* Create scoped queries for a specific element
495
* @param element - Element to scope queries to
496
* @returns Object with all query methods scoped to the element
497
*/
498
function within(element: ReactTestInstance): BoundQueries;
499
function getQueriesForElement(element: ReactTestInstance): BoundQueries; // Alias
500
501
interface BoundQueries {
502
// All the same query methods as screen/render result
503
// but scoped to the provided element
504
getByText: (text: string | RegExp, options?: TextMatchOptions) => ReactTestInstance;
505
getAllByText: (text: string | RegExp, options?: TextMatchOptions) => ReactTestInstance[];
506
// ... all other query methods
507
}
508
```
509
510
**Usage Examples:**
511
512
```typescript
513
import { render, screen, within } from "@testing-library/react-native";
514
515
test("scoped queries with within", () => {
516
render(
517
<View>
518
<View testID="user-card-1">
519
<Text>John Doe</Text>
520
<Text>john@example.com</Text>
521
<Pressable>
522
<Text>Edit</Text>
523
</Pressable>
524
</View>
525
<View testID="user-card-2">
526
<Text>Jane Smith</Text>
527
<Text>jane@example.com</Text>
528
<Pressable>
529
<Text>Edit</Text>
530
</Pressable>
531
</View>
532
</View>
533
);
534
535
// Scope queries to first user card
536
const userCard1 = screen.getByTestId("user-card-1");
537
const withinCard1 = within(userCard1);
538
539
// Find elements only within the first card
540
const johnName = withinCard1.getByText("John Doe");
541
const johnEmail = withinCard1.getByText("john@example.com");
542
const johnEditButton = withinCard1.getByText("Edit");
543
544
// Scope to second card
545
const userCard2 = screen.getByTestId("user-card-2");
546
const janeEditButton = within(userCard2).getByText("Edit");
547
});
548
```
549
550
## Query Options and Configuration
551
552
Common options and utilities used across all query types.
553
554
```typescript { .api }
555
/**
556
* Get default text normalizer function
557
* @returns Default normalizer that trims whitespace and collapses spaces
558
*/
559
function getDefaultNormalizer(): NormalizerFn;
560
561
// Common interfaces used across queries
562
interface WaitForOptions {
563
/** Timeout in milliseconds (default from config) */
564
timeout?: number;
565
/** Polling interval in milliseconds (default: 50) */
566
interval?: number;
567
/** Custom timeout error handler */
568
onTimeout?: (error: Error) => Error;
569
}
570
571
type NormalizerFn = (text: string) => string;
572
```
573
574
**Usage Examples:**
575
576
```typescript
577
import { getDefaultNormalizer } from "@testing-library/react-native";
578
579
test("custom text normalization", () => {
580
const customNormalizer = (text: string) =>
581
text.toLowerCase().replace(/\s+/g, " ").trim();
582
583
render(<Text> Hello World </Text>);
584
585
// Using custom normalizer
586
const text = screen.getByText("hello world", {
587
exact: false,
588
normalizer: customNormalizer
589
});
590
591
// Using default normalizer explicitly
592
const defaultNormalizer = getDefaultNormalizer();
593
const text2 = screen.getByText("Hello World", {
594
normalizer: defaultNormalizer
595
});
596
});
597
```