Skip to content

Commit cf14864

Browse files
authored
feat(browser): support userEvent.upload in playwright provider (#6442)
1 parent c853126 commit cf14864

File tree

18 files changed

+448
-43
lines changed

18 files changed

+448
-43
lines changed

docs/guide/browser/interactivity-api.md

Lines changed: 116 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ Almost every `userEvent` method inherits its provider options. To see all availa
3737

3838
## userEvent.setup
3939

40-
- **Type:** `() => UserEvent`
40+
```ts
41+
function setup(): UserEvent
42+
```
4143

4244
Creates a new user event instance. This is useful if you need to keep the state of keyboard to press and release buttons correctly.
4345

@@ -60,7 +62,12 @@ This behaviour is more useful because we do not emulate the keyboard, we actuall
6062

6163
## userEvent.click
6264

63-
- **Type:** `(element: Element | Locator, options?: UserEventClickOptions) => Promise<void>`
65+
```ts
66+
function click(
67+
element: Element | Locator,
68+
options?: UserEventClickOptions,
69+
): Promise<void>
70+
```
6471

6572
Click on an element. Inherits provider's options. Please refer to your provider's documentation for detailed explanation about how this method works.
6673

@@ -84,7 +91,12 @@ References:
8491

8592
## userEvent.dblClick
8693

87-
- **Type:** `(element: Element | Locator, options?: UserEventDoubleClickOptions) => Promise<void>`
94+
```ts
95+
function dblClick(
96+
element: Element | Locator,
97+
options?: UserEventDoubleClickOptions,
98+
): Promise<void>
99+
```
88100

89101
Triggers a double click event on an element.
90102

@@ -110,7 +122,12 @@ References:
110122

111123
## userEvent.tripleClick
112124

113-
- **Type:** `(element: Element | Locator, options?: UserEventTripleClickOptions) => Promise<void>`
125+
```ts
126+
function tripleClick(
127+
element: Element | Locator,
128+
options?: UserEventTripleClickOptions,
129+
): Promise<void>
130+
```
114131

115132
Triggers a triple click event on an element. Since there is no `tripleclick` in browser api, this method will fire three click events in a row, and so you must check [click event detail](https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event#usage_notes) to filter the event: `evt.detail === 3`.
116133

@@ -144,7 +161,12 @@ References:
144161

145162
## userEvent.fill
146163

147-
- **Type:** `(element: Element | Locator, text: string) => Promise<void>`
164+
```ts
165+
function fill(
166+
element: Element | Locator,
167+
text: string,
168+
): Promise<void>
169+
```
148170

149171
Set a value to the `input/textarea/conteneditable` field. This will remove any existing text in the input before setting the new value.
150172

@@ -179,7 +201,9 @@ References:
179201

180202
## userEvent.keyboard
181203

182-
- **Type:** `(text: string) => Promise<void>`
204+
```ts
205+
function keyboard(text: string): Promise<void>
206+
```
183207

184208
The `userEvent.keyboard` allows you to trigger keyboard strokes. If any input has a focus, it will type characters into that input. Otherwise, it will trigger keyboard events on the currently focused element (`document.body` if there are no focused elements).
185209

@@ -205,7 +229,9 @@ References:
205229

206230
## userEvent.tab
207231

208-
- **Type:** `(options?: UserEventTabOptions) => Promise<void>`
232+
```ts
233+
function tab(options?: UserEventTabOptions): Promise<void>
234+
```
209235

210236
Sends a `Tab` key event. This is a shorthand for `userEvent.keyboard('{tab}')`.
211237

@@ -235,10 +261,16 @@ References:
235261

236262
## userEvent.type
237263

238-
- **Type:** `(element: Element | Locator, text: string, options?: UserEventTypeOptions) => Promise<void>`
264+
```ts
265+
function type(
266+
element: Element | Locator,
267+
text: string,
268+
options?: UserEventTypeOptions,
269+
): Promise<void>
270+
```
239271

240272
::: warning
241-
If you don't rely on [special characters](https://testing-library.com/docs/user-event/keyboard) (e.g., `{shift}` or `{selectall}`), it is recommended to use [`userEvent.fill`](#userevent-fill) instead.
273+
If you don't rely on [special characters](https://testing-library.com/docs/user-event/keyboard) (e.g., `{shift}` or `{selectall}`), it is recommended to use [`userEvent.fill`](#userevent-fill) instead for better performance.
242274
:::
243275

244276
The `type` method implements `@testing-library/user-event`'s [`type`](https://testing-library.com/docs/user-event/utility/#type) utility built on top of [`keyboard`](https://testing-library.com/docs/user-event/keyboard) API.
@@ -271,7 +303,9 @@ References:
271303
272304
## userEvent.clear
273305
274-
- **Type:** `(element: Element | Locator) => Promise<void>`
306+
```ts
307+
function clear(element: Element | Locator): Promise<void>
308+
```
275309

276310
This method clears the input element content.
277311

@@ -300,7 +334,19 @@ References:
300334
301335
## userEvent.selectOptions
302336
303-
- **Type:** `(element: Element | Locator, values: HTMLElement | HTMLElement[] | Locator | Locator[] | string | string[], options?: UserEventSelectOptions) => Promise<void>`
337+
```ts
338+
function selectOptions(
339+
element: Element | Locator,
340+
values:
341+
| HTMLElement
342+
| HTMLElement[]
343+
| Locator
344+
| Locator[]
345+
| string
346+
| string[],
347+
options?: UserEventSelectOptions,
348+
): Promise<void>
349+
```
304350

305351
The `userEvent.selectOptions` allows selecting a value in a `<select>` element.
306352

@@ -345,7 +391,12 @@ References:
345391

346392
## userEvent.hover
347393

348-
- **Type:** `(element: Element | Locator, options?: UserEventHoverOptions) => Promise<void>`
394+
```ts
395+
function hover(
396+
element: Element | Locator,
397+
options?: UserEventHoverOptions,
398+
): Promise<void>
399+
```
349400

350401
This method moves the cursor position to the selected element. Please refer to your provider's documentation for detailed explanation about how this method works.
351402

@@ -363,7 +414,7 @@ test('hovers logo element', async () => {
363414
364415
await userEvent.hover(logo)
365416
// or you can access it directly on the locator
366-
await page.hover()
417+
await logo.hover()
367418
})
368419
```
369420

@@ -375,7 +426,12 @@ References:
375426

376427
## userEvent.unhover
377428

378-
- **Type:** `(element: Element | Locator, options?: UserEventHoverOptions) => Promise<void>`
429+
```ts
430+
function unhover(
431+
element: Element | Locator,
432+
options?: UserEventHoverOptions,
433+
): Promise<void>
434+
```
379435

380436
This works the same as [`userEvent.hover`](#userevent-hover), but moves the cursor to the `document.body` element instead.
381437

@@ -391,7 +447,7 @@ test('unhover logo element', async () => {
391447
392448
await userEvent.unhover(logo)
393449
// or you can access it directly on the locator
394-
await page.unhover()
450+
await logo.unhover()
395451
})
396452
```
397453

@@ -401,9 +457,53 @@ References:
401457
- [WebdriverIO `element.moveTo` API](https://webdriver.io/docs/api/element/moveTo/)
402458
- [testing-library `hover` API](https://testing-library.com/docs/user-event/convenience/#hover)
403459

460+
## userEvent.upload
461+
462+
```ts
463+
function upload(
464+
element: Element | Locator,
465+
files: string[] | string | File[] | File,
466+
): Promise<void>
467+
```
468+
469+
Change a file input element to have the specified files.
470+
471+
```ts
472+
import { page, userEvent } from '@vitest/browser/context'
473+
474+
test('can upload a file', async () => {
475+
const input = page.getByRole('button', { name: /Upload files/ })
476+
477+
const file = new File(['file'], 'file.png', { type: 'image/png' })
478+
479+
await userEvent.upload(input, file)
480+
// or you can access it directly on the locator
481+
await input.upload(file)
482+
483+
// you can also use file paths relative to the test file
484+
await userEvent.upload(input, '../fixtures/file.png')
485+
})
486+
```
487+
488+
::: warning
489+
`webdriverio` provider supports this command only in `chrome` and `edge` browsers. It also only supports string types at the moment.
490+
:::
491+
492+
References:
493+
494+
- [Playwright `locator.setInputFiles` API](https://playwright.dev/docs/api/class-locator#locator-set-input-files)
495+
- [WebdriverIO `browser.uploadFile` API](https://webdriver.io/docs/api/browser/uploadFile)
496+
- [testing-library `upload` API](https://testing-library.com/docs/user-event/utility/#upload)
497+
404498
## userEvent.dragAndDrop
405499

406-
- **Type:** `(source: Element | Locator, target: Element | Locator, options?: UserEventDragAndDropOptions) => Promise<void>`
500+
```ts
501+
function dragAndDrop(
502+
source: Element | Locator,
503+
target: Element | Locator,
504+
options?: UserEventDragAndDropOptions,
505+
): Promise<void>
506+
```
407507

408508
Drags the source element on top of the target element. Don't forget that the `source` element has to have the `draggable` attribute set to `true`.
409509

0 commit comments

Comments
 (0)