Install ink-testing-library
masterInstall ink-testing-library as a development dependency using npm.
$ npm install --save-dev ink-testing-libraryrepository·master·Indexed 41 days ago
https://github.com/vadimdemedes/ink-testing-libraryUtilities for testing Ink applications version 4.0.0. It provides a render function to simulate the rendering lifecycle, simulate stdin input via stdin.write(), and capture stdout/stderr output using lastFrame() and frames.
Install ink-testing-library as a development dependency using npm.
$ npm install --save-dev ink-testing-libraryUse render to wrap your Ink component. You can then use lastFrame() to assert the current output or rerender() to update the component with new props and verify the changes.
import React from 'react';
import {Text} from 'ink';
import {render} from 'ink-testing-library';
const Counter = ({count}) => <Text>Count: {count}</Text>;
const {lastFrame, rerender} = render(<Counter count={0}/>);
lastFrame() === 'Count: 0'; //=> true
rerender(<Counter count={1}/>);
lastFrame() === 'Count: 1'; //=> trueBoth stdout and stderr objects provide methods to inspect the output rendered by your component:
lastFrame(): Returns the most recent rendered frame (output) from the stream.frames: An array of all rendered frames, where the last frame is the final item in the array.Note: lastFrame() is also available as a top-level shortcut on the object returned by render.
const Counter = ({count}) => <Text>Count: {count}</Text>;
const {stdout, rerender} = render(<Counter count={0}/>);
rerender(<Counter count={1}/>);
console.log(stdout.frames); //=> ['Count: 0', 'Count: 1']Use rerender(tree) to update the currently rendered root component with different props or to replace it entirely with another component.
const {rerender} = render(<OldApp/>);
rerender(<NewApp/>);The stdin object allows you to simulate user input. Use stdin.write(data) to write data to the current component's stdin stream, which can be captured by hooks like useInput in Ink.
import {useInput, Text} from 'ink';
const Test = () => {
useInput(input => {
console.log(input);
//=> 'hello'
});
return …;
};
const {stdin} = render(<Test/>);
stdin.write('hello');Call unmount() to unmount the current component and clean up.
const {unmount} = render(<Test/>);
unmount();The render(tree) function is the primary entry point. It takes a ReactElement (the component you want to test) and returns an object containing utilities to interact with the rendered component's lifecycle and streams.
Parameters:
tree: The ReactElement to render.Returns: An object containing lastFrame, frames, rerender, unmount, stdin, stdout, and stderr.
render(<MyApp/>);The cleanup() function unmounts and cleans up every Ink instance created via render() during the current process. This is typically called in a test runner's global teardown hook to prevent memory leaks and side effects between tests.
import { cleanup } from 'ink-testing-library';
// In your test runner's global teardown (e.g., Vitest or Jest)
afterEach(() => {
cleanup();
});To assert against what the component printed to the terminal, use the stdout and stderr objects or the lastFrame() helper:
stdout.frames: An array of all frames written to standard output.stderr.frames: An array of all frames written to standard error.lastFrame(): A function that returns the most recent frame written to stdout.const { stdout, lastFrame } = render(<MyComponent />);
// Check the most recent output
expect(lastFrame()).toContain('Hello World');
// Check all frames captured
expect(stdout.frames).toContain('Initial State');The Instance returned by render() provides the following lifecycle methods:
rerender(tree: ReactElement): Updates the rendered component with a new React element.unmount(): Unmounts the current component instance.cleanup(): Cleans up all currently rendered instances (useful in afterEach hooks).const { rerender, unmount, cleanup } = render(<MyComponent />);
// To update the component:
rerender(<MyComponent updated />);
// To unmount this specific instance:
unmount();
// To clean up all instances globally:
cleanup();The stdin object allows you to simulate user typing or terminal input. You can use the write(data: string) method to push data into the stream, which will trigger 'data' and 'readable' events on the stdin instance.
const { stdin } = render(<MyComponent />);
// Simulate user typing 'hello'
stdin.write('hello');Use render(tree) to mount a React element within a test environment. It returns an Instance object that provides access to simulated stdin, stdout, and stderr streams, as well as methods to control the component lifecycle. This is the primary entry point for testing Ink applications.
import { render } from 'ink-testing-library';
const {
rerender,
unmount,
cleanup,
stdout,
stdin,
lastFrame
} = render(<MyComponent />);