Un client équipé du thème sombre d’administration, activé depuis son profil utilisateur, nous a signalé un tableau de bord personnalisé totalement illisible : texte gris sur fond gris, un widget qui affichait ses données en blanc sur blanc. Le composant fonctionnait parfaitement en thème clair, celui que toute l’équipe de développement utilisait par défaut. Le mode sombre de l’administration, disponible nativement dans le profil utilisateur WordPress, n’était tout simplement jamais testé.
Depuis cet incident, nous générons systématiquement, à chaque déploiement en recette, des captures d’écran des zones d’administration personnalisées dans les deux modes, comparées automatiquement à une image de référence pour détecter tout écart de rendu.
Activer le mode sombre pour un utilisateur de test
Le mode sombre de l’administration s’active via la meta utilisateur admin_color, réglable directement en base sans passer par l’interface, ce qui simplifie beaucoup l’automatisation :
wp user meta update 1 admin_color modern
wp user meta update 1 admin_color light
Sur les installations récentes, la palette modern introduit un fond sombre par défaut pour l’écran de connexion et certains éléments, tandis que light et default restent dans la palette claire historique. On teste les deux dans la même suite, en réinitialisant la couleur entre chaque capture.
Écrire le scénario Playwright de capture

import { test, expect } from '@playwright/test';
const ecrans = [
{ nom: 'tableau-de-bord', url: '/wp-admin/index.php' },
{ nom: 'liste-reservations', url: '/wp-admin/edit.php?post_type=reservation' },
{ nom: 'widget-statistiques', url: '/wp-admin/admin.php?page=stats-client' },
];
const palettes = ['light', 'modern'];
for (const palette of palettes) {
for (const ecran of ecrans) {
test(`capture ${ecran.nom} en palette ${palette}`, async ({ page }) => {
await page.goto(`/wp-admin/admin-ajax.php?action=set_test_palette&palette;=${palette}`);
await page.goto(ecran.url);
await page.waitForLoadState('networkidle');
await expect(page).toHaveScreenshot(`${ecran.nom}-${palette}.png`, {
maxDiffPixelRatio: 0.02,
});
});
}
}
Le seuil de tolérance maxDiffPixelRatio évite de faire échouer le test pour un antialiasing de police différent d’une machine à l’autre, tout en restant assez strict pour attraper un bloc de texte devenu invisible.
Cibler en priorité les écrans où un plugin injecte ses propres styles
Les écrans natifs de WordPress sont déjà testés par le cœur du projet pour les deux palettes. Le risque se concentre sur les écrans où une extension ou un thème ajoute ses propres feuilles de style, souvent écrites en supposant implicitement un fond blanc. Une couleur de texte codée en dur comme color: #333 sans tenir compte de la variable --wp-admin-theme-color ou du sélecteur .admin-color-modern est le symptôme le plus fréquent.
- Widgets de tableau de bord personnalisés.
- Colonnes ajoutées dans les listes d’articles via
manage_posts_columns. - Pages de réglages construites avec l’API Settings sans styles additionnels prévus pour le mode sombre.
- Notices admin personnalisées affichées via
admin_notices.
Automatiser la mise à jour des références après une refonte volontaire
Comme pour toute régression visuelle, la difficulté n’est pas de détecter un écart, mais de distinguer une régression involontaire d’une évolution volontaire de design. Nous exigeons qu’une refonte visuelle documentée dans un ticket s’accompagne de la commande de régénération des références dans le même commit, jamais dans un commit séparé qui masquerait la revue :
npx playwright test --update-snapshots
Notre verdict
Ce test coûte peu à mettre en place une fois l’infrastructure de capture Playwright déjà en place pour d’autres besoins, et il a permis de repérer, sur un autre projet, un bouton d’action devenu totalement transparent en mode sombre suite à une mise à jour de dépendance CSS. Un utilisateur en thème clair n’aurait jamais pu signaler ce défaut puisqu’il ne l’aurait jamais vu.