Simple and complete DOM testing utilities that encourage good testing practices.
—
Fire DOM events to simulate user interactions and test event handling.
Fire a DOM event on an element with optional properties.
const fireEvent: FireFunction & FireObject;
type FireFunction = (element: Node | Document | Window, event: Event) => boolean;
interface FireObject {
// Mouse events
click(element: Node, options?: {}): boolean;
dblClick(element: Node, options?: {}): boolean;
mouseDown(element: Node, options?: {}): boolean;
mouseUp(element: Node, options?: {}): boolean;
mouseMove(element: Node, options?: {}): boolean;
mouseEnter(element: Node, options?: {}): boolean;
mouseLeave(element: Node, options?: {}): boolean;
mouseOver(element: Node, options?: {}): boolean;
mouseOut(element: Node, options?: {}): boolean;
contextMenu(element: Node, options?: {}): boolean;
// Keyboard events
keyDown(element: Node, options?: {}): boolean;
keyUp(element: Node, options?: {}): boolean;
keyPress(element: Node, options?: {}): boolean;
// Form events
change(element: Node, options?: {}): boolean;
input(element: Node, options?: {}): boolean;
submit(element: Node, options?: {}): boolean;
reset(element: Node, options?: {}): boolean;
invalid(element: Node, options?: {}): boolean;
// Focus events
focus(element: Node, options?: {}): boolean;
blur(element: Node, options?: {}): boolean;
focusIn(element: Node, options?: {}): boolean;
focusOut(element: Node, options?: {}): boolean;
// Pointer events
pointerDown(element: Node, options?: {}): boolean;
pointerUp(element: Node, options?: {}): boolean;
pointerMove(element: Node, options?: {}): boolean;
pointerOver(element: Node, options?: {}): boolean;
pointerEnter(element: Node, options?: {}): boolean;
pointerLeave(element: Node, options?: {}): boolean;
pointerOut(element: Node, options?: {}): boolean;
pointerCancel(element: Node, options?: {}): boolean;
// Drag events
dragStart(element: Node, options?: {}): boolean;
drag(element: Node, options?: {}): boolean;
dragEnd(element: Node, options?: {}): boolean;
dragEnter(element: Node, options?: {}): boolean;
dragExit(element: Node, options?: {}): boolean;
dragLeave(element: Node, options?: {}): boolean;
dragOver(element: Node, options?: {}): boolean;
drop(element: Node, options?: {}): boolean;
// Touch events
touchStart(element: Node, options?: {}): boolean;
touchEnd(element: Node, options?: {}): boolean;
touchMove(element: Node, options?: {}): boolean;
touchCancel(element: Node, options?: {}): boolean;
// Clipboard events
copy(element: Node, options?: {}): boolean;
cut(element: Node, options?: {}): boolean;
paste(element: Node, options?: {}): boolean;
// Other events
scroll(element: Node, options?: {}): boolean;
wheel(element: Node, options?: {}): boolean;
select(element: Node, options?: {}): boolean;
load(element: Node, options?: {}): boolean;
error(element: Node, options?: {}): boolean;
// ... and many more
}import {fireEvent, screen} from '@testing-library/dom';
// Click
fireEvent.click(screen.getByRole('button', {name: /submit/i}));
// Change input value
fireEvent.change(screen.getByLabelText('Email'), {
target: {value: 'user@example.com'}
});
// Keyboard events
fireEvent.keyDown(screen.getByRole('textbox'), {
key: 'Enter',
code: 'Enter',
charCode: 13
});
// Mouse events
fireEvent.mouseDown(element, {clientX: 100, clientY: 100});
fireEvent.mouseUp(element);
// Form submission
fireEvent.submit(screen.getByRole('form'));
// Focus
fireEvent.focus(element);
fireEvent.blur(element);// Fill and submit form
const name = screen.getByLabelText('Name');
const email = screen.getByLabelText('Email');
const checkbox = screen.getByLabelText('I agree');
fireEvent.change(name, {target: {value: 'John Doe'}});
fireEvent.change(email, {target: {value: 'john@example.com'}});
fireEvent.click(checkbox);
fireEvent.submit(screen.getByRole('form'));
// Verify submission
expect(screen.getByText('Thank you')).toBeInTheDocument();const listbox = screen.getByRole('listbox');
// Navigate with keyboard
fireEvent.keyDown(listbox, {key: 'ArrowDown'});
fireEvent.keyDown(listbox, {key: 'ArrowDown'});
fireEvent.keyDown(listbox, {key: 'Enter'});const draggable = screen.getByTestId('draggable-item');
const dropZone = screen.getByTestId('drop-zone');
fireEvent.dragStart(draggable);
fireEvent.dragEnter(dropZone);
fireEvent.dragOver(dropZone);
fireEvent.drop(dropZone);
fireEvent.dragEnd(draggable);You can pass event properties through the options parameter:
// Mouse with coordinates
fireEvent.mouseDown(element, {clientX: 100, clientY: 100});
// Keyboard modifiers
fireEvent.keyDown(element, {
key: 'A',
keyCode: 65,
ctrlKey: true
});
// Custom properties
fireEvent.click(button, {
button: 0, // Left click
bubbles: true,
cancelable: true
});Create event objects without firing them (for advanced use cases).
const createEvent: CreateFunction & CreateObject;
type CreateFunction = (
eventName: string,
node: Node | Document | Window,
init?: {},
options?: {EventType?: string; defaultInit?: {}}
) => Event;Example:
const event = createEvent.click(element, {
bubbles: true,
cancelable: true,
button: 0
});
element.dispatchEvent(event);
// Or
fireEvent(element, event);For more realistic user interactions, consider @testing-library/user-event which simulates complete user sequences (e.g., mousedown → mouseup → click).
// fireEvent - single event
fireEvent.click(button);
// user-event - full sequence
import userEvent from '@testing-library/user-event';
await userEvent.click(button); // Fires mousedown, mouseup, clickInstall with Tessl CLI
npx tessl i tessl/npm-testing-library--dom