Recherche de Texte Fragmenté dans les Composants React
Introduction
Dans mes composants React, j'ai souvent besoin de fragmenter le texte pour appliquer du style mots par mots.
Un exemple tout simple est: <div>Hello <span>World</span></div>
.
Si dans mes tests je veux tester le contenu et non la mise en page (avec screen.getByText
), cela ne fonctionnera pas.
Voici une solution simple à ce problème avec Jest.
Code
import { screen } from "@testing-library/react";
export const getByShatteredText = (expectedText: string) =>
// Jest permet de passer une fonction plutôt qu'une chaîne de caractères à getByText, ce qui permet un correspondance personnalisée.
screen.getByText((_, element) => {
// Le premier argument est le contenu textuel du nœud, que nous allons ignorer.
// Le deuxième argument est le nœud HTML du DOM. S'il n'est pas défini, l'élément courant n'est pas celui recherché.
if (!element) return false;
// Nous préparons une fonction de test avec textContent, qui teste le contenu textuel de tout le nœud contrairement à innerText.
// Documentation : https://developer.mozilla.org/fr/docs/Web/API/Node/textContent#différences_avec_innertext
const hasText = (element: Element) => element.textContent === expectedText;
const nodeHasText = hasText(element);
// Nous testons si les enfants du nœud n'ont pas également le même texte, auquel cas nous ne sommes pas assez profonds dans l'arbre.
const noChildHasText = [...element.children].every(
(child) => !hasText(child)
);
// Conclusion: si j'ai mon texte dans l'élément et qu'aucun élément plus profond ne l'a, je suis au bon endroit.
return nodeHasText && noChildHasText;
});