0
# Rendering Utilities API
1
2
Utilities for rendering components into test environments and working with VNodes in testing scenarios. These functions provide the foundation for setting up test environments and extracting useful information from rendered components.
3
4
## Rendering Functions
5
6
### renderIntoContainer
7
8
```javascript { .api }
9
/**
10
* Renders input into a detached DOM container and returns the rendered tree
11
* @param input - VNode, component, or other renderable content to render
12
* @returns Rendered component tree or VNode suitable for testing
13
*/
14
function renderIntoContainer(input: boolean | VNode | InfernoChild | InfernoFragment | null | undefined): Component<any, any> | VNode
15
```
16
17
This is the primary function for setting up test environments. It creates a detached DOM element, renders your component into it, and returns the rendered tree for testing.
18
19
```javascript
20
import { renderIntoContainer } from 'inferno-test-utils';
21
import { Component } from 'inferno';
22
23
// Simple DOM element rendering
24
const simpleVNode = <div className="test">Hello World</div>;
25
const renderedSimple = renderIntoContainer(simpleVNode);
26
27
// Component rendering
28
class TestComponent extends Component {
29
constructor(props) {
30
super(props);
31
this.state = { count: 0 };
32
}
33
34
render() {
35
return (
36
<div className="component">
37
<p>Count: {this.state.count}</p>
38
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
39
Increment
40
</button>
41
</div>
42
);
43
}
44
}
45
46
const renderedComponent = renderIntoContainer(<TestComponent />);
47
48
// Functional component rendering
49
function FunctionalComponent({ name }) {
50
return <div className="functional">Hello {name}</div>;
51
}
52
53
const renderedFunctional = renderIntoContainer(<FunctionalComponent name="World" />);
54
55
// Complex nested structure
56
const complexVNode = (
57
<div className="app">
58
<header>
59
<h1>My App</h1>
60
</header>
61
<main>
62
<TestComponent />
63
<FunctionalComponent name="User" />
64
</main>
65
</div>
66
);
67
68
const renderedComplex = renderIntoContainer(complexVNode);
69
```
70
71
### Return Value Behavior
72
73
The function returns different types based on what was rendered:
74
75
```javascript
76
import { renderIntoContainer, isRenderedClassComponent } from 'inferno-test-utils';
77
import { Component } from 'inferno';
78
79
class MyClassComponent extends Component {
80
render() { return <div>Class Component</div>; }
81
}
82
83
function MyFunctionalComponent() {
84
return <div>Functional Component</div>;
85
}
86
87
// Class component returns the component instance
88
const classResult = renderIntoContainer(<MyClassComponent />);
89
console.log(isRenderedClassComponent(classResult)); // true
90
91
// Functional component returns the VNode
92
const functionalResult = renderIntoContainer(<MyFunctionalComponent />);
93
console.log(isRenderedClassComponent(functionalResult)); // false
94
95
// DOM element returns the VNode
96
const domResult = renderIntoContainer(<div>DOM Element</div>);
97
console.log(isRenderedClassComponent(domResult)); // false
98
```
99
100
### Working with Props and State
101
102
```javascript
103
import { renderIntoContainer, findRenderedDOMElementWithTag, isRenderedClassComponent } from 'inferno-test-utils';
104
import { Component } from 'inferno';
105
106
class StatefulComponent extends Component {
107
constructor(props) {
108
super(props);
109
this.state = { isVisible: props.initialVisible || false };
110
}
111
112
toggle = () => {
113
this.setState({ isVisible: !this.state.isVisible });
114
}
115
116
render() {
117
return (
118
<div>
119
<button onClick={this.toggle}>Toggle</button>
120
{this.state.isVisible && <p>Visible content</p>}
121
</div>
122
);
123
}
124
}
125
126
// Render with props
127
const rendered = renderIntoContainer(<StatefulComponent initialVisible={true} />);
128
129
// Access the component instance (for class components)
130
if (isRenderedClassComponent(rendered)) {
131
console.log(rendered.state.isVisible); // true
132
console.log(rendered.props.initialVisible); // true
133
134
// Trigger state changes
135
rendered.toggle();
136
console.log(rendered.state.isVisible); // false
137
}
138
139
// Find elements in the rendered output
140
const button = findRenderedDOMElementWithTag(rendered, 'button');
141
console.log(button.textContent); // "Toggle"
142
```
143
144
## Utility Functions
145
146
### getTagNameOfVNode
147
148
```javascript { .api }
149
/**
150
* Gets the lowercase tag name of a DOM VNode
151
* @param vNode - VNode representing a DOM element
152
* @returns Lowercase tag name of the DOM element, or undefined if not a DOM VNode
153
*/
154
function getTagNameOfVNode(vNode: VNode): string | undefined
155
```
156
157
```javascript
158
import { getTagNameOfVNode, scryRenderedVNodesWithType, renderIntoContainer } from 'inferno-test-utils';
159
160
const vNodeTree = (
161
<div>
162
<h1>Heading</h1>
163
<p>Paragraph</p>
164
<button>Button</button>
165
</div>
166
);
167
168
const rendered = renderIntoContainer(vNodeTree);
169
170
// Find all DOM VNodes and get their tag names
171
const h1VNodes = scryRenderedVNodesWithType(rendered, 'h1');
172
const pVNodes = scryRenderedVNodesWithType(rendered, 'p');
173
const buttonVNodes = scryRenderedVNodesWithType(rendered, 'button');
174
175
console.log(getTagNameOfVNode(h1VNodes[0])); // "h1"
176
console.log(getTagNameOfVNode(pVNodes[0])); // "p"
177
console.log(getTagNameOfVNode(buttonVNodes[0])); // "button"
178
179
// Returns undefined for non-DOM VNodes
180
function MyComponent() { return <div />; }
181
const componentVNodes = scryRenderedVNodesWithType(rendered, MyComponent);
182
console.log(getTagNameOfVNode(componentVNodes[0])); // undefined
183
```
184
185
## Test Wrapper Component
186
187
### Wrapper Class
188
189
```javascript { .api }
190
/**
191
* Test wrapper component that renders its children
192
* Useful for wrapping components that need a parent context
193
*/
194
class Wrapper<P, S> extends Component<P, S> {
195
public render(): InfernoNode
196
}
197
```
198
199
The Wrapper component is primarily used internally but can be useful for testing scenarios where you need to wrap components.
200
201
```javascript
202
import { Wrapper, renderIntoContainer, findRenderedDOMElementWithClass, findRenderedDOMElementWithTag } from 'inferno-test-utils';
203
import { Component } from 'inferno';
204
205
// Custom wrapper usage
206
class TestWrapper extends Wrapper {
207
render() {
208
return (
209
<div className="test-wrapper">
210
{this.props.children}
211
</div>
212
);
213
}
214
}
215
216
function MyComponent() {
217
return <p>Component content</p>;
218
}
219
220
// Wrap component for testing
221
const wrappedComponent = (
222
<TestWrapper>
223
<MyComponent />
224
</TestWrapper>
225
);
226
227
const rendered = renderIntoContainer(wrappedComponent);
228
229
// The wrapper provides additional structure for testing
230
const wrapperDiv = findRenderedDOMElementWithClass(rendered, 'test-wrapper');
231
const componentP = findRenderedDOMElementWithTag(rendered, 'p');
232
console.log(componentP.textContent); // "Component content"
233
```
234
235
## Advanced Rendering Patterns
236
237
### Testing with Context
238
239
```javascript
240
import { renderIntoContainer, findRenderedVNodeWithType } from 'inferno-test-utils';
241
import { Component, createContext } from 'inferno';
242
243
const ThemeContext = createContext('light');
244
245
class ThemedComponent extends Component {
246
static contextType = ThemeContext;
247
248
render() {
249
return <div className={`theme-${this.context}`}>Themed content</div>;
250
}
251
}
252
253
// Render with context provider
254
const rendered = renderIntoContainer(
255
<ThemeContext.Provider value="dark">
256
<ThemedComponent />
257
</ThemeContext.Provider>
258
);
259
260
const themedComponent = findRenderedVNodeWithType(rendered, ThemedComponent);
261
// Test that the component received the correct context
262
```
263
264
### Testing with Refs
265
266
```javascript
267
import { renderIntoContainer, findRenderedDOMElementWithTag, isRenderedClassComponent } from 'inferno-test-utils';
268
import { Component, createRef } from 'inferno';
269
270
class ComponentWithRef extends Component {
271
constructor(props) {
272
super(props);
273
this.inputRef = createRef();
274
}
275
276
focus = () => {
277
this.inputRef.current.focus();
278
}
279
280
render() {
281
return (
282
<div>
283
<input ref={this.inputRef} type="text" />
284
<button onClick={this.focus}>Focus Input</button>
285
</div>
286
);
287
}
288
}
289
290
const rendered = renderIntoContainer(<ComponentWithRef />);
291
292
// Access the component instance to test ref functionality
293
if (isRenderedClassComponent(rendered)) {
294
const input = findRenderedDOMElementWithTag(rendered, 'input');
295
296
// Test that ref is properly assigned
297
console.log(rendered.inputRef.current === input); // true
298
299
// Test ref functionality
300
rendered.focus();
301
console.log(document.activeElement === input); // true
302
}
303
```
304
305
### Testing Event Handlers
306
307
```javascript
308
import { renderIntoContainer, findRenderedDOMElementWithTag, isRenderedClassComponent } from 'inferno-test-utils';
309
import { Component } from 'inferno';
310
311
class ClickableComponent extends Component {
312
constructor(props) {
313
super(props);
314
this.state = { clicked: false };
315
}
316
317
handleClick = () => {
318
this.setState({ clicked: true });
319
if (this.props.onClick) {
320
this.props.onClick();
321
}
322
}
323
324
render() {
325
return (
326
<button onClick={this.handleClick}>
327
{this.state.clicked ? 'Clicked!' : 'Click me'}
328
</button>
329
);
330
}
331
}
332
333
// Test with mock callback
334
let callbackCalled = false;
335
const mockCallback = () => { callbackCalled = true; };
336
337
const rendered = renderIntoContainer(<ClickableComponent onClick={mockCallback} />);
338
const button = findRenderedDOMElementWithTag(rendered, 'button');
339
340
// Simulate click
341
button.click();
342
343
// Check that state updated and callback was called
344
if (isRenderedClassComponent(rendered)) {
345
console.log(rendered.state.clicked); // true
346
}
347
console.log(callbackCalled); // true
348
console.log(button.textContent); // "Clicked!"
349
```
350
351
## Integration with DOM Testing
352
353
```javascript
354
import { renderIntoContainer, scryRenderedDOMElementsWithTag, findRenderedDOMElementWithTag } from 'inferno-test-utils';
355
356
function FormComponent() {
357
return (
358
<form>
359
<input name="username" type="text" />
360
<input name="password" type="password" />
361
<button type="submit">Submit</button>
362
</form>
363
);
364
}
365
366
const rendered = renderIntoContainer(<FormComponent />);
367
368
// Get all form inputs
369
const inputs = scryRenderedDOMElementsWithTag(rendered, 'input');
370
371
// Test form interactions
372
inputs[0].value = 'testuser';
373
inputs[1].value = 'testpass';
374
375
console.log(inputs[0].value); // "testuser"
376
console.log(inputs[1].value); // "testpass"
377
378
// Test form submission
379
const form = findRenderedDOMElementWithTag(rendered, 'form');
380
const submitEvent = new Event('submit');
381
form.dispatchEvent(submitEvent);
382
```