0
# User Interactions
1
2
Comprehensive user event simulation supporting keyboard input, mouse interactions, form manipulation, and file uploads with provider-specific implementations for realistic browser testing.
3
4
## Capabilities
5
6
### Mouse Interactions
7
8
Simulate mouse events including clicks, hovers, and drag operations.
9
10
```typescript { .api }
11
/**
12
* Click on an element. Uses provider's API under the hood and supports all its options.
13
* @param element - Target element or locator
14
* @param options - Provider-specific click options
15
*/
16
click(element: Element | Locator, options?: UserEventClickOptions): Promise<void>;
17
18
/**
19
* Triggers a double click event on an element
20
* @param element - Target element or locator
21
* @param options - Provider-specific double click options
22
*/
23
dblClick(element: Element | Locator, options?: UserEventDoubleClickOptions): Promise<void>;
24
25
/**
26
* Triggers a triple click event on an element
27
* @param element - Target element or locator
28
* @param options - Provider-specific triple click options
29
*/
30
tripleClick(element: Element | Locator, options?: UserEventTripleClickOptions): Promise<void>;
31
32
/**
33
* Hovers over an element
34
* @param element - Target element or locator
35
* @param options - Provider-specific hover options
36
*/
37
hover(element: Element | Locator, options?: UserEventHoverOptions): Promise<void>;
38
39
/**
40
* Moves cursor position to the body element
41
* @param element - Element to move away from
42
* @param options - Provider-specific hover options
43
*/
44
unhover(element: Element | Locator, options?: UserEventHoverOptions): Promise<void>;
45
46
/**
47
* Drags a source element on top of the target element (not supported by preview provider)
48
* @param source - Source element or locator
49
* @param target - Target element or locator
50
* @param options - Provider-specific drag options
51
*/
52
dragAndDrop(source: Element | Locator, target: Element | Locator, options?: UserEventDragAndDropOptions): Promise<void>;
53
```
54
55
**Usage Examples:**
56
57
```typescript
58
import { userEvent, page } from "@vitest/browser/context";
59
60
// Basic mouse interactions
61
await userEvent.click(page.getByRole("button", { name: "Submit" }));
62
await userEvent.dblClick(page.getByText("Double click me"));
63
await userEvent.tripleClick(page.getByText("Select all text"));
64
65
// Hover interactions
66
await userEvent.hover(page.getByRole("menu"));
67
await userEvent.unhover(page.getByRole("menu"));
68
69
// Drag and drop
70
const sourceItem = page.getByTestId("drag-source");
71
const targetArea = page.getByTestId("drop-target");
72
await userEvent.dragAndDrop(sourceItem, targetArea);
73
74
// Provider-specific options (example with Playwright)
75
await userEvent.click(page.getByRole("button"), {
76
position: { x: 10, y: 10 }, // Click at specific position
77
button: "right" // Right click
78
});
79
```
80
81
### Keyboard Input
82
83
Handle keyboard events including typing, key combinations, and navigation.
84
85
```typescript { .api }
86
/**
87
* Type text on the keyboard. If any input is focused, it will receive the text,
88
* otherwise it will be typed on the document. Supports user-event keyboard syntax.
89
* @param text - Text to type (supports {Shift}, {Ctrl}, etc. syntax)
90
*/
91
keyboard(text: string): Promise<void>;
92
93
/**
94
* Types text into an element. Supports user-event keyboard syntax.
95
* This method can be significantly slower than fill(), so use only when necessary.
96
* @param element - Target element or locator
97
* @param text - Text to type (supports keyboard syntax)
98
* @param options - Typing options
99
*/
100
type(element: Element | Locator, text: string, options?: UserEventTypeOptions): Promise<void>;
101
102
/**
103
* Sends a Tab key event
104
* @param options - Tab options
105
*/
106
tab(options?: UserEventTabOptions): Promise<void>;
107
```
108
109
**Usage Examples:**
110
111
```typescript
112
import { userEvent, page } from "@vitest/browser/context";
113
114
// Basic keyboard input
115
await userEvent.keyboard("Hello World");
116
117
// Keyboard shortcuts
118
await userEvent.keyboard("{Ctrl}a"); // Select all
119
await userEvent.keyboard("{Ctrl}c"); // Copy
120
await userEvent.keyboard("{Ctrl}v"); // Paste
121
await userEvent.keyboard("{Shift}{Tab}"); // Shift+Tab
122
123
// Complex key combinations
124
await userEvent.keyboard("{Ctrl}{Shift}i"); // Open dev tools
125
await userEvent.keyboard("{Alt}f4"); // Alt+F4
126
127
// Type into specific elements
128
await userEvent.type(page.getByLabelText("Username"), "johndoe");
129
await userEvent.type(page.getByLabelText("Password"), "{Ctrl}a{Delete}newpassword");
130
131
// Tab navigation
132
await userEvent.tab(); // Tab forward
133
await userEvent.tab({ shift: true }); // Tab backward
134
135
// Escape sequences for literal characters
136
await userEvent.keyboard("{{"); // Types a literal {
137
await userEvent.keyboard("[["); // Types a literal [
138
```
139
140
### Form Manipulation
141
142
Handle form inputs, selections, and file uploads.
143
144
```typescript { .api }
145
/**
146
* Fills an input element with text. Removes existing text before typing.
147
* Faster than type() but doesn't support keyboard syntax.
148
* @param element - Target input element or locator
149
* @param text - Text to fill (literal text only)
150
* @param options - Fill options
151
*/
152
fill(element: Element | Locator, text: string, options?: UserEventFillOptions): Promise<void>;
153
154
/**
155
* Removes all text from an element
156
* @param element - Target element or locator
157
* @param options - Clear options
158
*/
159
clear(element: Element | Locator, options?: UserEventClearOptions): Promise<void>;
160
161
/**
162
* Choose one or more values from a select element
163
* @param element - Target select element
164
* @param values - Values to select (strings, elements, or locators)
165
* @param options - Selection options
166
*/
167
selectOptions(
168
element: Element,
169
values: HTMLElement | HTMLElement[] | Locator | Locator[] | string | string[],
170
options?: UserEventSelectOptions
171
): Promise<void>;
172
173
/**
174
* Change a file input element to have the specified files
175
* @param element - Target file input element or locator
176
* @param files - Files to upload (File objects or file paths)
177
* @param options - Upload options
178
*/
179
upload(element: Element | Locator, files: File | File[] | string | string[], options?: UserEventUploadOptions): Promise<void>;
180
```
181
182
**Usage Examples:**
183
184
```typescript
185
import { userEvent, page } from "@vitest/browser/context";
186
187
// Form filling
188
await userEvent.fill(page.getByLabelText("Email"), "user@example.com");
189
await userEvent.fill(page.getByLabelText("Password"), "secretpassword");
190
191
// Clear existing content
192
await userEvent.clear(page.getByLabelText("Search"));
193
194
// Select dropdown options
195
const countrySelect = page.getByLabelText("Country");
196
await userEvent.selectOptions(countrySelect, "United States");
197
198
// Multiple selections
199
await userEvent.selectOptions(countrySelect, ["US", "CA", "MX"]);
200
201
// Select by option elements
202
await userEvent.selectOptions(countrySelect, [
203
page.getByRole("option", { name: "United States" }),
204
page.getByRole("option", { name: "Canada" })
205
]);
206
207
// File uploads
208
const fileInput = page.getByLabelText("Upload file");
209
210
// Upload with File objects
211
await userEvent.upload(fileInput, [
212
new File(["content"], "test.txt", { type: "text/plain" }),
213
new File(["image data"], "image.png", { type: "image/png" })
214
]);
215
216
// Upload with file paths (server-side files)
217
await userEvent.upload(fileInput, ["./fixtures/test-file.pdf"]);
218
```
219
220
### Clipboard Operations
221
222
Handle copy, cut, and paste operations.
223
224
```typescript { .api }
225
/**
226
* Copies the selected content
227
*/
228
copy(): Promise<void>;
229
230
/**
231
* Cuts the selected content
232
*/
233
cut(): Promise<void>;
234
235
/**
236
* Pastes the copied or cut content
237
*/
238
paste(): Promise<void>;
239
```
240
241
**Usage Examples:**
242
243
```typescript
244
import { userEvent, page } from "@vitest/browser/context";
245
246
// Select and copy text
247
const textElement = page.getByText("Important text to copy");
248
await userEvent.tripleClick(textElement); // Select all text
249
await userEvent.copy();
250
251
// Cut from input field
252
const inputField = page.getByLabelText("Source text");
253
await userEvent.keyboard("{Ctrl}a"); // Select all
254
await userEvent.cut();
255
256
// Paste into another field
257
const targetField = page.getByLabelText("Destination");
258
await userEvent.click(targetField);
259
await userEvent.paste();
260
261
// Copy-paste workflow
262
await userEvent.keyboard("{Ctrl}a"); // Select all
263
await userEvent.copy(); // Copy
264
await userEvent.click(page.getByLabelText("Backup field"));
265
await userEvent.paste(); // Paste
266
```
267
268
### Instance Management
269
270
Create and manage separate user event instances with independent state.
271
272
```typescript { .api }
273
/**
274
* Creates a new user event instance with separate keyboard state
275
* @returns New UserEvent instance
276
*/
277
setup(): UserEvent;
278
279
/**
280
* Cleans up the user event instance, releasing any resources or state
281
*/
282
cleanup(): Promise<void>;
283
```
284
285
**Usage Examples:**
286
287
```typescript
288
import { userEvent } from "@vitest/browser/context";
289
290
// Create separate instance for complex interactions
291
const userEvent2 = userEvent.setup();
292
293
// Each instance maintains its own keyboard state
294
await userEvent.keyboard("{Shift}"); // Hold shift in default instance
295
await userEvent2.keyboard("text"); // Type in second instance (no shift)
296
297
// Clean up when done
298
await userEvent2.cleanup();
299
300
// Useful for parallel operations or state isolation
301
test("multiple user sessions", async () => {
302
const user1 = userEvent.setup();
303
const user2 = userEvent.setup();
304
305
// Simulate two users typing simultaneously
306
await Promise.all([
307
user1.type(page.getByLabelText("User 1 input"), "Hello"),
308
user2.type(page.getByLabelText("User 2 input"), "World")
309
]);
310
311
await user1.cleanup();
312
await user2.cleanup();
313
});
314
```
315
316
### Advanced Interactions
317
318
Complex interaction patterns and provider-specific features.
319
320
**Drag and Drop with Custom Positions:**
321
322
```typescript
323
// Drag with specific coordinates (WebdriverIO)
324
await userEvent.dragAndDrop(sourceElement, targetElement, {
325
sourceX: 10,
326
sourceY: 10,
327
targetX: 50,
328
targetY: 50
329
});
330
```
331
332
**File Upload with Custom File Properties:**
333
334
```typescript
335
// Create files with specific properties
336
const csvFile = new File(
337
["name,age\nJohn,30\nJane,25"],
338
"users.csv",
339
{ type: "text/csv", lastModified: Date.now() }
340
);
341
342
await userEvent.upload(page.getByLabelText("Import CSV"), csvFile);
343
```
344
345
**Complex Form Interactions:**
346
347
```typescript
348
// Multi-step form interaction
349
const form = page.getByRole("form");
350
351
await userEvent.fill(form.getByLabelText("First Name"), "John");
352
await userEvent.fill(form.getByLabelText("Last Name"), "Doe");
353
await userEvent.selectOptions(form.getByLabelText("Country"), "US");
354
await userEvent.click(form.getByLabelText("Agree to terms"));
355
await userEvent.upload(form.getByLabelText("Profile Picture"), profileImage);
356
await userEvent.click(form.getByRole("button", { name: "Submit" }));
357
```
358
359
## Types
360
361
Option interfaces for user interaction methods:
362
363
```typescript { .api }
364
interface UserEventClickOptions {
365
// Provider-specific options (e.g., Playwright click options)
366
}
367
368
interface UserEventDoubleClickOptions {
369
// Provider-specific options
370
}
371
372
interface UserEventTripleClickOptions {
373
// Provider-specific options
374
}
375
376
interface UserEventFillOptions {
377
// Provider-specific options
378
}
379
380
interface UserEventClearOptions {
381
// Provider-specific options
382
}
383
384
interface UserEventHoverOptions {
385
// Provider-specific options
386
}
387
388
interface UserEventSelectOptions {
389
// Provider-specific options
390
}
391
392
interface UserEventUploadOptions {
393
// Provider-specific options
394
}
395
396
interface UserEventDragAndDropOptions {
397
// Provider-specific options
398
}
399
400
interface UserEventTabOptions {
401
/** Whether to hold Shift while pressing Tab */
402
shift?: boolean;
403
}
404
405
interface UserEventTypeOptions {
406
/** Whether to skip the initial click on the element */
407
skipClick?: boolean;
408
/** Whether to skip automatic closing of dialogs */
409
skipAutoClose?: boolean;
410
}
411
```