Aller au contenu principal

Par rôle

[Traduction Bêta Non Officielle]

Cette page a été traduite par PageTurner AI (bêta). Non approuvée officiellement par le projet. Vous avez trouvé une erreur ? Signaler un problème →

getByRole, queryByRole, getAllByRole, queryAllByRole, findByRole, findAllByRole

API

getByRole(
// If you're using `screen`, then skip the container argument:
container: HTMLElement,
role: string,
options?: {
hidden?: boolean = false,
name?: TextMatch,
description?: TextMatch,
selected?: boolean,
busy?: boolean,
checked?: boolean,
pressed?: boolean,
suggest?: boolean,
current?: boolean | string,
expanded?: boolean,
queryFallbacks?: boolean,
level?: number,
value?: {
min?: number,
max?: number,
now?: number,
text?: TextMatch,
}
}): HTMLElement

Recherche les éléments avec le rôle donné (et accepte également un TextMatch). Les rôles par défaut sont pris en compte, par exemple <button /> possède le rôle button sans définition explicite de l'attribut role. Consultez ce tableau des éléments HTML avec leurs rôles par défaut.

Notez que définir un attribut role et/ou aria-* correspondant à la sémantique ARIA implicite est inutile et déconseillé, car ces propriétés sont déjà définies par le navigateur. Nous ne devons pas utiliser les attributs role et aria-* d'une manière contradictoire avec leur sémantique. Par exemple, un élément button ne peut pas avoir l'attribut role défini à heading, car l'élément button a des caractéristiques par défaut qui entrent en conflit avec le rôle heading.

Les rôles sont comparés par égalité de chaîne exacte, sans héritage de la hiérarchie ARIA. Ainsi, rechercher un rôle superclasse comme checkbox n'inclura pas les éléments avec un rôle sous-classe comme switch.

Vous pouvez filtrer les éléments retournés par leur nom ou description accessible. Le nom accessible correspond simplement au libellé d'un champ, au contenu textuel d'un bouton, ou à la valeur de l'attribut aria-label. Il permet de cibler un élément spécifique lorsque plusieurs partagent le même rôle. Pour un guide complet, consultez "Qu'est-ce qu'un nom accessible ?" de TPGi. Pour une recherche unique, privilégiez getByRole(expectedRole, { name: 'The name' }) plutôt que getByText('The name'). Le nom accessible ne remplace pas les requêtes comme *ByAlt ou *ByTitle. Bien qu'il puisse correspondre à ces attributs, il n'en reproduit pas la fonctionnalité. Par exemple <img aria-label="fancy image" src="fancy.jpg" /> sera trouvée via getByRole('img', { name: 'fancy image' }), mais l'image n'affichera pas sa description si fancy.jpg échoue au chargement. Libre à vous de tester ou non ce comportement.

[input type password]

Malheureusement, la spécification indique que <input type="password" /> n'a pas de rôle implicite. Pour interroger ces éléments, utilisez une requête moins précise comme ByLabelText.

Options

hidden

Définir hidden à true inclut les éléments normalement exclus de l'arbre d'accessibilité. Le comportement par défaut suit https://www.w3.org/TR/wai-aria-1.2/#tree_exclusion, sauf pour role="none" et role="presentation" toujours inclus. Par exemple :

<body>
<main aria-hidden="true">
<button>Open dialog</button>
</main>
<div role="dialog">
<button>Close dialog</button>
</div>
</body>

getByRole('button') ne retournera que le bouton Close dialog. Pour vérifier le bouton Open dialog, utilisez getAllByRole('button', { hidden: true }).

La valeur par défaut de hidden peut être configurée.

selected

Filtrez les éléments par leur état de sélection avec selected: true ou selected: false.

Par exemple dans

<body>
<div role="tablist">
<button role="tab" aria-selected="true">Native</button>
<button role="tab" aria-selected="false">React</button>
<button role="tab" aria-selected="false">Cypress</button>
</div>
</body>

vous pouvez obtenir l'onglet « Native » en appelant getByRole('tab', { selected: true }). Pour en savoir plus sur l'état sélectionné et les éléments pouvant avoir cet état, consultez ARIA aria-selected.

busy

Vous pouvez filtrer les éléments retournés par leur état d'occupation en définissant busy: true ou busy: false.

Par exemple dans

<body>
<section>
<div role="alert" aria-busy="false">Login failed</div>
<div role="alert" aria-busy="true">Error: Loading message...</div>
</section>
</body>

