Suite of utilities for testing Inferno applications with comprehensive tree traversal, element finding, and Jest snapshot integration.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
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.
/**
* Renders input into a detached DOM container and returns the rendered tree
* @param input - VNode, component, or other renderable content to render
* @returns Rendered component tree or VNode suitable for testing
*/
function renderIntoContainer(input: boolean | VNode | InfernoChild | InfernoFragment | null | undefined): Component<any, any> | VNodeThis 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.
import { renderIntoContainer } from 'inferno-test-utils';
import { Component } from 'inferno';
// Simple DOM element rendering
const simpleVNode = <div className="test">Hello World</div>;
const renderedSimple = renderIntoContainer(simpleVNode);
// Component rendering
class TestComponent extends Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
render() {
return (
<div className="component">
<p>Count: {this.state.count}</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Increment
</button>
</div>
);
}
}
const renderedComponent = renderIntoContainer(<TestComponent />);
// Functional component rendering
function FunctionalComponent({ name }) {
return <div className="functional">Hello {name}</div>;
}
const renderedFunctional = renderIntoContainer(<FunctionalComponent name="World" />);
// Complex nested structure
const complexVNode = (
<div className="app">
<header>
<h1>My App</h1>
</header>
<main>
<TestComponent />
<FunctionalComponent name="User" />
</main>
</div>
);
const renderedComplex = renderIntoContainer(complexVNode);The function returns different types based on what was rendered:
import { renderIntoContainer, isRenderedClassComponent } from 'inferno-test-utils';
import { Component } from 'inferno';
class MyClassComponent extends Component {
render() { return <div>Class Component</div>; }
}
function MyFunctionalComponent() {
return <div>Functional Component</div>;
}
// Class component returns the component instance
const classResult = renderIntoContainer(<MyClassComponent />);
console.log(isRenderedClassComponent(classResult)); // true
// Functional component returns the VNode
const functionalResult = renderIntoContainer(<MyFunctionalComponent />);
console.log(isRenderedClassComponent(functionalResult)); // false
// DOM element returns the VNode
const domResult = renderIntoContainer(<div>DOM Element</div>);
console.log(isRenderedClassComponent(domResult)); // falseimport { renderIntoContainer, findRenderedDOMElementWithTag, isRenderedClassComponent } from 'inferno-test-utils';
import { Component } from 'inferno';
class StatefulComponent extends Component {
constructor(props) {
super(props);
this.state = { isVisible: props.initialVisible || false };
}
toggle = () => {
this.setState({ isVisible: !this.state.isVisible });
}
render() {
return (
<div>
<button onClick={this.toggle}>Toggle</button>
{this.state.isVisible && <p>Visible content</p>}
</div>
);
}
}
// Render with props
const rendered = renderIntoContainer(<StatefulComponent initialVisible={true} />);
// Access the component instance (for class components)
if (isRenderedClassComponent(rendered)) {
console.log(rendered.state.isVisible); // true
console.log(rendered.props.initialVisible); // true
// Trigger state changes
rendered.toggle();
console.log(rendered.state.isVisible); // false
}
// Find elements in the rendered output
const button = findRenderedDOMElementWithTag(rendered, 'button');
console.log(button.textContent); // "Toggle"/**
* Gets the lowercase tag name of a DOM VNode
* @param vNode - VNode representing a DOM element
* @returns Lowercase tag name of the DOM element, or undefined if not a DOM VNode
*/
function getTagNameOfVNode(vNode: VNode): string | undefinedimport { getTagNameOfVNode, scryRenderedVNodesWithType, renderIntoContainer } from 'inferno-test-utils';
const vNodeTree = (
<div>
<h1>Heading</h1>
<p>Paragraph</p>
<button>Button</button>
</div>
);
const rendered = renderIntoContainer(vNodeTree);
// Find all DOM VNodes and get their tag names
const h1VNodes = scryRenderedVNodesWithType(rendered, 'h1');
const pVNodes = scryRenderedVNodesWithType(rendered, 'p');
const buttonVNodes = scryRenderedVNodesWithType(rendered, 'button');
console.log(getTagNameOfVNode(h1VNodes[0])); // "h1"
console.log(getTagNameOfVNode(pVNodes[0])); // "p"
console.log(getTagNameOfVNode(buttonVNodes[0])); // "button"
// Returns undefined for non-DOM VNodes
function MyComponent() { return <div />; }
const componentVNodes = scryRenderedVNodesWithType(rendered, MyComponent);
console.log(getTagNameOfVNode(componentVNodes[0])); // undefined/**
* Test wrapper component that renders its children
* Useful for wrapping components that need a parent context
*/
class Wrapper<P, S> extends Component<P, S> {
public render(): InfernoNode
}The Wrapper component is primarily used internally but can be useful for testing scenarios where you need to wrap components.
import { Wrapper, renderIntoContainer, findRenderedDOMElementWithClass, findRenderedDOMElementWithTag } from 'inferno-test-utils';
import { Component } from 'inferno';
// Custom wrapper usage
class TestWrapper extends Wrapper {
render() {
return (
<div className="test-wrapper">
{this.props.children}
</div>
);
}
}
function MyComponent() {
return <p>Component content</p>;
}
// Wrap component for testing
const wrappedComponent = (
<TestWrapper>
<MyComponent />
</TestWrapper>
);
const rendered = renderIntoContainer(wrappedComponent);
// The wrapper provides additional structure for testing
const wrapperDiv = findRenderedDOMElementWithClass(rendered, 'test-wrapper');
const componentP = findRenderedDOMElementWithTag(rendered, 'p');
console.log(componentP.textContent); // "Component content"import { renderIntoContainer, findRenderedVNodeWithType } from 'inferno-test-utils';
import { Component, createContext } from 'inferno';
const ThemeContext = createContext('light');
class ThemedComponent extends Component {
static contextType = ThemeContext;
render() {
return <div className={`theme-${this.context}`}>Themed content</div>;
}
}
// Render with context provider
const rendered = renderIntoContainer(
<ThemeContext.Provider value="dark">
<ThemedComponent />
</ThemeContext.Provider>
);
const themedComponent = findRenderedVNodeWithType(rendered, ThemedComponent);
// Test that the component received the correct contextimport { renderIntoContainer, findRenderedDOMElementWithTag, isRenderedClassComponent } from 'inferno-test-utils';
import { Component, createRef } from 'inferno';
class ComponentWithRef extends Component {
constructor(props) {
super(props);
this.inputRef = createRef();
}
focus = () => {
this.inputRef.current.focus();
}
render() {
return (
<div>
<input ref={this.inputRef} type="text" />
<button onClick={this.focus}>Focus Input</button>
</div>
);
}
}
const rendered = renderIntoContainer(<ComponentWithRef />);
// Access the component instance to test ref functionality
if (isRenderedClassComponent(rendered)) {
const input = findRenderedDOMElementWithTag(rendered, 'input');
// Test that ref is properly assigned
console.log(rendered.inputRef.current === input); // true
// Test ref functionality
rendered.focus();
console.log(document.activeElement === input); // true
}import { renderIntoContainer, findRenderedDOMElementWithTag, isRenderedClassComponent } from 'inferno-test-utils';
import { Component } from 'inferno';
class ClickableComponent extends Component {
constructor(props) {
super(props);
this.state = { clicked: false };
}
handleClick = () => {
this.setState({ clicked: true });
if (this.props.onClick) {
this.props.onClick();
}
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.clicked ? 'Clicked!' : 'Click me'}
</button>
);
}
}
// Test with mock callback
let callbackCalled = false;
const mockCallback = () => { callbackCalled = true; };
const rendered = renderIntoContainer(<ClickableComponent onClick={mockCallback} />);
const button = findRenderedDOMElementWithTag(rendered, 'button');
// Simulate click
button.click();
// Check that state updated and callback was called
if (isRenderedClassComponent(rendered)) {
console.log(rendered.state.clicked); // true
}
console.log(callbackCalled); // true
console.log(button.textContent); // "Clicked!"import { renderIntoContainer, scryRenderedDOMElementsWithTag, findRenderedDOMElementWithTag } from 'inferno-test-utils';
function FormComponent() {
return (
<form>
<input name="username" type="text" />
<input name="password" type="password" />
<button type="submit">Submit</button>
</form>
);
}
const rendered = renderIntoContainer(<FormComponent />);
// Get all form inputs
const inputs = scryRenderedDOMElementsWithTag(rendered, 'input');
// Test form interactions
inputs[0].value = 'testuser';
inputs[1].value = 'testpass';
console.log(inputs[0].value); // "testuser"
console.log(inputs[1].value); // "testpass"
// Test form submission
const form = findRenderedDOMElementWithTag(rendered, 'form');
const submitEvent = new Event('submit');
form.dispatchEvent(submitEvent);