0
# Tree Traversal
1
2
ReactTestInstance methods for navigating and searching the rendered component tree. These methods are essential for making assertions about rendered components and their structure.
3
4
## Capabilities
5
6
### ReactTestInstance Class
7
8
The ReactTestInstance class represents a node in the rendered component tree and provides methods for traversal and searching.
9
10
```javascript { .api }
11
/**
12
* Represents a node in the rendered component tree
13
*/
14
class ReactTestInstance {
15
/** The component type or HTML tag name */
16
readonly type: any;
17
/** Props passed to the component */
18
readonly props: object;
19
/** Parent test instance, null for root */
20
readonly parent: ReactTestInstance | null;
21
/** Array of child test instances and text nodes */
22
readonly children: Array<ReactTestInstance | string>;
23
/** The underlying component instance (for class components) */
24
readonly instance: any;
25
}
26
```
27
28
### Properties
29
30
#### type Property
31
32
The component type or HTML tag name.
33
34
```javascript { .api }
35
/**
36
* The component type or HTML tag name
37
* - For DOM elements: string (e.g., 'div', 'span')
38
* - For React components: the component function/class
39
*/
40
readonly type: any;
41
```
42
43
**Usage Examples:**
44
45
```javascript
46
const component = create(
47
<div>
48
<MyComponent />
49
<span>Text</span>
50
</div>
51
);
52
53
const root = component.root;
54
console.log(root.type); // 'div'
55
56
const myComponent = root.findByType(MyComponent);
57
console.log(myComponent.type === MyComponent); // true
58
59
const span = root.findByType('span');
60
console.log(span.type); // 'span'
61
```
62
63
#### props Property
64
65
Props passed to the component.
66
67
```javascript { .api }
68
/**
69
* Props passed to the component
70
* - Excludes 'children' prop for consistency
71
* - Returns current props for the component
72
*/
73
readonly props: object;
74
```
75
76
**Usage Examples:**
77
78
```javascript
79
const component = create(
80
<button className="primary" disabled onClick={() => {}}>
81
Click me
82
</button>
83
);
84
85
const button = component.root.findByType('button');
86
console.log(button.props.className); // 'primary'
87
console.log(button.props.disabled); // true
88
console.log(typeof button.props.onClick); // 'function'
89
```
90
91
#### parent Property
92
93
Parent test instance in the tree hierarchy.
94
95
```javascript { .api }
96
/**
97
* Parent test instance, null for root elements
98
*/
99
readonly parent: ReactTestInstance | null;
100
```
101
102
#### children Property
103
104
Array of child test instances and text nodes.
105
106
```javascript { .api }
107
/**
108
* Array of child test instances and text nodes
109
* - Test instances for React components and DOM elements
110
* - Strings for text nodes
111
*/
112
readonly children: Array<ReactTestInstance | string>;
113
```
114
115
**Usage Examples:**
116
117
```javascript
118
const component = create(
119
<div>
120
<span>Hello</span>
121
World
122
<button>Click</button>
123
</div>
124
);
125
126
const root = component.root;
127
console.log(root.children.length); // 3
128
console.log(root.children[0].type); // 'span' (ReactTestInstance)
129
console.log(root.children[1]); // 'World' (string)
130
console.log(root.children[2].type); // 'button' (ReactTestInstance)
131
```
132
133
#### instance Property
134
135
The underlying component instance.
136
137
```javascript { .api }
138
/**
139
* The underlying component instance
140
* - For class components: the component instance
141
* - For function components: null
142
* - For DOM elements: the mock or actual DOM node
143
*/
144
readonly instance: any;
145
```
146
147
### Search Methods
148
149
#### find Method
150
151
Finds a single matching descendant using a predicate function.
152
153
```javascript { .api }
154
/**
155
* Finds a single matching descendant using a predicate function
156
* @param predicate - Function that returns true for the target node
157
* @returns Single matching ReactTestInstance
158
* @throws Error if no matches or multiple matches found
159
*/
160
find(predicate: (node: ReactTestInstance) => boolean): ReactTestInstance;
161
```
162
163
**Usage Examples:**
164
165
```javascript
166
const component = create(
167
<div>
168
<button id="save">Save</button>
169
<button id="cancel">Cancel</button>
170
</div>
171
);
172
173
// Find by custom logic
174
const saveButton = component.root.find(node =>
175
node.type === 'button' && node.props.id === 'save'
176
);
177
178
// Find by text content
179
const cancelButton = component.root.find(node =>
180
node.type === 'button' &&
181
node.children.includes('Cancel')
182
);
183
```
184
185
#### findByType Method
186
187
Finds a single descendant by component type or tag name.
188
189
```javascript { .api }
190
/**
191
* Finds a single descendant by component type or tag name
192
* @param type - Component type or HTML tag name to search for
193
* @returns Single matching ReactTestInstance
194
* @throws Error if no matches or multiple matches found
195
*/
196
findByType(type: any): ReactTestInstance;
197
```
198
199
**Usage Examples:**
200
201
```javascript
202
const component = create(
203
<div>
204
<MyComponent />
205
<button>Click</button>
206
</div>
207
);
208
209
// Find React component
210
const myComponent = component.root.findByType(MyComponent);
211
212
// Find DOM element
213
const button = component.root.findByType('button');
214
215
// Will throw if multiple buttons exist
216
// const button = component.root.findByType('button'); // Error!
217
```
218
219
#### findByProps Method
220
221
Finds a single descendant by matching props.
222
223
```javascript { .api }
224
/**
225
* Finds a single descendant by matching props
226
* @param props - Object with props to match (partial matching)
227
* @returns Single matching ReactTestInstance
228
* @throws Error if no matches or multiple matches found
229
*/
230
findByProps(props: object): ReactTestInstance;
231
```
232
233
**Usage Examples:**
234
235
```javascript
236
const component = create(
237
<form>
238
<input type="text" name="username" />
239
<input type="password" name="password" />
240
<button type="submit" disabled>Submit</button>
241
</form>
242
);
243
244
// Find by single prop
245
const usernameInput = component.root.findByProps({ name: 'username' });
246
247
// Find by multiple props
248
const submitButton = component.root.findByProps({
249
type: 'submit',
250
disabled: true
251
});
252
```
253
254
#### findAll Method
255
256
Finds all matching descendants using a predicate function.
257
258
```javascript { .api }
259
/**
260
* Finds all matching descendants using a predicate function
261
* @param predicate - Function that returns true for target nodes
262
* @param options - Search options (deep search by default)
263
* @returns Array of matching ReactTestInstance objects
264
*/
265
findAll(
266
predicate: (node: ReactTestInstance) => boolean,
267
options?: FindOptions
268
): Array<ReactTestInstance>;
269
270
interface FindOptions {
271
/** Whether to search deeply into the tree (default: true) */
272
deep?: boolean;
273
}
274
```
275
276
**Usage Examples:**
277
278
```javascript
279
const component = create(
280
<div>
281
<button>Save</button>
282
<div>
283
<button>Cancel</button>
284
<button disabled>Delete</button>
285
</div>
286
</div>
287
);
288
289
// Find all buttons
290
const allButtons = component.root.findAll(node => node.type === 'button');
291
console.log(allButtons.length); // 3
292
293
// Find only direct children (shallow search)
294
const directChildren = component.root.findAll(
295
node => node.type === 'button',
296
{ deep: false }
297
);
298
console.log(directChildren.length); // 1
299
300
// Find buttons with specific attributes
301
const enabledButtons = component.root.findAll(node =>
302
node.type === 'button' && !node.props.disabled
303
);
304
console.log(enabledButtons.length); // 2
305
```
306
307
#### findAllByType Method
308
309
Finds all descendants by component type or tag name.
310
311
```javascript { .api }
312
/**
313
* Finds all descendants by component type or tag name
314
* @param type - Component type or HTML tag name to search for
315
* @param options - Search options (deep search by default)
316
* @returns Array of matching ReactTestInstance objects
317
*/
318
findAllByType(type: any, options?: FindOptions): Array<ReactTestInstance>;
319
```
320
321
**Usage Examples:**
322
323
```javascript
324
const component = create(
325
<form>
326
<input type="text" />
327
<div>
328
<input type="password" />
329
<input type="hidden" value="csrf" />
330
</div>
331
</form>
332
);
333
334
// Find all input elements
335
const allInputs = component.root.findAllByType('input');
336
console.log(allInputs.length); // 3
337
338
// Find only direct input children
339
const directInputs = component.root.findAllByType('input', { deep: false });
340
console.log(directInputs.length); // 1
341
342
// Find all instances of a React component
343
const allMyComponents = component.root.findAllByType(MyComponent);
344
```
345
346
#### findAllByProps Method
347
348
Finds all descendants by matching props.
349
350
```javascript { .api }
351
/**
352
* Finds all descendants by matching props
353
* @param props - Object with props to match (partial matching)
354
* @param options - Search options (deep search by default)
355
* @returns Array of matching ReactTestInstance objects
356
*/
357
findAllByProps(props: object, options?: FindOptions): Array<ReactTestInstance>;
358
```
359
360
**Usage Examples:**
361
362
```javascript
363
const component = create(
364
<div>
365
<button type="button" className="btn">Save</button>
366
<button type="button" className="btn secondary">Cancel</button>
367
<button type="submit" className="btn primary">Submit</button>
368
</div>
369
);
370
371
// Find all buttons with specific type
372
const typeButtons = component.root.findAllByProps({ type: 'button' });
373
console.log(typeButtons.length); // 2
374
375
// Find all elements with specific class (partial match)
376
const btnElements = component.root.findAllByProps({ className: 'btn' });
377
console.log(btnElements.length); // 3 (partial matching)
378
379
// Find with multiple props
380
const primaryButtons = component.root.findAllByProps({
381
type: 'submit',
382
className: 'btn primary'
383
});
384
console.log(primaryButtons.length); // 1
385
```
386
387
## Types
388
389
### Predicate Type
390
391
Function type for search predicates.
392
393
```javascript { .api }
394
/**
395
* Function type for search predicates
396
* @param node - ReactTestInstance to test
397
* @returns true if node matches, false otherwise
398
*/
399
type Predicate = (node: ReactTestInstance) => boolean | null;
400
```
401
402
### FindOptions Interface
403
404
Options for controlling search behavior.
405
406
```javascript { .api }
407
/**
408
* Options for controlling search behavior
409
*/
410
interface FindOptions {
411
/** Whether to search deeply into the tree (default: true) */
412
deep?: boolean;
413
}
414
```
415
416
## Error Handling
417
418
### Common Search Errors
419
420
The find methods throw specific errors when searches don't match expectations:
421
422
```javascript
423
// Single find methods throw when no matches found
424
try {
425
component.root.findByType('nonexistent');
426
} catch (error) {
427
console.log(error.message); // "No instances found with node type: "nonexistent""
428
}
429
430
// Single find methods throw when multiple matches found
431
try {
432
component.root.findByType('button'); // when multiple buttons exist
433
} catch (error) {
434
console.log(error.message); // "Expected 1 but found 3 instances with node type: "button""
435
}
436
```
437
438
### Error Types
439
440
Common error messages from search methods:
441
442
- **"No instances found [criteria]"**: No matching nodes found
443
- **"Expected 1 but found N instances [criteria]"**: Multiple matches when expecting single result
444
- **"Can't read from currently-mounting component. This error is likely caused by a bug in React. Please file an issue."**: Component accessed during mount
445
- **Invalid predicate errors**: When predicate function throws or returns invalid values