Instrumented version of Testing Library for Storybook Interactions addon
—
Direct DOM event triggering capabilities for lower-level interaction testing, with full instrumentation support. The fireEvent object provides methods for dispatching DOM events directly, useful for testing edge cases and low-level interactions.
Main interface for triggering DOM events directly. All fireEvent methods are instrumented for Storybook interaction tracking.
/**
* Fire DOM events directly on elements
* All methods are instrumented for Storybook interaction tracking
*/
interface FireEvent {
/**
* Dispatch a custom event on an element
* @param element - Target element
* @param event - Event object to dispatch
* @returns Boolean indicating if event was not cancelled
*/
(element: Element, event: Event): boolean;
/**
* Fire a click event
* @param element - Element to click
* @param options - Mouse event options
* @returns Boolean indicating if event was not cancelled
*/
click(element: Element, options?: MouseEventInit): boolean;
/**
* Fire a double-click event
* @param element - Element to double-click
* @param options - Mouse event options
* @returns Boolean indicating if event was not cancelled
*/
dblClick(element: Element, options?: MouseEventInit): boolean;
/**
* Fire a mouse down event
* @param element - Target element
* @param options - Mouse event options
* @returns Boolean indicating if event was not cancelled
*/
mouseDown(element: Element, options?: MouseEventInit): boolean;
/**
* Fire a mouse up event
* @param element - Target element
* @param options - Mouse event options
* @returns Boolean indicating if event was not cancelled
*/
mouseUp(element: Element, options?: MouseEventInit): boolean;
/**
* Fire a mouse enter event
* @param element - Target element
* @param options - Mouse event options
* @returns Boolean indicating if event was not cancelled
*/
mouseEnter(element: Element, options?: MouseEventInit): boolean;
/**
* Fire a mouse leave event
* @param element - Target element
* @param options - Mouse event options
* @returns Boolean indicating if event was not cancelled
*/
mouseLeave(element: Element, options?: MouseEventInit): boolean;
/**
* Fire a mouse move event
* @param element - Target element
* @param options - Mouse event options
* @returns Boolean indicating if event was not cancelled
*/
mouseMove(element: Element, options?: MouseEventInit): boolean;
/**
* Fire a mouse over event
* @param element - Target element
* @param options - Mouse event options
* @returns Boolean indicating if event was not cancelled
*/
mouseOver(element: Element, options?: MouseEventInit): boolean;
/**
* Fire a mouse out event
* @param element - Target element
* @param options - Mouse event options
* @returns Boolean indicating if event was not cancelled
*/
mouseOut(element: Element, options?: MouseEventInit): boolean;
/**
* Fire a change event (for form elements)
* @param element - Form element
* @param options - Event options
* @returns Boolean indicating if event was not cancelled
*/
change(element: Element, options?: EventInit): boolean;
/**
* Fire an input event (for form elements)
* @param element - Form element
* @param options - Event options
* @returns Boolean indicating if event was not cancelled
*/
input(element: Element, options?: EventInit): boolean;
/**
* Fire a focus event
* @param element - Element to focus
* @param options - Focus event options
* @returns Boolean indicating if event was not cancelled
*/
focus(element: Element, options?: FocusEventInit): boolean;
/**
* Fire a blur event
* @param element - Element to blur
* @param options - Focus event options
* @returns Boolean indicating if event was not cancelled
*/
blur(element: Element, options?: FocusEventInit): boolean;
/**
* Fire a focus-in event
* @param element - Target element
* @param options - Focus event options
* @returns Boolean indicating if event was not cancelled
*/
focusIn(element: Element, options?: FocusEventInit): boolean;
/**
* Fire a focus-out event
* @param element - Target element
* @param options - Focus event options
* @returns Boolean indicating if event was not cancelled
*/
focusOut(element: Element, options?: FocusEventInit): boolean;
/**
* Fire a key down event
* @param element - Target element
* @param options - Keyboard event options
* @returns Boolean indicating if event was not cancelled
*/
keyDown(element: Element, options?: KeyboardEventInit): boolean;
/**
* Fire a key up event
* @param element - Target element
* @param options - Keyboard event options
* @returns Boolean indicating if event was not cancelled
*/
keyUp(element: Element, options?: KeyboardEventInit): boolean;
/**
* Fire a key press event (deprecated but available)
* @param element - Target element
* @param options - Keyboard event options
* @returns Boolean indicating if event was not cancelled
*/
keyPress(element: Element, options?: KeyboardEventInit): boolean;
/**
* Fire a submit event on a form
* @param element - Form element
* @param options - Event options
* @returns Boolean indicating if event was not cancelled
*/
submit(element: Element, options?: EventInit): boolean;
/**
* Fire a reset event on a form
* @param element - Form element
* @param options - Event options
* @returns Boolean indicating if event was not cancelled
*/
reset(element: Element, options?: EventInit): boolean;
/**
* Fire a select event on an input
* @param element - Input element
* @param options - Event options
* @returns Boolean indicating if event was not cancelled
*/
select(element: Element, options?: EventInit): boolean;
/**
* Fire a scroll event
* @param element - Scrollable element
* @param options - Event options
* @returns Boolean indicating if event was not cancelled
*/
scroll(element: Element, options?: EventInit): boolean;
/**
* Fire a wheel event
* @param element - Target element
* @param options - Wheel event options
* @returns Boolean indicating if event was not cancelled
*/
wheel(element: Element, options?: WheelEventInit): boolean;
/**
* Fire a context menu event (right-click)
* @param element - Target element
* @param options - Mouse event options
* @returns Boolean indicating if event was not cancelled
*/
contextMenu(element: Element, options?: MouseEventInit): boolean;
/**
* Fire a drag event
* @param element - Target element
* @param options - Drag event options
* @returns Boolean indicating if event was not cancelled
*/
drag(element: Element, options?: DragEventInit): boolean;
/**
* Fire a drag start event
* @param element - Target element
* @param options - Drag event options
* @returns Boolean indicating if event was not cancelled
*/
dragStart(element: Element, options?: DragEventInit): boolean;
/**
* Fire a drag end event
* @param element - Target element
* @param options - Drag event options
* @returns Boolean indicating if event was not cancelled
*/
dragEnd(element: Element, options?: DragEventInit): boolean;
/**
* Fire a drag enter event
* @param element - Target element
* @param options - Drag event options
* @returns Boolean indicating if event was not cancelled
*/
dragEnter(element: Element, options?: DragEventInit): boolean;
/**
* Fire a drag leave event
* @param element - Target element
* @param options - Drag event options
* @returns Boolean indicating if event was not cancelled
*/
dragLeave(element: Element, options?: DragEventInit): boolean;
/**
* Fire a drag over event
* @param element - Target element
* @param options - Drag event options
* @returns Boolean indicating if event was not cancelled
*/
dragOver(element: Element, options?: DragEventInit): boolean;
/**
* Fire a drop event
* @param element - Target element
* @param options - Drag event options
* @returns Boolean indicating if event was not cancelled
*/
drop(element: Element, options?: DragEventInit): boolean;
/**
* Fire a touch start event
* @param element - Target element
* @param options - Touch event options
* @returns Boolean indicating if event was not cancelled
*/
touchStart(element: Element, options?: TouchEventInit): boolean;
/**
* Fire a touch end event
* @param element - Target element
* @param options - Touch event options
* @returns Boolean indicating if event was not cancelled
*/
touchEnd(element: Element, options?: TouchEventInit): boolean;
/**
* Fire a touch move event
* @param element - Target element
* @param options - Touch event options
* @returns Boolean indicating if event was not cancelled
*/
touchMove(element: Element, options?: TouchEventInit): boolean;
/**
* Fire a touch cancel event
* @param element - Target element
* @param options - Touch event options
* @returns Boolean indicating if event was not cancelled
*/
touchCancel(element: Element, options?: TouchEventInit): boolean;
/**
* Fire a load event
* @param element - Target element
* @param options - Event options
* @returns Boolean indicating if event was not cancelled
*/
load(element: Element, options?: EventInit): boolean;
/**
* Fire an error event
* @param element - Target element
* @param options - Event options
* @returns Boolean indicating if event was not cancelled
*/
error(element: Element, options?: EventInit): boolean;
/**
* Fire a resize event
* @param element - Target element
* @param options - Event options
* @returns Boolean indicating if event was not cancelled
*/
resize(element: Element, options?: EventInit): boolean;
}
declare const fireEvent: FireEvent;Creates DOM event objects that can be dispatched manually.
/**
* Create a DOM event object
* @param eventType - Type of event to create (e.g., 'click', 'keydown')
* @param element - Element the event will be dispatched on
* @param options - Event initialization options
* @returns Created event object
*/
function createEvent(
eventType: string,
element: Element,
options?: EventInit
): Event;import { within, fireEvent, waitFor } from "@storybook/testing-library";
export const BasicEventExample = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
// Fire a click event
const button = canvas.getByRole('button', { name: /click me/i });
fireEvent.click(button);
// Verify the click was handled
await waitFor(() => {
expect(canvas.getByText(/button clicked/i)).toBeInTheDocument();
});
}
};import { within, fireEvent, waitFor } from "@storybook/testing-library";
export const FormEventsExample = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const input = canvas.getByLabelText(/email/i);
// Fire focus event
fireEvent.focus(input);
expect(input).toHaveFocus();
// Fire input event with value change
fireEvent.input(input, { target: { value: 'user@example.com' } });
// Fire change event
fireEvent.change(input, { target: { value: 'user@example.com' } });
// Fire blur event
fireEvent.blur(input);
// Verify form validation
await waitFor(() => {
expect(canvas.queryByText(/invalid email/i)).not.toBeInTheDocument();
});
}
};import { within, fireEvent, waitFor } from "@storybook/testing-library";
export const KeyboardEventsExample = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const input = canvas.getByLabelText(/search/i);
fireEvent.focus(input);
// Fire key down events
fireEvent.keyDown(input, { key: 'A', code: 'KeyA' });
fireEvent.keyDown(input, { key: 'B', code: 'KeyB' });
fireEvent.keyDown(input, { key: 'C', code: 'KeyC' });
// Fire Enter key
fireEvent.keyDown(input, { key: 'Enter', code: 'Enter' });
// Verify search was triggered
await waitFor(() => {
expect(canvas.getByText(/searching for: ABC/i)).toBeInTheDocument();
});
}
};import { within, fireEvent, waitFor } from "@storybook/testing-library";
export const MouseEventsExample = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const draggable = canvas.getByTestId('draggable-item');
const dropzone = canvas.getByTestId('drop-zone');
// Simulate mouse drag
fireEvent.mouseDown(draggable, { clientX: 100, clientY: 100 });
fireEvent.mouseMove(draggable, { clientX: 150, clientY: 150 });
fireEvent.mouseUp(draggable, { clientX: 200, clientY: 200 });
// Hover events
fireEvent.mouseEnter(dropzone);
fireEvent.mouseOver(dropzone);
fireEvent.mouseLeave(dropzone);
// Context menu
fireEvent.contextMenu(draggable);
await waitFor(() => {
expect(canvas.getByRole('menu')).toBeInTheDocument();
});
}
};import { within, fireEvent, waitFor } from "@storybook/testing-library";
export const DragDropExample = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const draggable = canvas.getByTestId('draggable');
const dropzone = canvas.getByTestId('dropzone');
// Start drag operation
fireEvent.dragStart(draggable, {
dataTransfer: {
setData: (format: string, data: string) => {},
getData: (format: string) => 'dragged-item'
}
});
// Drag over drop zone
fireEvent.dragEnter(dropzone);
fireEvent.dragOver(dropzone);
// Complete drop
fireEvent.drop(dropzone, {
dataTransfer: {
getData: (format: string) => 'dragged-item'
}
});
fireEvent.dragEnd(draggable);
// Verify drop was handled
await waitFor(() => {
expect(canvas.getByText(/item dropped/i)).toBeInTheDocument();
});
}
};import { within, fireEvent, waitFor } from "@storybook/testing-library";
export const TouchEventsExample = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const touchTarget = canvas.getByTestId('touch-target');
// Simulate touch interaction
fireEvent.touchStart(touchTarget, {
touches: [{ clientX: 100, clientY: 100 }]
});
fireEvent.touchMove(touchTarget, {
touches: [{ clientX: 150, clientY: 150 }]
});
fireEvent.touchEnd(touchTarget, {
changedTouches: [{ clientX: 150, clientY: 150 }]
});
// Verify touch interaction
await waitFor(() => {
expect(canvas.getByText(/touched/i)).toBeInTheDocument();
});
}
};import { within, fireEvent, createEvent, waitFor } from "@storybook/testing-library";
export const CustomEventsExample = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const component = canvas.getByTestId('custom-component');
// Create and fire custom event
const customEvent = createEvent('customEvent', component, {
bubbles: true,
detail: { message: 'Hello from custom event' }
});
fireEvent(component, customEvent);
// Verify custom event was handled
await waitFor(() => {
expect(canvas.getByText(/custom event received/i)).toBeInTheDocument();
});
}
};import { within, fireEvent } from "@storybook/testing-library";
export const EventOptionsExample = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const button = canvas.getByRole('button', { name: /special click/i });
// Click with modifier keys
fireEvent.click(button, {
ctrlKey: true,
shiftKey: true,
button: 0, // Left mouse button
clientX: 100,
clientY: 200
});
// Keyboard event with modifiers
const input = canvas.getByLabelText(/shortcut input/i);
fireEvent.keyDown(input, {
key: 'S',
code: 'KeyS',
ctrlKey: true,
shiftKey: true
});
}
};import { within, fireEvent, waitFor } from "@storybook/testing-library";
export const FormSubmissionExample = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const form = canvas.getByRole('form');
const emailInput = canvas.getByLabelText(/email/i);
const passwordInput = canvas.getByLabelText(/password/i);
// Fill form
fireEvent.change(emailInput, { target: { value: 'user@example.com' } });
fireEvent.change(passwordInput, { target: { value: 'password123' } });
// Submit form
fireEvent.submit(form);
// Verify submission
await waitFor(() => {
expect(canvas.getByText(/form submitted/i)).toBeInTheDocument();
});
}
};import { within, fireEvent, waitFor } from "@storybook/testing-library";
export const ScrollEventsExample = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const scrollableContainer = canvas.getByTestId('scrollable');
// Fire scroll event
fireEvent.scroll(scrollableContainer, { target: { scrollY: 100 } });
// Fire wheel event for mouse wheel scrolling
fireEvent.wheel(scrollableContainer, { deltaY: 100 });
// Verify scroll behavior
await waitFor(() => {
expect(canvas.getByText(/scrolled/i)).toBeInTheDocument();
});
}
};import { within, fireEvent, userEvent } from "@storybook/testing-library";
export const ComparisonExample = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const input = canvas.getByLabelText(/username/i);
// fireEvent - direct, low-level
fireEvent.change(input, { target: { value: 'testuser' } });
// userEvent - realistic, high-level
await userEvent.type(input, 'testuser');
}
};Install with Tessl CLI
npx tessl i tessl/npm-storybook--testing-library