← Journal technique
Ferry·frontend·2026-09-15

Un panneau VS Code vide, et un test qui passait quand même

A useRef initializer runs on every render, not just the first, so each re-render called acquireVsCodeApi() again — VS Code allows it once per webview, and the panel rendered empty.

Le filet avait un trou

Le test, le journal d'audit, le scanner, la CI — couvrant moins que je ne le supposais.

Première vraie installation du .vsix packagé : « Ferry: Open Panel » et « Pair a Device » ouvraient un webview vide.

La cause était useRef(client ?? new FerryClient()) — l'initialiseur d'un useRef est évalué à chaque rendu, pas seulement au premier, donc chaque nouveau rendu construisait un FerryClient frais → VsCodeTransport → appelait acquireVsCodeApi() à nouveau. VS Code n'autorise cet appel qu'une fois par webview ; le deuxième appel lève une exception, et React démontait tout l'arbre. Ça n'est jamais apparu dans le build navigateur, parce que là la même erreur fuitait simplement un WebSocketTransport de plus par rendu au lieu de crasher.

Le test e2e existant était vert pendant toute la durée où ce bug existait, parce qu'il vérifiait seulement qu'un onglet nommé « Ferry » existait — pas que quoi que ce soit s'affichait à l'intérieur.

Corrigé le bug (une init useRef paresseuse, plus un cache au niveau module pour qu'acquireVsCodeApi() ne puisse plus jamais être appelé deux fois) et corrigé le test pour qu'il attende le propre message {kind:"start"} du webview avant de passer, pour que « ouvert mais jamais monté » soit maintenant un échec dur. Vérifié en échec avant le correctif et en succès après, sur une vraie installation VS Code.

L'écart entre « le conteneur est là » et « la chose à l'intérieur fonctionne » est exactement là où l'expérience d'un vrai utilisateur et une suite de tests qui passe peuvent diverger longtemps sans que personne ne le remarque. Vérifier un signal que l'application émet elle-même quand elle est vraiment prête, pas un signal que l'hôte a simplement ouvert un emplacement pour elle.