0
# Tree Traversal and Search API
1
2
Powerful functions for traversing component trees and finding elements based on various criteria. These utilities enable comprehensive testing by allowing you to locate specific elements within complex component hierarchies.
3
4
## Tree Traversal Functions
5
6
### findAllInRenderedTree
7
8
```javascript { .api }
9
/**
10
* Traverses a rendered tree and finds all VNodes matching a predicate
11
* @param renderedTree - The rendered component tree (from renderIntoContainer or render)
12
* @param predicate - Function that returns true for matching VNodes
13
* @returns Array of VNodes where predicate returns true
14
*/
15
function findAllInRenderedTree(renderedTree: any, predicate: (vNode: VNode) => boolean): VNode[] | any
16
```
17
18
```javascript
19
import { findAllInRenderedTree, renderIntoContainer } from 'inferno-test-utils';
20
import { Component } from 'inferno';
21
22
class MyComponent extends Component {
23
render() {
24
return (
25
<div className="container">
26
<span>Hello</span>
27
<p>World</p>
28
</div>
29
);
30
}
31
}
32
33
const renderedTree = renderIntoContainer(<MyComponent />);
34
35
// Find all DOM elements with a specific tag
36
const spans = findAllInRenderedTree(renderedTree, (vnode) =>
37
vnode.type === 'span'
38
);
39
40
// Find all elements with specific props
41
const elementsWithClass = findAllInRenderedTree(renderedTree, (vnode) =>
42
vnode.props && vnode.props.className === 'container'
43
);
44
45
// Find all components of a specific type
46
const myComponents = findAllInRenderedTree(renderedTree, (vnode) =>
47
vnode.type === MyComponent
48
);
49
```
50
51
### findAllInVNodeTree
52
53
```javascript { .api }
54
/**
55
* Traverses a VNode tree and finds all VNodes matching a predicate
56
* @param vNodeTree - The VNode tree to traverse
57
* @param predicate - Function that returns true for matching VNodes
58
* @returns Array of VNodes where predicate returns true
59
*/
60
function findAllInVNodeTree(vNodeTree: VNode, predicate: (vNode: VNode) => boolean): any
61
```
62
63
```javascript
64
import { findAllInVNodeTree } from 'inferno-test-utils';
65
import { createElement } from 'inferno-create-element';
66
67
const vNodeTree = (
68
<div className="outer">
69
<MyComponent className="inner" />
70
<span>Text content</span>
71
</div>
72
);
73
74
// Find all VNodes with className prop
75
const withClassName = findAllInVNodeTree(vNodeTree, (vnode) =>
76
vnode.props && vnode.props.className
77
);
78
79
// Find all text elements
80
const textElements = findAllInVNodeTree(vNodeTree, (vnode) =>
81
vnode.type === 'span'
82
);
83
```
84
85
## Search Functions - Multiple Results (Scry)
86
87
These functions find multiple matching elements and return arrays. They never throw errors for multiple matches.
88
89
### DOM Element Search
90
91
```javascript { .api }
92
/**
93
* Finds all DOM elements with specified class names in a rendered tree
94
* @param renderedTree - The rendered component tree
95
* @param classNames - Space-separated class names string or array of class names
96
* @returns Array of DOM elements matching the class criteria
97
*/
98
function scryRenderedDOMElementsWithClass(renderedTree: any, classNames: string | string[]): Element[]
99
```
100
101
```javascript
102
import { scryRenderedDOMElementsWithClass, renderIntoContainer } from 'inferno-test-utils';
103
104
const vNodeTree = (
105
<div className="outer">
106
<div className="inner one">First</div>
107
<div className="inner two">Second</div>
108
<span className="inner">Third</span>
109
</div>
110
);
111
112
const renderedTree = renderIntoContainer(vNodeTree);
113
114
// Find all elements with 'inner' class
115
const innerElements = scryRenderedDOMElementsWithClass(renderedTree, 'inner');
116
console.log(innerElements.length); // 3
117
118
// Find elements with multiple classes (space-separated string)
119
const innerOneElements = scryRenderedDOMElementsWithClass(renderedTree, 'inner one');
120
console.log(innerOneElements.length); // 1
121
122
// Find elements with multiple classes (array)
123
const innerTwoElements = scryRenderedDOMElementsWithClass(renderedTree, ['inner', 'two']);
124
console.log(innerTwoElements.length); // 1
125
126
// No matches returns empty array
127
const nonexistent = scryRenderedDOMElementsWithClass(renderedTree, 'nonexistent');
128
console.log(nonexistent.length); // 0
129
```
130
131
```javascript { .api }
132
/**
133
* Finds all DOM elements with specified tag name in a rendered tree
134
* @param renderedTree - The rendered component tree
135
* @param tagName - HTML tag name to search for
136
* @returns Array of DOM elements with the specified tag name
137
*/
138
function scryRenderedDOMElementsWithTag(renderedTree: any, tagName: string): Element[]
139
```
140
141
```javascript
142
import { scryRenderedDOMElementsWithTag, renderIntoContainer } from 'inferno-test-utils';
143
144
const vNodeTree = (
145
<div>
146
<h1>Heading</h1>
147
<p>Paragraph One</p>
148
<p>Paragraph Two</p>
149
<p>Paragraph Three</p>
150
</div>
151
);
152
153
const renderedTree = renderIntoContainer(vNodeTree);
154
155
// Find all paragraph elements
156
const paragraphs = scryRenderedDOMElementsWithTag(renderedTree, 'p');
157
console.log(paragraphs.length); // 3
158
159
// Find all heading elements
160
const headings = scryRenderedDOMElementsWithTag(renderedTree, 'h1');
161
console.log(headings.length); // 1
162
163
// No matches returns empty array
164
const spans = scryRenderedDOMElementsWithTag(renderedTree, 'span');
165
console.log(spans.length); // 0
166
```
167
168
### VNode Search
169
170
```javascript { .api }
171
/**
172
* Finds all rendered VNodes of specified type in a rendered tree
173
* @param renderedTree - The rendered component tree
174
* @param type - Component type, function, or string to search for
175
* @returns Array of VNodes matching the specified type
176
*/
177
function scryRenderedVNodesWithType(renderedTree: any, type: unknown): VNode[]
178
```
179
180
```javascript
181
import { scryRenderedVNodesWithType, renderIntoContainer } from 'inferno-test-utils';
182
import { Component } from 'inferno';
183
184
class MyComponent extends Component {
185
render() { return <div>My Component</div>; }
186
}
187
188
function MyFunctionalComponent() {
189
return <div>Functional Component</div>;
190
}
191
192
const vNodeTree = (
193
<div>
194
<h1>Heading</h1>
195
<MyComponent />
196
<MyComponent />
197
<MyFunctionalComponent />
198
</div>
199
);
200
201
const renderedTree = renderIntoContainer(vNodeTree);
202
203
// Find all instances of MyComponent
204
const myComponents = scryRenderedVNodesWithType(renderedTree, MyComponent);
205
console.log(myComponents.length); // 2
206
207
// Find all h1 elements
208
const headings = scryRenderedVNodesWithType(renderedTree, 'h1');
209
console.log(headings.length); // 1
210
211
// Find functional components
212
const functionalComponents = scryRenderedVNodesWithType(renderedTree, MyFunctionalComponent);
213
console.log(functionalComponents.length); // 1
214
```
215
216
```javascript { .api }
217
/**
218
* Finds all VNodes of specified type in a VNode tree
219
* @param vNodeTree - The VNode tree to search
220
* @param type - Component type, function, or string to search for
221
* @returns Array of VNodes matching the specified type
222
*/
223
function scryVNodesWithType(vNodeTree: VNode, type: unknown): VNode[]
224
```
225
226
```javascript
227
import { scryVNodesWithType } from 'inferno-test-utils';
228
229
const vNodeTree = (
230
<div>
231
<h1>Heading</h1>
232
<MyComponent />
233
<MyComponent />
234
</div>
235
);
236
237
// Find all instances of MyComponent in the VNode tree
238
const myComponents = scryVNodesWithType(vNodeTree, MyComponent);
239
console.log(myComponents.length); // 2
240
241
// Find all h1 elements
242
const headings = scryVNodesWithType(vNodeTree, 'h1');
243
console.log(headings.length); // 1
244
```
245
246
## Find Functions - Single Results
247
248
These functions find exactly one matching element and throw errors if zero or multiple matches are found.
249
250
### DOM Element Finders
251
252
```javascript { .api }
253
/**
254
* Finds a single DOM element with specified class names in a rendered tree
255
* @param renderedTree - The rendered component tree
256
* @param classNames - Space-separated class names string or array of class names
257
* @returns Single DOM element matching the class criteria
258
* @throws Error if zero or multiple matches found
259
*/
260
function findRenderedDOMElementWithClass(renderedTree: any, classNames: string | string[]): Element
261
```
262
263
```javascript
264
import { findRenderedDOMElementWithClass, renderIntoContainer } from 'inferno-test-utils';
265
266
const vNodeTree = (
267
<div className="outer">
268
<div className="unique-class">Unique element</div>
269
<div className="inner">First inner</div>
270
<div className="inner">Second inner</div>
271
</div>
272
);
273
274
const renderedTree = renderIntoContainer(vNodeTree);
275
276
// Find single element - success
277
const uniqueElement = findRenderedDOMElementWithClass(renderedTree, 'unique-class');
278
console.log(uniqueElement.textContent); // "Unique element"
279
280
// Find single element - throws error due to multiple matches
281
try {
282
const innerElement = findRenderedDOMElementWithClass(renderedTree, 'inner');
283
} catch (error) {
284
console.log(error.message); // "Did not find exactly one match (found 2) for class: inner"
285
}
286
287
// Find single element - throws error due to no matches
288
try {
289
const nonexistent = findRenderedDOMElementWithClass(renderedTree, 'nonexistent');
290
} catch (error) {
291
console.log(error.message); // "Did not find exactly one match (found 0) for class: nonexistent"
292
}
293
```
294
295
```javascript { .api }
296
/**
297
* Finds a single DOM element with specified tag name in a rendered tree
298
* @param renderedTree - The rendered component tree
299
* @param tagName - HTML tag name to search for
300
* @returns Single DOM element with the specified tag name
301
* @throws Error if zero or multiple matches found
302
*/
303
function findRenderedDOMElementWithTag(renderedTree: any, tagName: string): Element
304
```
305
306
```javascript
307
import { findRenderedDOMElementWithTag, renderIntoContainer } from 'inferno-test-utils';
308
309
const vNodeTree = (
310
<div>
311
<h1>Unique heading</h1>
312
<p>First paragraph</p>
313
<p>Second paragraph</p>
314
</div>
315
);
316
317
const renderedTree = renderIntoContainer(vNodeTree);
318
319
// Find single h1 - success
320
const heading = findRenderedDOMElementWithTag(renderedTree, 'h1');
321
console.log(heading.textContent); // "Unique heading"
322
323
// Find single p - throws error due to multiple matches
324
try {
325
const paragraph = findRenderedDOMElementWithTag(renderedTree, 'p');
326
} catch (error) {
327
console.log(error.message); // "Did not find exactly one match (found 2) for tag: p"
328
}
329
```
330
331
### VNode Finders
332
333
```javascript { .api }
334
/**
335
* Finds a single rendered VNode of specified type in a rendered tree
336
* @param renderedTree - The rendered component tree
337
* @param type - Component type, function, or string to search for
338
* @returns Single VNode matching the specified type
339
* @throws Error if zero or multiple matches found
340
*/
341
function findRenderedVNodeWithType(renderedTree: any, type: unknown): VNode
342
```
343
344
```javascript
345
import { findRenderedVNodeWithType, renderIntoContainer } from 'inferno-test-utils';
346
import { Component } from 'inferno';
347
348
class UniqueComponent extends Component {
349
render() { return <div>Unique</div>; }
350
}
351
352
class CommonComponent extends Component {
353
render() { return <div>Common</div>; }
354
}
355
356
const vNodeTree = (
357
<div>
358
<UniqueComponent />
359
<CommonComponent />
360
<CommonComponent />
361
</div>
362
);
363
364
const renderedTree = renderIntoContainer(vNodeTree);
365
366
// Find single unique component - success
367
const uniqueComponent = findRenderedVNodeWithType(renderedTree, UniqueComponent);
368
console.log(uniqueComponent.type === UniqueComponent); // true
369
370
// Find common component - throws error due to multiple matches
371
try {
372
const commonComponent = findRenderedVNodeWithType(renderedTree, CommonComponent);
373
} catch (error) {
374
console.log(error.message); // "Did not find exactly one match (found 2) for component: CommonComponent"
375
}
376
```
377
378
```javascript { .api }
379
/**
380
* Finds a single VNode of specified type in a VNode tree
381
* @param vNodeTree - The VNode tree to search
382
* @param type - Component type, function, or string to search for
383
* @returns Single VNode matching the specified type
384
* @throws Error if zero or multiple matches found
385
*/
386
function findVNodeWithType(vNodeTree: VNode, type: unknown): VNode
387
```
388
389
```javascript
390
import { findVNodeWithType } from 'inferno-test-utils';
391
392
const vNodeTree = (
393
<div>
394
<h1>Unique heading</h1>
395
<UniqueComponent />
396
<CommonComponent />
397
<CommonComponent />
398
</div>
399
);
400
401
// Find single h1 - success
402
const heading = findVNodeWithType(vNodeTree, 'h1');
403
console.log(heading.type); // 'h1'
404
405
// Find unique component - success
406
const uniqueComponent = findVNodeWithType(vNodeTree, UniqueComponent);
407
console.log(uniqueComponent.type === UniqueComponent); // true
408
409
// Find common component - throws error due to multiple matches
410
try {
411
const commonComponent = findVNodeWithType(vNodeTree, CommonComponent);
412
} catch (error) {
413
console.log(error.message); // "Did not find exactly one match (found 2) for VNode: CommonComponent"
414
}
415
```
416
417
## Advanced Usage Patterns
418
419
### Custom Predicates
420
421
```javascript
422
import { findAllInRenderedTree, renderIntoContainer } from 'inferno-test-utils';
423
424
const renderedTree = renderIntoContainer(<MyComplexApp />);
425
426
// Find elements with specific props
427
const elementsWithId = findAllInRenderedTree(renderedTree, (vnode) =>
428
vnode.props && vnode.props.id
429
);
430
431
// Find elements with specific attributes
432
const buttonsWithDisabled = findAllInRenderedTree(renderedTree, (vnode) =>
433
vnode.type === 'button' && vnode.props && vnode.props.disabled
434
);
435
436
// Find components with specific state (for class components)
437
const componentsWithState = findAllInRenderedTree(renderedTree, (vnode) =>
438
vnode.children && vnode.children.state && vnode.children.state.isLoading
439
);
440
```
441
442
### Combining Search Functions
443
444
```javascript
445
import {
446
scryRenderedDOMElementsWithClass,
447
scryRenderedDOMElementsWithTag,
448
renderIntoContainer
449
} from 'inferno-test-utils';
450
451
const renderedTree = renderIntoContainer(<MyApp />);
452
453
// Get all buttons, then filter by class
454
const allButtons = scryRenderedDOMElementsWithTag(renderedTree, 'button');
455
const primaryButtons = scryRenderedDOMElementsWithClass(renderedTree, 'btn-primary');
456
const primaryButtonElements = allButtons.filter(btn =>
457
primaryButtons.includes(btn)
458
);
459
```
460
461
### Error Handling
462
463
```javascript
464
import { findRenderedDOMElementWithClass } from 'inferno-test-utils';
465
466
function findElementSafely(renderedTree, className) {
467
try {
468
return findRenderedDOMElementWithClass(renderedTree, className);
469
} catch (error) {
470
if (error.message.includes('Did not find exactly one match')) {
471
console.warn(`Multiple or no elements found with class: ${className}`);
472
return null;
473
}
474
throw error;
475
}
476
}
477
```