0
# Storybook Testing Library
1
2
Storybook Testing Library is an instrumented version of Testing Library specifically designed for Storybook's Interactions addon. It wraps `@testing-library/dom` and `@testing-library/user-event` with Storybook's instrumentation layer to enable interaction testing within Storybook stories, providing all standard Testing Library functionality while capturing interactions for the Storybook UI.
3
4
## Package Information
5
6
- **Package Name**: @storybook/testing-library
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install @storybook/testing-library`
10
11
## Core Imports
12
13
```typescript
14
import {
15
screen,
16
within,
17
waitFor,
18
userEvent,
19
fireEvent,
20
getByText,
21
findByRole,
22
queryByTestId
23
} from "@storybook/testing-library";
24
```
25
26
For CommonJS:
27
28
```javascript
29
const {
30
screen,
31
within,
32
waitFor,
33
userEvent,
34
fireEvent,
35
getByText,
36
findByRole,
37
queryByTestId
38
} = require("@storybook/testing-library");
39
```
40
41
## Basic Usage
42
43
```typescript
44
import { within, userEvent, waitFor } from "@storybook/testing-library";
45
46
export const InteractiveExample = {
47
play: async ({ canvasElement }) => {
48
// Use within instead of screen for Storybook compatibility
49
const canvas = within(canvasElement);
50
51
// Find elements using queries
52
const button = canvas.getByRole('button', { name: /click me/i });
53
const input = canvas.getByLabelText(/username/i);
54
55
// Simulate user interactions
56
await userEvent.type(input, 'john@example.com');
57
await userEvent.click(button);
58
59
// Wait for changes and assert results
60
await waitFor(() => {
61
expect(canvas.getByText('Welcome, john@example.com')).toBeInTheDocument();
62
});
63
},
64
};
65
```
66
67
## Architecture
68
69
Storybook Testing Library consists of several key components:
70
71
- **Instrumented Queries**: All Testing Library query methods wrapped with Storybook's instrumentation
72
- **User Event Integration**: Instrumented userEvent object for realistic user interactions
73
- **Screen Object**: Modified to encourage use of `within(canvasElement)` instead
74
- **Async Utilities**: Instrumented `waitFor` and `waitForElementToBeRemoved` functions
75
- **Event System**: Instrumented `fireEvent` object for direct DOM event triggering
76
77
The instrumentation captures all interactions for display in Storybook's Interactions addon, allowing developers to see and replay user actions.
78
79
## Capabilities
80
81
### DOM Queries
82
83
Complete set of Testing Library query functions for finding elements in the DOM. All queries are instrumented for Storybook interaction tracking.
84
85
```typescript { .api }
86
// Synchronous queries that throw if not found
87
function getByRole(container: HTMLElement, role: string, options?: ByRoleOptions): HTMLElement;
88
function getByText(container: HTMLElement, text: string | RegExp, options?: SelectorMatcherOptions): HTMLElement;
89
function getByTestId(container: HTMLElement, testId: string, options?: SelectorMatcherOptions): HTMLElement;
90
91
// Synchronous queries that return null if not found
92
function queryByRole(container: HTMLElement, role: string, options?: ByRoleOptions): HTMLElement | null;
93
function queryByText(container: HTMLElement, text: string | RegExp, options?: SelectorMatcherOptions): HTMLElement | null;
94
95
// Asynchronous queries that wait and resolve/reject
96
function findByRole(container: HTMLElement, role: string, options?: ByRoleOptions): Promise<HTMLElement>;
97
function findByText(container: HTMLElement, text: string | RegExp, options?: SelectorMatcherOptions): Promise<HTMLElement>;
98
```
99
100
[DOM Queries](./queries.md)
101
102
### User Interactions
103
104
Instrumented user-event functionality for simulating realistic user interactions with full keyboard, mouse, and input device support.
105
106
```typescript { .api }
107
interface UserEvent {
108
click(element: Element, options?: ClickOptions): Promise<void>;
109
type(element: Element, text: string, options?: TypeOptions): Promise<void>;
110
clear(element: Element): Promise<void>;
111
selectOptions(element: Element, values: string | string[], options?: SelectOptions): Promise<void>;
112
upload(element: Element, file: File | File[]): Promise<void>;
113
}
114
115
declare const userEvent: UserEvent;
116
```
117
118
[User Interactions](./user-interactions.md)
119
120
### Element Scoping
121
122
Scoping utilities for limiting queries to specific DOM containers, essential for Storybook story isolation.
123
124
```typescript { .api }
125
function within(element: HTMLElement): BoundFunctions;
126
127
interface BoundFunctions {
128
getByRole(role: string, options?: ByRoleOptions): HTMLElement;
129
queryByRole(role: string, options?: ByRoleOptions): HTMLElement | null;
130
findByRole(role: string, options?: ByRoleOptions): Promise<HTMLElement>;
131
// ... all query functions bound to the container
132
}
133
```
134
135
[Element Scoping](./scoping.md)
136
137
### Async Utilities
138
139
Asynchronous utilities for waiting for DOM changes and element state transitions, with instrumentation for Storybook interaction tracking.
140
141
```typescript { .api }
142
function waitFor<T>(
143
callback: () => T | Promise<T>,
144
options?: WaitForOptions
145
): Promise<T>;
146
147
function waitForElementToBeRemoved<T>(
148
callback: (() => T) | T,
149
options?: WaitForOptions
150
): Promise<void>;
151
152
interface WaitForOptions {
153
timeout?: number;
154
interval?: number;
155
onTimeout?: (error: Error) => Error;
156
}
157
```
158
159
[Async Utilities](./async-utilities.md)
160
161
### Event Handling
162
163
Direct DOM event triggering capabilities for lower-level interaction testing, with full instrumentation support.
164
165
```typescript { .api }
166
interface FireEvent {
167
(element: Element, event: Event): boolean;
168
click(element: Element, options?: MouseEventInit): boolean;
169
change(element: Element, options?: EventInit): boolean;
170
input(element: Element, options?: EventInit): boolean;
171
keyDown(element: Element, options?: KeyboardEventInit): boolean;
172
keyUp(element: Element, options?: KeyboardEventInit): boolean;
173
focus(element: Element, options?: FocusEventInit): boolean;
174
blur(element: Element, options?: FocusEventInit): boolean;
175
}
176
177
declare const fireEvent: FireEvent;
178
```
179
180
[Event Handling](./events.md)
181
182
### Configuration and Utilities
183
184
Configuration options and utility functions for customizing Testing Library behavior and building custom queries.
185
186
```typescript { .api }
187
function configure(options: ConfigureOptions): void;
188
function buildQueries<T extends (...args: any[]) => HTMLElement[]>(
189
queryAllBy: T,
190
getMultipleError: (container: HTMLElement, ...args: Parameters<T>) => string,
191
getMissingError: (container: HTMLElement, ...args: Parameters<T>) => string
192
): QueryHelpers<T>;
193
194
interface ConfigureOptions {
195
testIdAttribute?: string;
196
asyncUtilTimeout?: number;
197
computedStyleSupportsPseudoElements?: boolean;
198
defaultHidden?: boolean;
199
showOriginalStackTrace?: boolean;
200
}
201
```
202
203
[Configuration and Utilities](./configuration.md)
204
205
## Types
206
207
```typescript { .api }
208
interface ByRoleOptions {
209
hidden?: boolean;
210
name?: string | RegExp;
211
description?: string | RegExp;
212
queryFallbacks?: boolean;
213
selected?: boolean;
214
checked?: boolean;
215
pressed?: boolean;
216
current?: boolean | string;
217
expanded?: boolean;
218
level?: number;
219
}
220
221
interface SelectorMatcherOptions {
222
exact?: boolean;
223
normalizer?: (text: string) => string;
224
trim?: boolean;
225
collapseWhitespace?: boolean;
226
ignore?: string | boolean;
227
timeout?: number;
228
}
229
230
interface ClickOptions {
231
button?: number;
232
ctrlKey?: boolean;
233
shiftKey?: boolean;
234
altKey?: boolean;
235
metaKey?: boolean;
236
}
237
238
interface TypeOptions {
239
delay?: number;
240
skipClick?: boolean;
241
skipAutoClose?: boolean;
242
initialSelectionStart?: number;
243
initialSelectionEnd?: number;
244
}
245
```
246
247
## Important Notes
248
249
### Screen Object Deprecation
250
251
The `screen` object is available but shows a deprecation warning encouraging use of `within(canvasElement)` instead:
252
253
```typescript { .api }
254
// Deprecated: Shows warning message
255
const button = screen.getByRole('button');
256
257
// Recommended: Use within() for Storybook compatibility
258
const canvas = within(canvasElement);
259
const button = canvas.getByRole('button');
260
```
261
262
### Package Deprecation
263
264
This package is deprecated in favor of `@storybook/test` for Storybook 8 and later versions, but remains functional for earlier Storybook versions requiring instrumented testing capabilities.