Localisateurs 2.1.0+
Un localisateur représente un élément ou un ensemble d'éléments. Chaque localisateur est défini par une chaîne appelée sélecteur. Vitest simplifie l'utilisation de ces sélecteurs en fournissant des méthodes pratiques qui les génèrent en arrière-plan.
L'API de localisateur utilise un fork des localisateurs de Playwright nommé Ivya. Cependant, Vitest rend cette API disponible pour chaque fournisseur.
getByRole
function getByRole(
role: ARIARole | string,
options?: LocatorByRoleOptions
): Locator;
Crée un localisateur pour trouver un élément en fonction de son rôle ARIA, de ses attributs ARIA et de son nom accessible.
TIP
Si vous cherchez un seul élément avec getByText('Le nom')
, il est souvent préférable d'utiliser getByRole(roleAttendu, { name: 'Le nom' })
. La recherche par nom accessible ne remplace pas les autres types de requêtes comme *ByAltText
ou *ByTitle
. Bien que le nom accessible puisse être identique à ces attributs, il ne remplace pas leur fonctionnalité spécifique.
Considérez la structure DOM suivante :
<h3>Sign up</h3>
<label>
Login
<input type="text" />
</label>
<label>
Password
<input type="password" />
</label>
<br />
<button>Submit</button>
Vous pouvez localiser chaque élément par son rôle implicite :
await expect
.element(page.getByRole('heading', { name: 'Sign up' }))
.toBeVisible();
await page.getByRole('textbox', { name: 'Login' }).fill('admin');
await page.getByRole('textbox', { name: 'Password' }).fill('admin');
await page.getByRole('button', { name: /submit/i }).click();
WARNING
Les rôles sont mis en correspondance par égalité de chaîne, sans tenir compte de la hiérarchie des rôles ARIA. Par conséquent, interroger un rôle de superclasse comme checkbox
n'inclura pas les éléments avec un rôle de sous-classe comme switch
.
Par défaut, de nombreux éléments sémantiques en HTML ont un rôle ; par exemple, <input type="radio">
a le rôle "radio". Les éléments non sémantiques en HTML n'ont pas de rôle ; <div>
et <span>
sans sémantique ajoutée renvoient null
. L'attribut role
peut ajouter de la sémantique.
Fournir des rôles via les attributs role
ou aria-*
aux éléments natifs qui ont déjà un rôle implicite est fortement déconseillé par les directives ARIA.
Options
exact: boolean
Indique si le
name
doit correspondre exactement : sensible à la casse et à la chaîne entière. Désactivé par défaut. Cette option est ignorée siname
est une expression régulière. Notez que la correspondance exacte supprime toujours les espaces blancs.tsx<button>Hello World</button>; page.getByRole('button', { name: 'hello world' }); // ✅ page.getByRole('button', { name: 'hello world', exact: true }); // ❌ page.getByRole('button', { name: 'Hello World', exact: true }); // ✅
checked: boolean
Indique si les éléments cochés (définis par
aria-checked
ou<input type="checkbox"/>
) doivent être inclus ou non. Par défaut, ce filtre n'est pas appliqué.Voir
aria-checked
pour plus d'informations.tsx<> <button role="checkbox" aria-checked="true" /> <input type="checkbox" checked /> </>; page.getByRole('checkbox', { checked: true }); // ✅ page.getByRole('checkbox', { checked: false }); // ❌
disabled: boolean
Indique si les éléments désactivés doivent être inclus ou non. Par défaut, ce filtre n'est pas appliqué. Notez que contrairement aux autres attributs, l'état
disabled
est hérité.Voir
aria-disabled
pour plus d'informations.tsx<input type="text" disabled />; page.getByRole('textbox', { disabled: true }); // ✅ page.getByRole('textbox', { disabled: false }); // ❌
expanded: boolean
Indique si les éléments développés doivent être inclus ou non. Par défaut, ce filtre n'est pas appliqué.
Voir
aria-expanded
pour plus d'informations.tsx<a aria-expanded="true" href="example.com"> Link </a>; page.getByRole('link', { expanded: true }); // ✅ page.getByRole('link', { expanded: false }); // ❌
includeHidden: boolean
Indique si les éléments qui sont normalement exclus de l'arbre d'accessibilité doivent être recherchés. Par défaut, seuls les éléments visibles sont mis en correspondance par le sélecteur de rôle.
Notez que les rôles
none
etpresentation
sont toujours inclus.tsx<button style="display: none" />; page.getByRole('button'); // ❌ page.getByRole('button', { includeHidden: false }); // ❌ page.getByRole('button', { includeHidden: true }); // ✅
level: number
Un attribut numérique 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, ce filtre n'est pas appliqué.Voir
aria-level
pour plus d'informations.tsx<> <h1>Heading Level One</h1> <div role="heading" aria-level="1"> Second Heading Level One </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.tsx<button>Click Me!</button>; page.getByRole('button', { name: 'Click Me!' }); // ✅ page.getByRole('button', { name: 'click me!' }); // ✅ page.getByRole('button', { name: 'Click Me?' }); // ❌
pressed: boolean
Indique si les éléments pressés doivent être inclus ou non. Par défaut, ce filtre n'est pas appliqué.
Voir
aria-pressed
pour plus d'informations.tsx<button aria-pressed="true">👍</button>; page.getByRole('button', { pressed: true }); // ✅ page.getByRole('button', { pressed: false }); // ❌
selected: boolean
Indique si les éléments sélectionnés doivent être inclus ou non. Par défaut, ce filtre n'est pas appliqué.
Voir
aria-selected
pour plus d'informations.tsx<button role="tab" aria-selected="true"> Vue </button>; page.getByRole('button', { selected: true }); // ✅ page.getByRole('button', { selected: false }); // ❌
Voir aussi
getByAltText
function getByAltText(text: string | RegExp, options?: LocatorOptions): Locator;
Crée un localisateur capable de trouver un élément avec un attribut alt
correspondant au texte spécifié. Contrairement à l'implémentation de testing-library, Vitest mettra en correspondance tout élément ayant un attribut alt
correspondant.
<img alt="Incredibles 2 Poster" src="/incredibles-2.png" />;
page.getByAltText(/incredibles.*? poster/i); // ✅
page.getByAltText('non existing alt text'); // ❌
Options
exact: boolean
Indique si le
text
doit correspondre exactement : sensible à la casse et à la chaîne entière. Désactivé par défaut. Cette option est ignorée sitext
est une expression régulière. Notez que la correspondance exacte supprime toujours les espaces blancs.
Voir aussi
getByLabelText
function getByLabelText(
text: string | RegExp,
options?: LocatorOptions
): Locator;
Crée un localisateur capable de trouver un élément associé à une étiquette.
Le localisateur page.getByLabelText('Username')
trouvera chaque champ d'entrée dans l'exemple ci-dessous :
<!-- Relation for/htmlFor entre l'étiquette et l'id de l'élément de formulaire -->
<label for="username-input">Username</label>
<input id="username-input" />
<!-- L'attribut aria-labelledby avec les éléments de formulaire -->
<label id="username-label">Username</label>
<input aria-labelledby="username-label" />
<!-- Étiquettes enveloppantes -->
<label>Username <input /></label>
<!-- Étiquettes enveloppantes où le texte de l'étiquette est dans un autre élément enfant -->
<label>
<span>Username</span>
<input />
</label>
<!-- Attributs aria-label -->
<!-- Attention, car ce n'est pas une étiquette visible par les utilisateurs sur la page, -->
<!-- donc le but de votre champ d'entrée doit être évident pour les utilisateurs voyants. -->
<input aria-label="Username" />
Options
exact: boolean
Indique si le
text
doit correspondre exactement : sensible à la casse et à la chaîne entière. Désactivé par défaut. Cette option est ignorée sitext
est une expression régulière. Notez que la correspondance exacte supprime toujours les espaces blancs.
Voir aussi
getByPlaceholder
function getByPlaceholder(
text: string | RegExp,
options?: LocatorOptions
): Locator;
Crée un localisateur capable de trouver un élément avec l'attribut placeholder
spécifié. Vitest mettra en correspondance tout élément ayant un attribut placeholder
correspondant, pas seulement les éléments input
.
<input placeholder="Username" />;
page.getByPlaceholder('Username'); // ✅
page.getByPlaceholder('not found'); // ❌
WARNING
Il est généralement préférable de s'appuyer sur une étiquette en utilisant getByLabelText
plutôt que sur un placeholder.
Options
exact: boolean
Indique si le
text
doit correspondre exactement : sensible à la casse et à la chaîne entière. Désactivé par défaut. Cette option est ignorée sitext
est une expression régulière. Notez que la correspondance exacte supprime toujours les espaces blancs.
Voir aussi
getByText
function getByText(text: string | RegExp, options?: LocatorOptions): Locator;
Crée un localisateur capable de trouver un élément contenant le texte spécifié. Le texte sera mis en correspondance avec le nodeValue
du TextNode ou la valeur de l'input si le type est button
ou reset
. La correspondance par texte normalise toujours les espaces blancs, même avec une correspondance exacte. Par exemple, elle transforme plusieurs espaces en un seul, les sauts de ligne en espaces, et ignore les espaces blancs de début et de fin.
<a href="/about">About ℹ️</a>;
page.getByText(/about/i); // ✅
page.getByText('about', { exact: true }); // ❌
TIP
Ce localisateur est utile pour localiser des éléments non interactifs. Si vous devez localiser un élément interactif, comme un bouton ou un champ d'entrée, préférez getByRole
.
Options
exact: boolean
Indique si le
text
doit correspondre exactement : sensible à la casse et à la chaîne entière. Désactivé par défaut. Cette option est ignorée sitext
est une expression régulière. Notez que la correspondance exacte supprime toujours les espaces blancs.
Voir aussi
getByTitle
function getByTitle(text: string | RegExp, options?: LocatorOptions): Locator;
Crée un localisateur capable de trouver un élément avec l'attribut title
spécifié. Contrairement à getByTitle
de testing-library, Vitest ne peut pas trouver les éléments title
dans un SVG.
<span title="Delete" id="2"></span>;
page.getByTitle('Delete'); // ✅
page.getByTitle('Create'); // ❌
Options
exact: boolean
Indique si le
text
doit correspondre exactement : sensible à la casse et à la chaîne entière. Désactivé par défaut. Cette option est ignorée sitext
est une expression régulière. Notez que la correspondance exacte supprime toujours les espaces blancs.
Voir aussi
getByTestId
function getByTestId(text: string | RegExp): Locator;
Crée un localisateur capable de trouver un élément correspondant à l'attribut d'identifiant de test spécifié. Vous pouvez configurer le nom de l'attribut avec browser.locators.testIdAttribute
.
<div data-testid="custom-element" />;
page.getByTestId('custom-element'); // ✅
page.getByTestId('non-existing-element'); // ❌
WARNING
Il est recommandé de n'utiliser ceci que si les autres localisateurs ne conviennent pas à votre cas d'utilisation. L'utilisation d'attributs data-testid
ne reflète pas la manière dont votre logiciel est utilisé et doit être évitée si possible.
Options
exact: boolean
Indique si le
text
doit correspondre exactement : sensible à la casse et à la chaîne entière. Désactivé par défaut. Cette option est ignorée sitext
est une expression régulière. Notez que la correspondance exacte supprime toujours les espaces blancs.
Voir aussi
Méthodes
Toutes les méthodes sont asynchrones et doivent être attendues (await
). Depuis Vitest 2.2, les tests échoueront si une méthode n'est pas attendue.
click
function click(options?: UserEventClickOptions): Promise<void>;
Clique 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
function dblClick(options?: UserEventDoubleClickOptions): 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
function tripleClick(options?: UserEventTripleClickOptions): Promise<void>;
Déclenche un événement de triple-clic sur un élément. Comme il n'y a pas d'événement 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
function clear(): Promise<void>;
Efface le contenu de l'élément input.
import { page } from '@vitest/browser/context';
await page.getByRole('textbox', { name: 'Full Name' }).clear();
hover
function hover(options?: UserEventHoverOptions): Promise<void>;
Déplace la position du curseur sur l'élément sélectionné.
import { page } from '@vitest/browser/context';
await page.getByRole('img', { name: 'Rose' }).hover();
unhover
function unhover(options?: UserEventHoverOptions): Promise<void>;
Cette méthode fonctionne de manière similaire à 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
function fill(text: string, options?: UserEventFillOptions): Promise<void>;
Définit la valeur de l'élément input
, textarea
ou contenteditable
actuel.
import { page } from '@vitest/browser/context';
await page.getByRole('input', { name: 'Full Name' }).fill('Mr. Bean');
dropTo
function dropTo(
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
function selectOptions(
values: HTMLElement | HTMLElement[] | Locator | Locator[] | string | string[],
options?: UserEventSelectOptions
): Promise<void>;
Sélectionne une ou plusieurs valeurs dans un élément <select>
.
import { page } from '@vitest/browser/context';
const languages = page.getByRole('select', { name: 'Languages' });
await languages.selectOptions('EN');
await languages.selectOptions(['ES', 'FR']);
await languages.selectOptions([
languages.getByRole('option', { name: 'Spanish' }),
languages.getByRole('option', { name: 'French' }),
]);
screenshot
function screenshot(
options: LocatorScreenshotOptions & { base64: true }
): Promise<{
path: string;
base64: string;
}>;
function screenshot(
options?: LocatorScreenshotOptions & { base64?: false }
): Promise<string>;
Crée une capture d'écran de l'élément correspondant au sélecteur du localisateur.
Vous pouvez spécifier l'emplacement d'enregistrement de la capture d'écran à l'aide de 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 du fichier de la capture d'écran.
Si vous avez également besoin du contenu de la capture d'écran, vous pouvez spécifier base64: true
pour le renvoyer en plus du chemin du fichier où la capture d'écran est enregistrée.
import { page } from '@vitest/browser/context';
const button = page.getByRole('button', { name: 'Click Me!' });
const path = await button.screenshot();
const { path, base64 } = await button.screenshot({
path: './button-click-me.png',
base64: true, // renvoie é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
function query(): Element | null;
Cette méthode renvoie un seul élément correspondant au sélecteur du localisateur ou null
si aucun élément n'est trouvé.
Si plusieurs éléments correspondent au sélecteur, cette méthode lèvera 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 localisateurs correspondant au sélecteur.
Considérez la structure DOM suivante :
<div>Hello <span>World</span></div>
<div>Hello</div>
Ces localisateurs ne lèveront pas d'erreur :
page.getByText('Hello World').query(); // ✅ HTMLDivElement
page.getByText('Hello Germany').query(); // ✅ null
page.getByText('World').query(); // ✅ HTMLSpanElement
page.getByText('Hello', { exact: true }).query(); // ✅ HTMLSpanElement
Ces localisateurs lèveront une erreur :
// renvoie plusieurs éléments
page.getByText('Hello').query(); // ❌
page.getByText(/^Hello/).query(); // ❌
element
function element(): Element;
Cette méthode renvoie un seul élément correspondant au sélecteur du localisateur.
Si aucun élément ne correspond au sélecteur, une erreur est levée. Envisagez d'utiliser .query()
lorsque vous avez juste besoin de vérifier si l'élément existe.
Si plusieurs éléments correspondent au sélecteur, une erreur est levée. Utilisez .elements()
lorsque vous avez besoin de tous les éléments DOM correspondants ou .all()
si vous avez besoin d'un tableau de localisateurs correspondant au sélecteur.
TIP
Cette méthode peut être utile si vous devez la transmettre à une bibliothèque externe. Elle est appelée automatiquement lorsque le localisateur est utilisé avec expect.element
chaque fois que l'assertion est réessayée :
await expect.element(page.getByRole('button')).toBeDisabled();
Considérez la structure DOM suivante :
<div>Hello <span>World</span></div>
<div>Hello Germany</div>
<div>Hello</div>
Ces localisateurs ne lèveront pas d'erreur :
page.getByText('Hello World').element(); // ✅
page.getByText('Hello Germany').element(); // ✅
page.getByText('World').element(); // ✅
page.getByText('Hello', { exact: true }).element(); // ✅
Ces localisateurs lèveront une erreur :
// renvoie plusieurs éléments
page.getByText('Hello').element(); // ❌
page.getByText(/^Hello/).element(); // ❌
// renvoie aucun élément
page.getByText('Hello USA').element(); // ❌
elements
function elements(): Element[];
Cette méthode renvoie un tableau d'éléments correspondant au sélecteur du localisateur.
Cette fonction ne lève jamais d'erreur. S'il n'y a aucun élément correspondant au sélecteur, cette méthode renverra un tableau vide.
Considérez la structure DOM suivante :
<div>Hello <span>World</span></div>
<div>Hello</div>
Ces localisateurs réussiront toujours :
page.getByText('Hello World').elements(); // ✅ [HTMLElement]
page.getByText('World').elements(); // ✅ [HTMLElement]
page.getByText('Hello', { exact: true }).elements(); // ✅ [HTMLElement]
page.getByText('Hello').elements(); // ✅ [HTMLElement, HTMLElement]
page.getByText('Hello USA').elements(); // ✅ []
all
function all(): Locator[];
Cette méthode renvoie un tableau de nouveaux localisateurs qui correspondent au sélecteur.
En interne, cette méthode appelle .elements
et enveloppe chaque élément à l'aide de page.elementLocator
.