Files
ng-eventually/.project/concepts/e2e-harness/knowledge_what-each-suite-judges.md
Sylvain Duchesne 9e7aeef269 docs: deux exécutions peuvent maintenant se chevaucher
La feuille disait le contraire, et c'est moi qui l'ai écrite hier : « deux
exécutions ne doivent jamais se chevaucher », « c'est désormais tenu par un
verrou », « une suite d'un dépôt consommateur entre en collision ». Les trois
sont fausses depuis l'extraction.

Chaque exécution a son propre répertoire de profil et tue le navigateur qui le
détient en finissant. Les exécutions concurrentes — y compris celle d'une
application consommatrice, depuis son propre dépôt — sont indépendantes par
construction.

Et la leçon de forme est consignée, parce qu'elle se généralise : le verrou ne
traitait qu'un symptôme, supprimer le partage a supprimé le besoin. Quand deux
exécutions se disputent une chose, la rendre propre à chacune plutôt que de
sérialiser l'accès.
2026-08-16 14:17:38 +02:00

39 lines
3.4 KiB
Markdown

---
type: knowledge
summary: Which suite answers which question, what a batch costs, and why two runs must never overlap
---
# What each suite judges
**The polyfill suite** exercises the published surface against the real broker: capabilities, reads, inboxes, reactivity. It is the one that judges whether the emulation behaves like the target.
**The applicative suite** drives the example application through a browser, as a person would — several identities, several pages, assertions on what is on screen rather than on what the library returns. It judges whether an application built on this package actually works, including the sign-in a person really performs.
**The reactivity suite** isolates document subscription.
A unit suite cannot replace any of them, and none of them replaces the unit suite: they are slow, they depend on live external services, and they cannot enumerate a case space.
## What a batch costs, and why
Every run mints its own physical user by driving the wallet application's real interface, then discards the previous one. That is deliberate — identities must not leak between runs — and it puts a floor under every run that no test filter can remove.
Consequence worth knowing before optimizing anything: the setup runs before any `journey`, so filtering journeys saves journey time only — the floor stays.
## Two runs may overlap — and that was not free
They once could not: the profile was a single shared directory, and a run starting while another was alive destroyed it, which then failed in a way that read as a product defect. Several measurements were lost to it.
Now each run gets its own profile directory and kills the browser holding it when it ends, so concurrent runs — including a consuming application's suite, from its own checkout — are independent by construction. A lock once guarded the shared directory; it treated the symptom, and removing the sharing removed the need. Prefer that shape whenever two runs contend: make the contended thing per-run rather than serialising access to it.
## A bound must be larger than the sum of what it encloses
An enclosing deadline shorter than its own steps can only ever fire first, so every failure underneath it reports the *enclosing* name and none of them can name a cause. The sign-in bound sat at 180 s over steps totalling 270 s, and for days every failure said the same four words while the real step stayed anonymous. Days went into looking for a cause the harness was structurally incapable of reporting.
So: compute an enclosing bound from its parts rather than picking a number, and size every leaf bound from a **measured** healthy duration recorded beside it. A bare figure teaches nothing and rots without anyone noticing; a figure with its measurement lets the next reader tell a generous bound from a tight one.
## What a run must report whatever happens
Declare the journeys and their checks before anything can fail, so a run reports the same number of rows every time. When the count itself moves with the failure — journeys dying and taking their unreported checks with them — two runs are no longer comparable, and a shrinking total reads like a smaller problem instead of a bigger one.
The related trap that made it self-perpetuating: discarding the profile was once conditioned on a marker written at the *end* of a batch, so a run killed before writing it left a profile the next run happily reused — and inherited its breakage. Discarding now keys on the profile itself.