Skip to content

User Event

user-event is a helper that provides more advanced simulation of CLI interactions than the fireEvent method.

Upgrading from v3? See the v3 to v4 migration guide for keyboard-input changes.

userEvent can be used either as a global import or as returned from render:

import { userEvent } from "cli-testing-library";

Or:

import { render } from "cli-testing-library";
const { userEvent } = render("command");

Note: All userEvent methods are synchronous with one exception: when delay option used with userEvent.keyboard as described below. We also discourage using userEvent inside before/after blocks at all, for important reasons described in “Avoid Nesting When You’re Testing”.

Writes text inside a CLI’s stdin buffer

import { render } from "cli-testing-library";
test("type", () => {
const { getByText, userEvent } = render("command");
userEvent.keyboard("Hello, World![Enter]");
expect(getByText("Hello, world!")).toBeTruthy();
});

options.delay is the number of milliseconds that pass between two characters are typed. By default it’s 0. You can use this option if your component has a different behavior for fast or slow users. If you do this, you need to make sure to await!

Keystrokes can be described:

  • Per printable character

    userEvent.keyboard("foo"); // translates to: f, o, o
    userEvent.keyboard("/test-dir\\"); // forward and backslashes are typed literally
    userEvent.keyboard("Grüße 👋"); // Unicode text is typed literally too

    Printable text is written directly to the process. It does not need to be added to the keyboard map.

    The bracket [ is used as a special character and can be referenced by doubling it.

    userEvent.keyboard("a[["); // translates to: a, [
  • Per special key mapping with the [ symbol

    userEvent.keyboard("[ArrowLeft][KeyF][KeyO][KeyO]"); // translates to: Left Arrow, F, O, O

Named special keys are resolved through the default terminal key map. You can provide your own mapping to replace it, or extend the default map with application-specific descriptors.

The default map targets Node readline and xterm-compatible input over a piped stdin. Its raw bytes and decoded Node keypress events are tested on Linux, macOS, and Windows. This does not emulate a real PTY; programs that require a TTY or another terminal protocol may need a custom map or direct fireEvent calls.

import { defaultKeyMap } from "cli-testing-library";
userEvent.keyboard("[Confirm]", {
keyboardMap: [
{ code: "Confirm", hex: "\r" },
...defaultKeyMap,
],
});

Chords use + inside a single descriptor. For example, [Ctrl+C] sends the Ctrl+C control character and [Ctrl+D] sends Ctrl+D. Sequential forms such as [Ctrl]c are not supported because Ctrl has no standalone terminal input.

A chord emits one control character. For example, [Ctrl+C] writes only 0x03. When options.delay is set, the delay applies between the chord and surrounding keys, not between Ctrl and C.

We support inputting many special character strings with the [ syntax mentioned previously. Here are some of the ones that are supported:

Text string Key name
[Enter] Enter
[Space] ' '
[Escape] Escape
[Backspace] Backspace
[Ctrl+C] Ctrl+C
[Ctrl+D] Ctrl+D
[Tab] Tab
[ShiftTab] Shift+Tab
[Delete] Delete
[Insert] Insert
[ArrowLeft] Left Arrow
[ArrowRight] Right Arrow
[ArrowUp] Up Arrow
[ArrowDown] Down Arrow
[Home] Home
[End] End
[PageUp] Page Up
[PageDown] Page Down
[F1][F12] Function keys

A full list of supported special characters that can be input can be found in our key mapping file.