Passer au contenu

Locateurs <Version>2.1.0</Version>

Un locateur est une représentation d’un élément ou d’un certain nombre d’éléments. Chaque locateur est défini par une chaîne appelée sélecteur. Vitest abstrait ce sélecteur en fournissant des méthodes pratiques qui génèrent ces sélecteurs en arrière-plan.

L’API de locateur utilise un fork des locateurs de Playwright appelé Ivya. Cependant, Vitest fournit cette API à chaque fournisseur.

getByRole

  • Type : (role: ARIARole | string, options?: LocatorByRoleOptions) => Locator

Crée une manière de localiser un élément par son rôle ARIA, attributs ARIA et nom accessible.

Considérez la structure DOM suivante.

<h3>S'inscrire</h3>
<label>
Login
<input type="text" />
</label>
<label>
Mot de passe
<input type="password" />
</label>
<br/>
<button>Soumettre</button>

Vous pouvez localiser chaque élément par son rôle implicite :

await expect.element(
page.getByRole('heading', { name: 'S\'inscrire' })
).toBeVisible()
await page.getByRole('textbox', { name: 'Login' }).fill('admin')
await page.getByRole('textbox', { name: 'Mot de passe' }).fill('admin')
await page.getByRole('button', { name: /soumettre/i }).click()
Options
  • exact: boolean

    Indique si le name est apparié exactement : sensible à la casse et chaîne entière. Désactivé par défaut. Cette option est ignorée si name est une expression régulière. Notez que la correspondance exacte enlève toujours les espaces.

    <button>Bonjour le monde</button>
    page.getByRole('button', { name: 'bonjour le monde' }) // ✅
    page.getByRole('button', { name: 'bonjour le monde', exact: true }) // ❌
    page.getByRole('button', { name: 'Bonjour le monde', exact: true }) // ✅
  • checked: boolean

    Les éléments cochés (définis par aria-checked ou <input type="checkbox"/>) doivent-ils être inclus ou non. Par défaut, le filtre n’est pas appliqué.

    Consultez aria-checked pour plus d’informations.

    <>
    <button role="checkbox" aria-checked="true" />
    <input type="checkbox" checked />
    </>
    page.getByRole('checkbox', { checked: true }) // ✅
    page.getByRole('checkbox', { checked: false }) // ❌
  • disabled: boolean

    Les éléments désactivés doivent-ils être inclus ou non. Par défaut, le filtre n’est pas appliqué. Notez qu’à la différence des autres attributs, l’état disable est hérité.

    Consultez aria-disabled pour plus d’informations.

    <input type="text" disabled />
    page.getByRole('textbox', { disabled: true }) // ✅
    page.getByRole('textbox', { disabled: false }) // ❌
  • expanded: boolean

    Les éléments étendus doivent-ils être inclus ou non. Par défaut, le filtre n’est pas appliqué.

    Consultez aria-expanded pour plus d’informations.

    <a aria-expanded="true" href="example.com">Lien</a>
    page.getByRole('link', { expanded: true }) // ✅
    page.getByRole('link', { expanded: false }) // ❌
  • includeHidden: boolean

    Les éléments qui sont normalement exclus de l’arbre d’accessibilité doivent-ils être interrogés. Par défaut, seuls les éléments non cachés sont appariés par le sélecteur de rôle.

    Notez que les rôles none et presentation sont toujours inclus.

    <button style="display: none" />
    page.getByRole('button') // ❌
    page.getByRole('button', { includeHidden: false }) // ❌
    page.getByRole('button', { includeHidden: true }) // ✅
  • level: number

    Un attribut numérique qui est généralement présent pour les rôles heading, listitem, row, treeitem, avec des valeurs par défaut pour les éléments <h1>-<h6>. Par défaut, le filtre n’est pas appliqué.

    Consultez aria-level pour plus d’informations.

    <>
    <h1>Titre de Niveau Un</h1>
    <div role="heading" aria-level="1">Deuxième Titre de Niveau Un</div>
    </>
    page.getByRole('heading', { level: 1 }) // ✅
    page.getByRole('heading', { level: 2 }) // ❌
  • name: string | RegExp

    Un nom accessible. Par défaut, la correspondance est insensible à la casse et recherche une sous-chaîne. Utilisez l’option exact pour contrôler ce comportement.

    <button>Cliquez moi !</button>
    page.getByRole('button', { name: 'Cliquez moi !' }) // ✅
    page.getByRole('button', { name: 'cliquez moi !' }) // ✅
    page.getByRole('button', { name: 'Cliquez moi ?' }) // ❌
  • pressed: boolean

    Les éléments pressés doivent-ils être inclus ou non. Par défaut, le filtre n’est pas appliqué.

    Consultez aria-pressed pour plus d’informations.

    <button aria-pressed="true">👍</button>
    page.getByRole('button', { pressed: true }) // ✅
    page.getByRole('button', { pressed: false }) // ❌
  • selected: boolean

    Les éléments sélectionnés doivent-ils être inclus ou non. Par défaut, le filtre n’est pas appliqué.

    Consultez aria-selected pour plus d’informations.

    <button role="tab" aria-selected="true">Vue</button>
    page.getByRole('button', { selected: true }) // ✅
    page.getByRole('button', { selected: false }) // ❌
