--- title: Frontend — Patterns : Tests domain: frontend bucket: patterns tags: [tests, react-native, jest, styles, ui] applies_to: [implementation, review] severity: medium validated_on: 2026-04-07 source_projects: [app-alexandrie, RL799_V2] --- # Frontend — Patterns : Tests > Extrait de la base de connaissance Lead_tech. Voir `knowledge/frontend/patterns/README.md` pour l'index complet. --- ## Pattern : Tests de styles React Native sans renderer JSX ### Synthèse - **Objectif** : tester les tokens et styles de composants React Native dans un environnement Jest `testEnvironment: node` sans renderer JSX. - **Contexte** : config Jest avec `transform: { '^.+\\.ts$': 'ts-jest' }` — les `.tsx` ne sont pas transformés. - **Quand l'utiliser** : tokens de thème, logique pure, valeurs de style exportées. - **Quand l'éviter** : rendu conditionnel (styles dynamiques inline) — nécessite `@testing-library/react-native`. ### Analyse - **Avantages** : - teste que le composant utilise les bons tokens, pas seulement que les tokens ont des valeurs - détecte les régressions de style sans renderer - rapide, aucune config Jest supplémentaire - **Limites / vigilance** : - ne teste pas le style calculé au runtime (style conditionnel dynamique) ### Validation - Validé le : 19-03-2026 - Contexte technique : React Native / Jest / ts-jest — app-alexandrie story 0.2 ### Implémentation ```typescript // Button.tsx — exporter le StyleSheet avec un nom préfixé export const buttonStyles = StyleSheet.create({ base: { borderRadius: 20, height: 57 }, primary: { backgroundColor: colors.primary }, }); export function Button(...) { ... } // ui-components.spec.ts — importer et vérifier les tokens import { buttonStyles } from './Button'; import { colors } from '@/theme'; it('variante primary utilise colors.primary', () => { expect(buttonStyles.primary.backgroundColor).toBe(colors.primary); }); ``` ### Deux niveaux de tests UI recommandés 1. `.spec.ts` (node) : tokens, valeurs, logique pure 2. `.spec.tsx` (config séparée avec renderer) : rendu visuel, interactions --- ## Pattern : Niveaux de test frontend Vue ### Synthèse - **Objectif** : clarifier quand utiliser chaque niveau de test frontend Vue (structurel, composant monté, E2E). - **Contexte** : les tests frontend du projet sont du string-matching sur le source `.vue` (`readFileSync` + `includes`). Ce pattern est rapide mais ne valide pas le comportement réel. - **Quand l'utiliser** : à chaque choix de stratégie de test sur un composant Vue. ### Niveaux | Niveau | Outil | Quand l'utiliser | |--------|-------|-----------------| | Structurel (string-matching) | `node:test` + `readFileSync` | Smoke tests : vérifier qu'un composant contient les imports, props, slots attendus. Acceptable pour MVP/sprint rapide. | | Composant monté | `@vue/test-utils` + `vitest` | Valider le comportement interactif (toggle, emit, slots conditionnels). Obligatoire dès qu'il y a de la logique UI. | | E2E | Playwright | Parcours critiques multi-pages. | ### Règle Si un test vérifie un *comportement* (ex: "le menu se ferme après clic"), il doit monter le composant, pas chercher une string dans le source. ### Validation - Validé le : 03-04-2026 - Contexte technique : Vue 3 / node:test — RL799_V2 story 6A.8 --- ## Pattern : Vérifier l'ordre DOM avec `compareDocumentPosition`, pas `boundingBox` ### Synthèse - **Objectif** : valider l'ordre réel des éléments dans le DOM, indépendamment du rendu CSS. - **Contexte** : tests E2E Playwright qui doivent vérifier l'ordre d'affichage de sections ou d'éléments. - **Quand l'utiliser** : toute assertion d'ordre dans un test E2E. - **Quand l'éviter** : si on veut explicitement tester la position visuelle CSS (rare). ### Analyse - **Avantages** : - vérifie l'ordre DOM réel, insensible aux propriétés CSS (`flex-order`, `position`, `transform`) - pas de `null` en retour (contrairement à `boundingBox()` hors viewport) - déterministe - **Limites / vigilance** : - ne vérifie pas la position visuelle — si le test doit valider un rendu CSS spécifique, `boundingBox` reste pertinent ### Validation - Validé le : 08-04-2026 - Contexte technique : Playwright / E2E — RL799_V2 story 17-5 ### Implémentation ```ts const aBeforeB = await page.evaluate(() => { const a = document.querySelector('[data-testid="section-a"]'); const b = document.querySelector('[data-testid="section-b"]'); if (!a || !b) return false; return (a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING) !== 0; }); expect(aBeforeB).toBe(true); ``` ### Risque associé `boundingBox().y` vérifie la position visuelle rendue par CSS, pas l'ordre dans le DOM. De plus `boundingBox()` retourne `null` pour les éléments hors viewport → crash non déterministe.