Passer au contenu

API d’interactivité

Vitest implémente un sous-ensemble des API @testing-library/user-event en utilisant le Chrome DevTools Protocol ou webdriver au lieu de simuler des événements, ce qui rend le comportement du navigateur plus fiable et cohérent avec la façon dont les utilisateurs interagissent avec une page.

import { userEvent } from '@vitest/browser/context'
await userEvent.click(document.querySelector('.button'))

Presque chaque méthode userEvent hérite de ses options de fournisseur. Pour voir toutes les options disponibles dans votre IDE, ajoutez les types webdriver ou playwright (en fonction de votre fournisseur) à votre fichier tsconfig.json :

{
"compilerOptions": {
"types": [
"@vitest/browser/providers/playwright"
]
}
}

userEvent.setup

  • Type: () => UserEvent

Crée une nouvelle instance d’événement utilisateur. Cela est utile si vous devez garder l’état du clavier pour appuyer et relâcher correctement les boutons.

userEvent.click

  • Type: (element: Element | Locator, options?: UserEventClickOptions) => Promise<void>

Clique sur un élément. Hérite des options du fournisseur. Veuillez vous référer à la documentation de votre fournisseur pour une explication détaillée sur le fonctionnement de cette méthode.

import { page, userEvent } from '@vitest/browser/context'
test('clique sur un élément', async () => {
const logo = page.getByRole('img', { name: /logo/ })
await userEvent.click(logo)
// ou vous pouvez y accéder directement via le localisateur
await logo.click()
})

Références :

userEvent.dblClick

  • Type: (element: Element | Locator, options?: UserEventDoubleClickOptions) => Promise<void>

Déclenche un événement de double clic sur un élément.

Veuillez vous référer à la documentation de votre fournisseur pour une explication détaillée sur le fonctionnement de cette méthode.

import { page, userEvent } from '@vitest/browser/context'
test('déclenche un double clic sur un élément', async () => {
const logo = page.getByRole('img', { name: /logo/ })
await userEvent.dblClick(logo)
// ou vous pouvez y accéder directement via le localisateur
await logo.dblClick()
})

Références :

userEvent.tripleClick

  • Type: (element: Element | Locator, options?: UserEventTripleClickOptions) => Promise<void>

Déclenche un événement de triple clic sur un élément. Étant donné qu’il n’y a pas de tripleclick dans l’API du navigateur, cette méthode déclenchera trois événements de clic consécutifs, vous devez donc vérifier le détail de l’événement click pour filtrer l’événement : evt.detail === 3.

Veuillez vous référer à la documentation de votre fournisseur pour une explication détaillée sur le fonctionnement de cette méthode.

import { page, userEvent } from '@vitest/browser/context'
test('déclenche un triple clic sur un élément', async () => {
const logo = page.getByRole('img', { name: /logo/ })
let tripleClickFired = false
logo.addEventListener('click', (evt) => {
if (evt.detail === 3) {
tripleClickFired = true
}
})
await userEvent.tripleClick(logo)
// ou vous pouvez y accéder directement via le localisateur
await logo.tripleClick()
expect(tripleClickFired).toBe(true)
})

Références :

userEvent.fill

  • Type: (element: Element | Locator, text: string) => Promise<void>

Définissez une valeur au champ input/textarea/conteneditable. Cela supprimera tout texte existant dans l’entrée avant de définir la nouvelle valeur.

import { page, userEvent } from '@vitest/browser/context'
test('met à jour l\'input', async () => {
const input = page.getByRole('input')
await userEvent.fill(input, 'foo') // input.value == foo
await userEvent.fill(input, '{{a[[') // input.value == {{a[[
await userEvent.fill(input, '{Shift}') // input.value == {Shift}
// ou vous pouvez y accéder directement via le localisateur
await input.fill('foo') // input.value == foo
})

Cette méthode met l’élément au point, le remplit et déclenche un événement input après le remplissage. Vous pouvez utiliser une chaîne vide pour effacer le champ.

Références :

userEvent.keyboard

  • Type: (text: string) => Promise<void>

Le userEvent.keyboard vous permet de déclencher des frappes au clavier. Si un champ a le focus, cela tapera des caractères dans ce champ. Sinon, cela déclenchera des événements de clavier sur l’élément actuellement focalisé (document.body s’il n’y a aucun élément focalisé).

Cette API supporte la syntaxe keyboard de user-event.

import { userEvent } from '@vitest/browser/context'
test('déclenche des frappes', async () => {
await userEvent.keyboard('foo') // se traduit par : f, o, o
await userEvent.keyboard('{{a[[') // se traduit par : {, a, [
await userEvent.keyboard('{Shift}{f}{o}{o}') // se traduit par : Shift, f, o, o
await userEvent.keyboard('{a>5}') // appuie sur a sans le relâcher et déclenche 5 keydown
await userEvent.keyboard('{a>5/}') // appuie sur a pour 5 keydown puis le relâche
})

