Aller au contenu principal

Méthodes Asynchrones

[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 →

Plusieurs utilitaires sont fournis pour gérer du code asynchrone. Ils permettent d'attendre l'apparition ou la disparition d'un élément en réponse à un événement, une action utilisateur, un timeout ou une Promise. (Voir le guide sur le test des disparitions.)

Les méthodes asynchrones renvoient des Promesses, pensez donc à utiliser await ou .then lors de leur appel.

Requêtes findBy

Les méthodes findBy combinent les requêtes getBy queries et waitFor. Elles acceptent les options de waitFor comme dernier argument (ex: await screen.findByText('text', queryOptions, waitForOptions)).

Les requêtes findBy sont utiles quand vous attendez qu'un élément apparaisse, mais que la modification du DOM peut ne pas être immédiate.

const button = screen.getByRole('button', {name: 'Click Me'})
fireEvent.click(button)
await screen.findByText('Clicked once')
fireEvent.click(button)
await screen.findByText('Clicked twice')

waitFor

function waitFor<T>(
callback: () => T | Promise<T>,
options?: {
container?: HTMLElement
timeout?: number
interval?: number
onTimeout?: (error: Error) => Error
mutationObserverOptions?: MutationObserverInit
},
): Promise<T>

Pour attendre pendant une durée quelconque, utilisez waitFor jusqu'à ce que vos attentes soient satisfaites. Retourner une condition fausse ne suffit pas pour déclencher une nouvelle tentative : le callback doit lancer une erreur pour réessayer. Exemple simple :

// ...
// Wait until the callback does not throw an error. In this case, that means
// it'll wait until the mock function has been called once.
await waitFor(() => expect(mockAPI).toHaveBeenCalledTimes(1))
// ...

waitFor peut exécuter le callback plusieurs fois jusqu'au timeout. Le nombre d'appels est limité par les options timeout et interval.

Utile pour les tests unitaires mockant des appels API, quand vous devez attendre la résolution de toutes vos Promesses mockées.

Si vous retournez une Promesse dans le callback de waitFor (explicitement ou implicitement via async), alors l'utilitaire waitFor n'appellera pas à nouveau votre callback avant son rejet. Cela permet de waitFor des éléments nécessitant une vérification asynchrone.

Le container par défaut est le document global. Assurez-vous que les éléments attendus sont des descendants de ce container.

L'interval par défaut est 50ms. Le callback est exécuté immédiatement avant le démarrage des intervalles.

Le timeout par défaut est 1000ms.

L'option par défaut onTimeout ajoute l'état imprimé du container au message d'erreur, facilitant l'identification de la cause du timeout.

Les mutationObserverOptions par défaut sont {subtree: true, childList: true, attributes: true, characterData: true}. Elles détectent les ajouts/suppressions d'éléments enfants (y compris les nœuds texte) dans le container et ses descendants, ainsi que les changements d'attributs. Toute modification relance le callback.

waitForElementToBeRemoved

function waitForElementToBeRemoved<T>(
callback: (() => T) | T,
options?: {
container?: HTMLElement
timeout?: number
interval?: number
onTimeout?: (error: Error) => Error
mutationObserverOptions?: MutationObserverInit
},
): Promise<void>

Pour attendre la suppression d'élément(s) du DOM, utilisez waitForElementToBeRemoved. La fonction waitForElementToBeRemoved est un simple wrapper autour de waitFor.

Le premier argument doit être un élément, un tableau d'éléments, ou un callback retournant un élément ou un tableau d'éléments.

Exemple où la promesse est résolue suite à la suppression de l'élément :

const el = document.querySelector('div.getOuttaHere')

waitForElementToBeRemoved(document.querySelector('div.getOuttaHere')).then(() =>
console.log('Element no longer in DOM'),
)

el.setAttribute('data-neat', true)
// other mutations are ignored...

el.parentElement.removeChild(el)
// logs 'Element no longer in DOM'

waitForElementToBeRemoved lance une erreur si le premier argument est null ou un tableau vide :

waitForElementToBeRemoved(null).catch(err => console.log(err))
waitForElementToBeRemoved(queryByText(/not here/i)).catch(err =>
console.log(err),
)
waitForElementToBeRemoved(queryAllByText(/not here/i)).catch(err =>
console.log(err),
)
waitForElementToBeRemoved(() => getByText(/not here/i)).catch(err =>
console.log(err),
)

// Error: The element(s) given to waitForElementToBeRemoved are already removed. waitForElementToBeRemoved requires that the element(s) exist(s) before waiting for removal.

L'objet d'options est transmis à waitFor.