Files
ng-eventually/.project/concepts/e2e-harness/caveat_a-dropped-pipe-kills-a-run.md
T
Sylvain Duchesne f30685bdb9 docs: la doctrine enseignait le réflexe qui a coûté la journée
La feuille disait : « si la suite rapporte un délai nommé plutôt qu'une
assertion échouée, soupçonner le transport avant le code ». C'est faux, et je
l'ai écrite hier.

Un délai dit seulement qu'une chose n'est pas arrivée à temps. Il ne dit jamais
pourquoi — et se tourner vers l'environnement est la réponse confortable,
puisqu'elle exonère le code.

Le cas est maintenant raconté dans la feuille : tous les sign-in expiraient, on
a accusé le broker et le réseau de l'hôte pendant des heures, et la cause était
une correspondance de sous-chaîne sur une URL, lisible depuis le début. Le
propriétaire du dépôt a tranché contre cette attribution — « je n'ai jamais eu
de problème avec le broker, les tests si » — et il avait raison.

La discipline devient : lire son propre harnais d'abord, et ne parler de
transport qu'une fois le mécanisme nommé.
2026-08-14 10:57:21 +02:00

28 lines
3.5 KiB
Markdown

---
type: caveat
summary: Chromium's control pipe drops without Playwright emitting close or disconnected, so a run dies mid-flight — it looks like a product defect and is not one
last_checked: 2026-08-11
---
# A run can die from a dropped pipe, and it is not the product
Chromium's devtools pipe sometimes drops mid-run. It logs a terminated-pipe message and exits cleanly, and **Playwright emits neither `close` nor `disconnected`** — observed four times out of four. From the client's side the browser simply stops answering.
Before waits were bounded this was fatal in a specific way: the suite blocked in its own teardown, so it printed **neither its summary nor the failure already on its way out**. Hours went into diagnosing silence. Every wait is now bounded and names what it was waiting for, so a lost browser costs seconds and a report.
**How to recognize it.** The run dies without a coherent failure, or several unrelated interactions time out at once, or the summary is missing entirely. **Do not read a named deadline as a verdict on the transport.** A deadline says only that something did not happen in time; it never says why, and reaching for the environment is the comfortable answer because it absolves the code.
That reflex cost a full day here. Every actor sign-in was timing out, and it was blamed on the broker and on a churning host for hours. The real cause was one line of ours: the harness looked for the application frame with a substring match on the URL, and the broker's own login page carries the application address in its query string — so it matched the login page from the first instant, skipped the wallet click and the password as "already logged in", and handed back the wrong frame. What made it intermittent was a 2-second visibility probe on a button that painted in 1.0 to 1.6 seconds. All of it was readable in the code the whole time.
**It is not ours to fix.** It is not caused by how a child process is spawned, nor by a leftover holding the profile, nor by overlapping launches — all three were probed and ruled out. It looks like Playwright losing its file descriptors without telling its client. Worth reporting upstream.
## The host can be the cause too
A machine that reconfigures its network — a container in a crash-restart loop cycling its virtual interface, for instance — makes the applicative suite unreliable. The browser answers with a network-changed error, broker sockets fail, and every failure looks like a different product bug.
This has happened here: seven failures out of ten runs in one afternoon, all transport, none product. The check costs seconds — watch for repeated link events, and look for a container restarting.
But do not conclude the suite is unmeasurable: under that same churn it also ran green four times in a row. A red run under a moving network proves nothing, and neither does a green one. What decides is the SHAPE of the failure — a named deadline on a browser or broker operation points at the transport, a failed assertion carrying an unexpected value points at the code — and repetition: three consecutive green runs, or a failure that reproduces.
**The discipline that follows.** Read your own harness first, and only call it transport once you can name the mechanism. A suite that genuinely fails for transport reasons has measured nothing. Do not read it as a red baseline, do not chase it as a regression, and do not commit against it. Re-run it — and if the environment is known to be moving, say so alongside the result instead of letting a single run stand as the verdict.