vous pouvez obtenir l'alerte « Login failed » en appelant getByRole('alert', { busy: false }). Pour en savoir plus sur l'état d'occupation, consultez ARIA aria-busy et L'attribut MDN aria-busy.

checked

Vous pouvez filtrer les éléments retournés par leur état coché en définissant checked: true ou checked: false.

Par exemple dans

<body>
<section>
<button role="checkbox" aria-checked="true">Sugar</button>
<button role="checkbox" aria-checked="false">Gummy bears</button>
<button role="checkbox" aria-checked="false">Whipped cream</button>
</section>
</body>

vous pouvez obtenir l'option « Sugar » en appelant getByRole('checkbox', { checked: true }). Pour en savoir plus sur l'état coché et les éléments pouvant avoir cet état, consultez ARIA aria-checked.

Note

Les cases à cocher ont un état "mixte", qui n'est considéré ni comme coché ni comme décoché (détails ici).

current

Vous pouvez filtrer les éléments retournés par leur état courant en définissant current: boolean | string. Notez qu'aucun attribut aria-current ne correspondra à current: false car false est la valeur par défaut de aria-current.

Par exemple dans

<body>
<nav>
<a href="current/page" aria-current="page">👍</a>
<a href="another/page">👎</a>
</nav>
</body>

vous pouvez obtenir le lien « 👍 » en appelant getByRole('link', { current: 'page' }) et le lien « 👎 » en appelant getByRole('link', { current: false }). Pour en savoir plus sur l'état courant, consultez ARIA aria-current.

pressed

Les boutons peuvent avoir un état enfoncé. Vous pouvez filtrer les éléments retournés par leur état enfoncé en définissant pressed: true ou pressed: false.

Par exemple dans

<body>
<section>
<button aria-pressed="true">👍</button>
<button aria-pressed="false">👎</button>
</section>
</body>

vous pouvez obtenir le bouton « 👍 » en appelant getByRole('button', { pressed: true }). Pour en savoir plus sur l'état enfoncé, consultez ARIA aria-pressed.

suggest

Vous pouvez désactiver la capacité à lancer des suggestions pour une requête spécifique en définissant cette valeur à false.
Définir cette valeur à true lancera des suggestions pour la requête spécifique.

expanded

Vous pouvez filtrer les éléments retournés par leur état déplié en définissant expanded: true ou expanded: false.

Par exemple dans

<body>
<nav>
<ul>
<li>
<a aria-expanded="false" aria-haspopup="true" href="..."
>Expandable Menu Item</a
>
<ul>
<li><a href="#">Submenu Item 1</a></li>
<li><a href="#">Submenu Item 1</a></li>
</ul>
</li>
<li><a href="#">Regular Menu Item</a></li>
</ul>
</nav>
</body>

vous pouvez obtenir le lien « Expandable Menu Item » en appelant getByRole('link', { expanded: false }). Pour en savoir plus sur l'état déplié et les éléments pouvant avoir cet état, consultez ARIA aria-expanded.

<div role="dialog">...</div>
import {screen} from '@testing-library/dom'

const dialogContainer = screen.getByRole('dialog')

queryFallbacks

Par défaut, on considère que seul le premier rôle de chaque élément est pris en charge, donc uniquement ce premier rôle peut être interrogé. Si vous devez interroger un élément par l'un de ses rôles de secours, utilisez queryFallbacks: true.

Par exemple, getByRole('switch') correspondrait toujours à <div role="switch checkbox" /> car c'est le premier rôle, alors que getByRole('checkbox') ne le ferait pas. Cependant, getByRole('checkbox', { queryFallbacks: true }) activerait tous les rôles de secours et correspondrait donc au même élément.

Un élément n'a pas plusieurs rôles dans un environnement donné. Il en a un seul. Les rôles multiples dans l'attribut sont évalués de gauche à droite jusqu'à ce que l'environnement trouve le premier rôle qu'il comprend. Ceci est utile lorsque de nouveaux rôles sont introduits et que vous souhaitez les prendre en charge ainsi que les environnements plus anciens qui ne comprennent pas encore ce rôle.

level

Un élément avec le rôle heading peut être interrogé par n'importe quel niveau getByRole('heading') ou par un niveau spécifique via l'option level getByRole('heading', { level: 2 }).

