diff --git a/.project/concepts/bdd-testing/caveat_poll-broker-reads.md b/.project/concepts/bdd-testing/caveat_poll-broker-reads.md new file mode 100644 index 0000000..6fdde1a --- /dev/null +++ b/.project/concepts/bdd-testing/caveat_poll-broker-reads.md @@ -0,0 +1,36 @@ +--- +type: caveat +summary: Les lectures @data/@multibrowser contre le broker réel convergent avec un lag de sync (~s) — asserter en POLLING borné, jamais en lecture unique ; une lecture one-shot course la fenêtre de sync/réactivité et flake. Vaut pour les lectures à froid (reconnexion) ET la propagation réactive (compteur cross-navigateur). +last_checked: 2026-07-08 +--- + +# Asserter les lectures broker en polling, pas en one-shot + +Contre le **broker réel** (@data, @multibrowser), une donnée écrite n'est pas +lisible **instantanément** par un lecteur : il y a un **lag de sync** (le CRDT du +doc doit se propager/s'ouvrir avant qu'une lecture ancrée le rende). Mesuré : une +donnée fraîche se lit typiquement en **~1 s**, parfois après la 1ʳᵉ tentative. + +**Piège** : une assertion qui lit **une seule fois**, tout de suite, **course +cette fenêtre** et échoue de façon **flaky** — alors que le comportement applicatif +est correct (l'UI réelle est **réactive** : `doc_subscribe` fait converger l'écran +en quelques secondes). Un test qui lit one-shot mesure le lag, pas le bug. + +**Règle** : asserter en **POLLING borné** (re-lire en boucle jusqu'à ~10-15 s max) +la condition attendue. C'est ce que fait déjà la matérialisation côté steps ; toute +NOUVELLE assertion de lecture doit suivre le même pattern. + +Deux familles concernées, toutes deux vérifiées : +- **Lecture à froid / reconnexion** — une session verifier fraîche (page fraîche, + nouveau login) relit ses propres docs après ouverture de repo ; la 1ʳᵉ lecture + peut rendre 0, la suivante les données. Voir `event/reconnexion-meme-identite` + (les 3 `Then` de la page fraîche pollent) et `event/steps/data/reconnexion.steps.ts`. +- **Propagation réactive cross-navigateur** — un compteur écrit par le propriétaire + se propage au `doc_subscribe` d'un autre navigateur ; asserter « passe à {int} + sans reload » en attendant la convergence. Voir le scénario réactif de + `event/e2e-multibrowser.feature` (POV A **et** B). + +Ce caveat porte sur **comment écrire les assertions** contre le broker — pas sur +les internes NextGraph (lag/sync/ouverture de repo), qui vivent dans le repo +`@ng-eventually/client`. Voir aussi [[caveat_wallet-bloat-hang]] (autre source de +flakiness @data : le profil gonflé qui fait hanger les requêtes ancrées). diff --git a/src/modules/event/features/e2e-multibrowser.feature b/src/modules/event/features/e2e-multibrowser.feature index a4fc4f9..2309dd7 100644 --- a/src/modules/event/features/e2e-multibrowser.feature +++ b/src/modules/event/features/e2e-multibrowser.feature @@ -72,11 +72,16 @@ Fonctionnalité: Validation e2e multi-navigateurs des nouvelles features (T02.f) Quand le navigateur "B" s'inscrit à l'événement "Apéro réactif" Alors sans recharger, le compteur de participants réactif dans "A" pour "Apéro réactif" passe à 1 Et le navigateur "A" affiche un participant "inconnu" pour "Apéro réactif" + # Convergence symétrique côté inscrit : B voit aussi le compteur à 1 réactivement + # (le doc public de l'événement mis à jour par A se propage via le broker vers B). + Et sans recharger, le compteur de participants réactif dans "B" pour "Apéro réactif" passe à 1 # Option B symétrique : B se désinscrit → A (propriétaire) matérialise le # marqueur "leave" depuis l'inbox et RECALCULE participantCount sur SON PROPRE # doc → le compteur repasse à 0 côté A, SANS reload ni action de A. Quand le navigateur "B" se désinscrit de l'événement "Apéro réactif" Alors sans recharger, le compteur de participants réactif dans "A" pour "Apéro réactif" passe à 0 + # Convergence symétrique côté inscrit après désinscription : B voit aussi 0. + Et sans recharger, le compteur de participants réactif dans "B" pour "Apéro réactif" passe à 0 Scénario: Un navigateur découvre l'événement public publié dans l'autre Étant donné un navigateur "A" avec le wallet partagé