Ce que seuls les tests en conditions réelles ont trouvé
Des tests automatisés au vert, une analyse statique propre, un code relu : tout indiquait que StormPress fonctionnait. Puis nous l'avons installé sur un vrai WordPress et cliqué partout. Récit de trois défauts que nos tests et nos relectures n'avaient pas vus.
Début septembre, avant de présenter StormPress plus largement, nous avons fait ce qu'on repousse toujours : installer l'extension sur un WordPress réel, avec de vrais contenus, et utiliser chaque écran comme le ferait un client. Pas un test unitaire, pas une relecture : une session complète, souris en main, captures à l'appui.
Ce que nous y avons trouvé justifie, à lui seul, que nous en fassions une règle.
1. La palette ⌘K ne s'affichait nulle part
La palette de commandes est la première fonction que nous mettions en avant. Elle avait ses tests, et ils passaient. Sur une vraie installation, pourtant, ⌘ K ne faisait rien. Ni sur notre site de test, ni ailleurs.
La cause tient en un attribut. L'interface est compilée en module JavaScript moderne, qui contient des instructions import. Un tel fichier doit être chargé avec <script type="module">. WordPress, lui, insère par défaut une balise <script> classique. Le navigateur tentait donc d'exécuter le module comme un script ordinaire, rencontrait une instruction qu'un script classique n'admet pas, et refusait le fichier entier — sans rien afficher à l'utilisateur.
Avec la palette tombaient en silence tout ce qui dépendait du même fichier sur les écrans classiques : les commandes slash, le graphe de contenus, le glisser-déposer des médias, l'enregistrement de la PWA.
Pourquoi les tests ne l'ont pas vu. Les tests de l'interface chargent le code avec l'outil de test, qui comprend parfaitement les modules. Ils vérifiaient que la palette fonctionne une fois chargée. Rien ne vérifiait qu'elle soit chargée.
La correction force le type du script au moment où WordPress l'insère dans la page, par un filtre compatible avec toutes les versions que nous prenons en charge. Elle est livrée depuis la 4.1.7.
2. Un connecteur qui s'éteignait en se mettant à jour
Fin septembre, sur un site en production, le connecteur embarqué dans StormPress s'est désactivé tout seul au cours d'une mise à jour. Et une fois désactivé, il ne pouvait plus recevoir l'ordre de se réactiver : le canal qui transportait cet ordre, c'était lui.
Un logiciel qui se coupe la branche sur laquelle il est assis. Le défaut tenait à une règle de WordPress : pendant une mise à jour, l'extension est désactivée, sauf si l'opération passe par le cron, et n'est réactivée ensuite que dans ce même cas. Nos mises à jour pilotées à distance arrivent par l'API REST : WordPress éteignait le connecteur et ne le rallumait pas. Rien ne le signalait tant que nous n'avions pas mis à jour un vrai site depuis la plateforme.
La correction, livrée dans le connecteur 3.13.6, a été embarquée dans la 4.1.8.
3. L'archive ne contenait pas ce que nous croyions
Le troisième défaut n'était pas dans le code, mais dans le paquet. En ouvrant l'archive téléchargeable de la 4.1.7, nous avons constaté qu'elle embarquait le connecteur 3.13.5, sans le correctif précédent, alors que les sources en étaient à la 3.13.6. Archive et sources portaient pourtant le même numéro, 4.1.7.
Une archive et des sources portant le même numéro, avec un contenu différent : c'est le scénario dans lequel tout le monde croit le problème réglé. La 4.1.8 existe en grande partie pour cela : livrer, dans l'archive réelle, ce que le dépôt contenait déjà.
Plus tôt dans l'année, l'inspection d'une archive nous avait déjà montré qu'elle contenait des fichiers de développement qui n'avaient rien à y faire. Les règles d'exclusion étaient correctes sur le papier ; l'archive, elle, disait autre chose.
Ce que nous faisons désormais
- Une fonction n'est pas terminée tant qu'elle n'a pas été utilisée sur une vraie installation. Les tests automatisés vérifient la logique ; ils ne vérifient pas que la page s'affiche. Quand cet essai n'a pas pu être fait, par exemple faute d'avoir installé l'extension tierce concernée, la fonction est publiée avec cette limite écrite noir sur blanc dans l'article qui la présente : c'est le cas de plusieurs intégrations de la 4.2.0.
- Nous inspectons l'artefact livré, pas la recette. Une liste d'exclusion ne prouve rien ; le contenu de l'archive, si. Un contrôle automatique compare désormais, fichier par fichier, le code PHP du connecteur embarqué dans l'archive de la version courante à ses sources : toute divergence de code non justifiée fait échouer notre intégration continue.
- Un numéro de version désigne un seul contenu. Si le contenu change, le numéro change.
- Un défaut trouvé à la main devient, quand c'est possible, un contrôle automatique. C'est ainsi qu'est né le contrôle de l'archive ; d'autres suivront.
La leçon, au-delà de StormPress
Le point commun de ces trois défauts est inconfortable : aucun indicateur n'est passé au rouge. Nos contrôles vérifiaient la logique, pas ce que vit l'utilisateur ni ce que reçoit le site. Le premier le montre crûment : une fonction affichée dans le menu peut n'avoir jamais fonctionné chez personne.
Si vous maintenez des sites WordPress, la même vérité s'applique à votre parc. Une mise à jour « réussie » n'est pas une mise à jour qui fonctionne. Ouvrir le site, cliquer sur les parcours qui comptent, regarder la console du navigateur : cinq minutes qui évitent de l'apprendre par un client.
Nous racontons les correctifs de sécurité de cet été dans un article séparé, avec la même transparence.