L'option level interroge les éléments avec le rôle heading correspondant au niveau indiqué, déterminé par les éléments HTML sémantiques <h1>-<h6> ou correspondant à l'attribut aria-level.

Dans l'exemple ci-dessous,

<body>
<section>
<h1>Heading Level One</h1>
<h2>First Heading Level Two</h2>
<h3>Heading Level Three</h3>
<div role="heading" aria-level="2">Second Heading Level Two</div>
</section>
</body>

vous pouvez interroger le titre Heading Level Three via getByRole('heading', { level: 3 }).

getByRole('heading', {level: 1})
// <h1>Heading Level One</h1>

getAllByRole('heading', {level: 2})
// [
// <h2>First Heading Level Two</h2>,
// <div role="heading" aria-level="2">Second Heading Level Two</div>
// ]

Bien qu'il soit possible de définir explicitement role="heading" et l'attribut aria-level sur un élément, il est fortement recommandé d'utiliser les balises HTML sémantiques <h1>-<h6>.

Pour en savoir plus sur la propriété aria-level, consultez ARIA aria-level.

L'option level est uniquement applicable au rôle heading. Une erreur sera levée si elle est utilisée avec un autre rôle.

value

Un widget de plage peut être interrogé par n'importe quelle valeur getByRole('spinbutton') ou par une valeur spécifique via l'option level : getByRole('spinbutton', { value: { now: 5, min: 0, max: 10, text: 'medium' } }).

Notez que vous n'avez pas à spécifier toutes les propriétés dans value. Un sous-ensemble suffit, par exemple : getByRole('spinbutton', { value: { now: 5, text: 'medium' } }).

Dans l'exemple ci-dessous,

<body>
<section>
<button
role="spinbutton"
aria-valuenow="5"
aria-valuemin="0"
aria-valuemax="10"
aria-valuetext="medium"
>
Volume
</button>
<button
role="spinbutton"
aria-valuenow="3"
aria-valuemin="0"
aria-valuemax="10"
aria-valuetext="medium"
>
Pitch
</button>
</section>
</body>

vous pouvez interroger des spinbutton spécifiques avec les requêtes suivantes :

getByRole('spinbutton', {value: {now: 5}})
// <button>Volume</button>

getAllByRole('spinbutton', {value: {min: 0}})
// [
// <button>Volume</button>,
// <button>Pitch</button>
// ]

Chaque propriété spécifiée dans value doit correspondre. Par exemple, une requête {value: {min: 0, now: 3}} nécessite que aria-valuemin soit égal à 0 ET aria-valuenow égal à 3.

L'option value est uniquement applicable à certains rôles (consultez les pages MDN liées ci-dessous). Une erreur sera levée si elle est utilisée avec un autre rôle.

Pour en savoir plus sur les propriétés aria-value*, consultez : MDN aria-valuemin, MDN aria-valuemax, MDN aria-valuenow, MDN aria-valuetext.

description

Vous pouvez filtrer les éléments retournés par leur description accessible dans les cas où vous avez plusieurs éléments avec le même rôle qui ne possèdent pas de nom accessible mais disposent d'une description.
Ce serait le cas pour les éléments avec le rôle alertdialog, où l'attribut aria-describedby est utilisé pour décrire le contenu de l'élément.

Par exemple dans

<body>
<ul>
<li role="alertdialog" aria-describedby="notification-id-1">
<div><button>Close</button></div>
<div id="notification-id-1">You have unread emails</div>
</li>
<li role="alertdialog" aria-describedby="notification-id-2">
<div><button>Close</button></div>
<div id="notification-id-2">Your session is about to expire</div>
</li>
</ul>
</body>

Vous pouvez interroger un élément spécifique comme ceci

getByRole('alertdialog', {description: 'Your session is about to expire'})

Performances

getByRole est la requête la plus recommandée car elle reflète fidèlement l'expérience utilisateur, cependant les calculs nécessaires pour garantir cette fiabilité peuvent être coûteux (notamment avec de grands arbres DOM).

Lorsque la performance des tests est critique, il peut être souhaitable de sacrifier une partie de cette fiabilité pour améliorer les performances.

Les performances de getByRole peuvent être améliorées en définissant l'option hidden à true, évitant ainsi les coûteuses vérifications de visibilité. Notez qu'ainsi des éléments inaccessibles seront inclus dans les résultats.

Une autre option consiste à remplacer getByRole par des requêtes plus simples comme getByLabelText et getByText, alternatives nettement plus rapides bien que moins robustes.