Voir aussi

getByAltText

  • Type : (text: string | RegExp, options?: LocatorOptions) => Locator

Crée un locateur capable de trouver un élément avec un attribut alt qui correspond au texte. Contrairement à l’implémentation de testing-library, Vitest fera correspondre tout élément ayant un attribut alt correspondant.

<img alt="Affiche des Incredibles 2" src="/incredibles-2.png" />
page.getByAltText(/incredibles.*? affiche/i) // ✅
page.getByAltText('texte alt non existant') // ❌

Options

  • exact: boolean

    Indique si le text est apparié exactement : sensible à la casse et chaîne entière. Désactivé par défaut. Cette option est ignorée si text est une expression régulière. Notez que la correspondance exacte enlève toujours les espaces.

Voir aussi

getByLabelText

  • Type : (text: string | RegExp, options?: LocatorOptions) => Locator

Crée un locateur capable de trouver un élément qui a une étiquette associée.

Le locateur page.getByLabelText('Nom d'utilisateur') trouvera chaque entrée dans l’exemple ci-dessous :

// Relation for/htmlFor entre étiquette et id de l'élément de formulaire
<label for="username-input">Nom d'utilisateur</label>
<input id="username-input" />
// L'attribut aria-labelledby avec les éléments de formulaire
<label id="username-label">Nom d'utilisateur</label>
<input aria-labelledby="username-label" />
// Étiquettes enveloppantes
<label>Nom d'utilisateur <input /></label>
// Étiquettes enveloppantes où le texte de l'étiquette est dans un autre élément enfant
<label>
<span>Nom d'utilisateur</span>
<input />
</label>
// Attributs aria-label
// Faites attention car ce n'est pas une étiquette que les utilisateurs peuvent voir sur la page,
// donc le but de votre entrée doit être évident pour les utilisateurs visuels.
<input aria-label="Nom d'utilisateur" />

Options

  • exact: boolean

    Indique si le text est apparié exactement : sensible à la casse et chaîne entière. Désactivé par défaut. Cette option est ignorée si text est une expression régulière. Notez que la correspondance exacte enlève toujours les espaces.

Voir aussi

getByPlaceholder

  • Type : (text: string | RegExp, options?: LocatorOptions) => Locator

Crée un locateur capable de trouver un élément qui a l’attribut placeholder spécifié. Vitest fera correspondre tout élément qui a un attribut placeholder correspondant, pas seulement input.

<input placeholder="Nom d'utilisateur" />
page.getByPlaceholder('Nom d'utilisateur') //
page.getByPlaceholder('introuvable') // ❌

Options

  • exact: boolean

    Indique si le text est apparié exactement : sensible à la casse et chaîne entière. Désactivé par défaut. Cette option est ignorée si text est une expression régulière. Notez que la correspondance exacte enlève toujours les espaces.

Voir aussi

getByText

  • Type : (text: string | RegExp, options?: LocatorOptions) => Locator

Crée un locateur capable de trouver un élément contenant le texte spécifié. Le texte sera comparé à nodeValue du TextNode ou à la valeur d’un input si le type est button ou reset. La correspondance par texte normalise toujours les espaces, même avec une correspondance exacte. Par exemple, cela transforme plusieurs espaces en un, transforme les sauts de ligne en espaces et ignore les espaces de tête et de fin.

<a href="/about">À propos ℹ️</a>
page.getByText(/à propos/i) // ✅
page.getByText('à propos', { exact: true }) // ❌

Options

  • exact: boolean

    Indique si le text est apparié exactement : sensible à la casse et chaîne entière. Désactivé par défaut. Cette option est ignorée si text est une expression régulière. Notez que la correspondance exacte enlève toujours les espaces.

Voir aussi

getByTitle

  • Type : (text: string | RegExp, options?: LocatorOptions) => Locator

Crée un locateur capable de trouver un élément qui a l’attribut title spécifié. Contrairement à getByTitle de testing-library, Vitest ne peut pas trouver d’éléments title dans un SVG.

<span title="Supprimer" id="2"></span>
page.getByTitle('Supprimer') // ✅
page.getByTitle('Créer') // ❌

Options

  • exact: boolean

    Indique si le text est apparié exactement : sensible à la casse et chaîne entière. Désactivé par défaut. Cette option est ignorée si text est une expression régulière. Notez que la correspondance exacte enlève toujours les espaces.

Voir aussi

getByTestId

  • Type : (text: string | RegExp) => Locator

Crée un locateur capable de trouver un élément qui correspond à l’attribut d’identifiant de test spécifié. Vous pouvez configurer le nom de l’attribut avec browser.locators.testIdAttribute.

<div data-testid="élément-personnalisé" />
page.getByTestId('élément-personnalisé') // ✅
page.getByTestId('élément-non-existant') // ❌

Options

  • exact: boolean

    Indique si le text est apparié exactement : sensible à la casse et chaîne entière. Désactivé par défaut. Cette option est ignorée si text est une expression régulière. Notez que la correspondance exacte enlève toujours les espaces.

Voir aussi

Méthodes

click

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

Cliquez sur un élément. Vous pouvez utiliser les options pour définir la position du curseur.

import { page } from '@vitest/browser/context'
await page.getByRole('img', { name: 'Rose' }).click()

dblClick

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

Déclenche un événement de double clic sur un élément. Vous pouvez utiliser les options pour définir la position du curseur.

import { page } from '@vitest/browser/context'
await page.getByRole('img', { name: 'Rose' }).dblClick()

tripleClick

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

Déclenche un événement de triple clic sur un élément. Comme il n’y a pas de tripleclick dans l’API du navigateur, cette méthode déclenchera trois événements de clic consécutifs.

import { page } from '@vitest/browser/context'
await page.getByRole('img', { name: 'Rose' }).tripleClick()

clear

  • Type : () => Promise<void>

Efface le contenu de l’élément d’entrée.

import { page } from '@vitest/browser/context'
await page.getByRole('textbox', { name: 'Nom complet' }).clear()

hover

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

Déplace la position du curseur vers l’élément sélectionné.

import { page } from '@vitest/browser/context'
await page.getByRole('img', { name: 'Rose' }).hover()

unhover

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

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

import { page } from '@vitest/browser/context'
await page.getByRole('img', { name: 'Rose' }).unhover()

fill

  • Type : (text: string, options?: UserEventFillOptions) => Promise<void>

Définit la valeur de l’élément input, textarea ou conteneditable actuel.

import { page } from '@vitest/browser/context'
await page.getByRole('input', { name: 'Nom complet' }).fill('M. Bean')

dropTo

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

Fait glisser l’élément actuel vers l’emplacement cible.

import { page } from '@vitest/browser/context'
const paris = page.getByText('Paris')
const france = page.getByText('France')
await paris.dropTo(france)

selectOptions

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

Choisissez une ou plusieurs valeurs d’un élément <select>.

import { page } from '@vitest/browser/context'
const languages = page.getByRole('select', { name: 'Langues' })
await languages.selectOptions('EN')
await languages.selectOptions(['ES', 'FR'])
await languages.selectOptions([
languages.getByRole('option', { name: 'Espagnol' }),
languages.getByRole('option', { name: 'Français' }),
])

screenshot

  • Type : (options?: LocatorScreenshotOptions) => Promise<string | { path: string; base64: string }>

Crée une capture d’écran de l’élément correspondant au sélecteur du locateur.

Vous pouvez spécifier l’emplacement de sauvegarde de la capture d’écran en utilisant l’option path, qui est relative au fichier de test actuel. Si l’option path n’est pas définie, Vitest utilisera par défaut browser.screenshotDirectory (__screenshot__ par défaut), ainsi que les noms du fichier et du test pour déterminer le chemin d’accès à la capture d’écran.

Si vous avez également besoin du contenu de la capture d’écran, vous pouvez spécifier base64: true pour le retourner avec le chemin d’accès où la capture d’écran est enregistrée.

import { page } from '@vitest/browser/context'
const button = page.getByRole('button', { name: 'Cliquez moi !' })
const path = await button.screenshot()
const { path, base64 } = await button.screenshot({
path: './bouton-cliquez-moi.png',
base64: true, // retourner également la chaîne base64
})
// path - chemin complet vers la capture d'écran
// base64 - chaîne encodée en base64 de la capture d'écran

query

  • Type : () => Element | null

Cette méthode retourne un seul élément correspondant au sélecteur du locateur ou null si aucun élément n’est trouvé.

Si plusieurs éléments correspondent au sélecteur, cette méthode générera une erreur. Utilisez .elements() lorsque vous avez besoin de tous les éléments DOM correspondants ou .all() si vous avez besoin d’un tableau de locateurs correspondants au sélecteur.

Considérez la structure DOM suivante :

<div>Bonjour <span>Monde</span></div>
<div>Bonjour</div>

Ces locateurs ne généreront pas d’erreur :

page.getByText('Bonjour Monde').query() // ✅ HTMLDivElement
page.getByText('Bonjour Allemagne').query() // ✅ null
page.getByText('Monde').query() // ✅ HTMLSpanElement
page.getByText('Bonjour', { exact: true }).query() // ✅ HTMLSpanElement

Ces locateurs généreront une erreur :

// renvoie plusieurs éléments
page.getByText('Bonjour').query() // ❌
page.getByText(/^Bonjour/).query() // ❌

element

  • Type : () => Element

Cette méthode retourne un seul élément correspondant au sélecteur du locateur.

Si aucun élément ne correspond au sélecteur, une erreur est générée. Envisagez d’utiliser .query() lorsque vous devez juste vérifier si l’élément existe.

Si plusieurs éléments correspondent au sélecteur, une erreur est générée. Utilisez .elements() lorsque vous avez besoin de tous les éléments DOM correspondants ou .all() si vous avez besoin d’un tableau de locateurs correspondants au sélecteur.

Considérez la structure DOM suivante :

<div>Bonjour <span>Monde</span></div>
<div>Bonjour Allemagne</div>
<div>Bonjour</div>

Ces locateurs ne généreront pas d’erreur :

page.getByText('Bonjour Monde').element() // ✅
page.getByText('Bonjour Allemagne').element() // ✅
page.getByText('Monde').element() // ✅
page.getByText('Bonjour', { exact: true }).element() // ✅

Ces locateurs généreront une erreur :

// renvoie plusieurs éléments
page.getByText('Bonjour').element() // ❌
page.getByText(/^Bonjour/).element() // ❌
// ne retourne aucun élément
page.getByText('Bonjour USA').element() // ❌

elements

  • Type : () => Element[]

Cette méthode retourne un tableau d’éléments correspondant au sélecteur du locateur.

Cette fonction ne déclenche jamais une erreur. S’il n’y a pas d’éléments correspondant au sélecteur, cette méthode renverra un tableau vide.

Considérez la structure DOM suivante :

<div>Bonjour <span>Monde</span></div>
<div>Bonjour</div>

Ces locateurs réussiront toujours :

page.getByText('Bonjour Monde').elements() // ✅ [HTMLElement]
page.getByText('Monde').elements() // ✅ [HTMLElement]
page.getByText('Bonjour', { exact: true }).elements() // ✅ [HTMLElement]
page.getByText('Bonjour').element() // ✅ [HTMLElement, HTMLElement]
page.getByText('Bonjour USA').elements() // ✅ []

all

  • Type : () => Locator[]

Cette méthode retourne un tableau de nouveaux locateurs qui correspondent au sélecteur.

Cette méthode appelle en interne .elements et enveloppe chaque élément en utilisant page.elementLocator.