Références :

userEvent.tab

  • Type: (options?: UserEventTabOptions) => Promise<void>

Envoie un événement de touche Tab. C’est un raccourci pour userEvent.keyboard('{tab}').

import { page, userEvent } from '@vitest/browser/context'
test('la touche tab fonctionne', async () => {
const [input1, input2] = page.getByRole('input').elements()
expect(input1).toHaveFocus()
await userEvent.tab()
expect(input2).toHaveFocus()
await userEvent.tab({ shift: true })
expect(input1).toHaveFocus()
})

Références :

userEvent.type

  • Type: (element: Element | Locator, text: string, options?: UserEventTypeOptions) => Promise<void>

La méthode type implémente l’utilitaire type de @testing-library/user-event construit sur l’API keyboard.

Cette fonction vous permet de taper des caractères dans un élément input/textarea/conteneditable. Elle supporte la syntaxe keyboard de user-event.

Si vous avez juste besoin d’appuyer sur des caractères sans un champ d’entrée, utilisez l’API userEvent.keyboard.

import { page, userEvent } from '@vitest/browser/context'
test('met à jour l\'input', async () => {
const input = page.getByRole('input')
await userEvent.type(input, 'foo') // input.value == foo
await userEvent.type(input, '{{a[[') // input.value == foo{a[
await userEvent.type(input, '{Shift}') // input.value == foo{a[
})

Vitest n’expose pas la méthode .type sur le localisateur comme input.type car elle n’existe que pour des raisons de compatibilité avec la bibliothèque userEvent. Il est recommandé d’utiliser .fill à la place, car elle est plus rapide.

Références :

userEvent.clear

  • Type: (element: Element | Locator) => Promise<void>

Cette méthode efface le contenu de l’élément input.

import { page, userEvent } from '@vitest/browser/context'
test('efface l\'input', async () => {
const input = page.getByRole('input')
await userEvent.fill(input, 'foo')
expect(input).toHaveValue('foo')
await userEvent.clear(input)
// ou vous pouvez y accéder directement via le localisateur
await input.clear()
expect(input).toHaveValue('')
})

Références :

userEvent.selectOptions

  • Type: (element: Element | Locator, values: HTMLElement | HTMLElement[] | Locator | Locator[] | string | string[], options?: UserEventSelectOptions) => Promise<void>

Le userEvent.selectOptions permet de sélectionner une valeur dans un élément <select>.

import { page, userEvent } from '@vitest/browser/context'
test('efface l\'input', async () => {
const select = page.getByRole('select')
await userEvent.selectOptions(select, 'Option 1')
// ou vous pouvez y accéder directement via le localisateur
await select.selectOptions('Option 1')
expect(select).toHaveValue('option-1')
await userEvent.selectOptions(select, 'option-1')
expect(select).toHaveValue('option-1')
await userEvent.selectOptions(select, [
page.getByRole('option', { name: 'Option 1' }),
page.getByRole('option', { name: 'Option 2' }),
])
expect(select).toHaveValue(['option-1', 'option-2'])
})

Références :

userEvent.hover

  • Type: (element: Element | Locator, options?: UserEventHoverOptions) => Promise<void>

Cette méthode déplace la position du curseur vers l’élément sélectionné. Veuillez vous référer à la documentation de votre fournisseur pour une explication détaillée sur le fonctionnement de cette méthode.

import { page, userEvent } from '@vitest/browser/context'
test('survole l\'élément logo', async () => {
const logo = page.getByRole('img', { name: /logo/ })
await userEvent.hover(logo)
// ou vous pouvez y accéder directement via le localisateur
await page.hover()
})

Références :

userEvent.unhover

  • Type: (element: Element | Locator, options?: UserEventHoverOptions) => Promise<void>

Cela fonctionne de la même manière que userEvent.hover, mais déplace le curseur vers l’élément document.body à la place.

import { page, userEvent } from '@vitest/browser/context'
test('ne survole plus l\'élément logo', async () => {
const logo = page.getByRole('img', { name: /logo/ })
await userEvent.unhover(logo)
// ou vous pouvez y accéder directement via le localisateur
await page.unhover()
})

Références :

userEvent.dragAndDrop

  • Type: (source: Element | Locator, target: Element | Locator, options?: UserEventDragAndDropOptions) => Promise<void>

Fait glisser l’élément source sur l’élément cible. N’oubliez pas que l’élément source doit avoir l’attribut draggable défini sur true.

import { page, userEvent } from '@vitest/browser/context'
test('le glisser-déposer fonctionne', async () => {
const source = page.getByRole('img', { name: /logo/ })
const target = page.getByTestId('logo-target')
await userEvent.dragAndDrop(source, target)
// ou vous pouvez y accéder directement via le localisateur
await source.dropTo(target)
await expect.element(target).toHaveTextContent('Logo est traité')
})

Références :