Aller au contenu principal
Logo GiwiSoft
scenarii — Automatisez et surveillez vos scénarios web avec YAML

scenarii — Automatisez et surveillez vos scénarios web avec YAML

Xavier MARIN Xavier MARIN DevOps, Réalisations, Monitoring 6 min

Scenarii est un outil de monitoring et de test E2E que j’ai conçu pour automatiser la vérification de scénarios web complexes. Le principe est simple : vous décrivez vos scénarios en YAML, Scenarii les exécute périodiquement, stocke les métriques dans SQLite, et expose le tout sur un dashboard avec alertes par Telegram ou email.

Pourquoi scenarii ?

Les outils de monitoring classiques (Prometheus + blackbox-exporter, Uptime Kuma, Checkmk) brillent pour les vérifications simples : un port qui répond, un certificat SSL qui expire, une page HTTP qui renvoie 200. Mais dès qu’on veut enchaîner plusieurs étapes — par exemple : je me connecte, je navigue, je remplis un formulaire, je vérifie le résultat — ces outils deviennent limités.

Scenarii répond à ce besoin : une succession d’étapes, HTTP ou navigateur, avec extraction de variables, validation par assertions, et notification en cas de changement d’état.

Architecture

L’application suit une architecture monolithe modulaire :

Architecture

Points clés de l’architecture

  • Queue split : Les scénarios HTTP-only s’exécutent en parallèle via fetch natif. Les scénarios navigateur sont sérialisés sur une queue Promise-chain, car Lightpanda ne supporte qu’une connexion CDP à la fois.
  • Graceful degradation : Si @lightpanda/browser n’est pas installé, les scénarios HTTP continuent de fonctionner. Le binaire manquant est détecté au lancement avec un simple require.resolve.
  • Retry : Les steps navigateur réessayent automatiquement 2 fois (backoff 1s, 2s) en cas d’échec. Les notifications Telegram/Mailgun tentent 3 fois avec backoff exponentiel.
  • Hot-reload : Le fichier settings.yaml est surveillé via fs.watchFile et rechargé sans redémarrage.

Écrire un scénario

Un scénario est un fichier YAML. Voici un exemple complet :

name: Ma Boutique
base_url: https://ma-boutique.example.com
schedule: "*/10 * * * *"
timeout: 60000
ignoreHTTPSErrors: false

steps:
- name: Page d'accueil
action: http.get
path: /
expect:
status: 200
body_contains: "Bienvenue"
variables:
csrf: { json_path: "$.csrf_token" }

- name: Connexion
action: http.post
path: /api/login
headers:
Content-Type: application/json
body: |
{"email": "admin@test.com", "password": "test123", "_token": "{{csrf}}"}
expect:
status: 200
json_path: "$.token"
variables:
session: { json_path: "$.token" }

- name: Dashboard
action: browser.navigate
url: /dashboard
headers:
Authorization: "Bearer {{session}}"

- name: Vérifier le tableau
action: browser.wait_for
selector: "#stats"
timeout: 5000
expect:
has_text: "Commandes du jour"

Actions HTTP

Les actions HTTP utilisent l’API fetch native de Node.js — aucune dépendance navigateur n’est nécessaire. Idéal pour les APIs REST, les health checks, et les parcours critiques sans rendu JavaScript.

ActionDescription
http.get / http.post / http.put / http.patch / http.deleteRequêtes HTTP avec headers, body, et assertions

Assertions disponibles : status, status_in, body_contains, body_matches, json_path, json_value, response_time_under

Les variables sont extraites via json_path et réinjectées dans les steps suivantes avec {{variable_name}}.

Actions navigateur

Les actions navigateur utilisent Lightpanda, un navigateur headless en WebAssembly qui parle le protocole CDP de Playwright. Il est léger (~20 Mo) et démarre en ~200ms.

ActionDescription
browser.navigateNavigation vers une URL
browser.fillRemplir un champ (selector, value)
browser.typeSaisie caractère par caractère
browser.clickClic sur un élément
browser.wait_forAttente d’un sélecteur avec assertions (has_text, not_has_text, url_contains)
browser.selectSélection dans une liste déroulante
browser.evaluateExécution de JavaScript dans la page
browser.check / browser.uncheckCheckbox
browser.screenshotCapture d’écran

Dashboard

Le dashboard propose deux vues :

scenarii — Automatisez et surveillez vos scénarios web avec YAML
scenarii — Automatisez et surveillez vos scénarios web avec YAML
  • Liste des scénarios : Vue d’ensemble avec statut (pass/fail), taux de réussite, dernière exécution. Mise à jour temps réel via WebSocket.
  • Détail d’un scénario : Graphique de tendance des temps de réponse, taux de succès glissant, détail par step, historique paginé avec export JSON/CSV.
  • Thème dark/light : Bascule en navbar, preference persistée dans localStorage.

Le dashboard reçoit les mises à jour en temps réel via WebSocket (/ws). Après chaque exécution, un message JSON est broadcast à tous les clients connectés, ce qui permet une mise à jour instantanée sans polling.

API et monitoring

Endpoints REST

EndpointDescription
GET /api/scenariosListe des scénarios
GET /api/scenarios/:nameDétail avec historique paginé (?limit=&offset=)
GET /api/scenarios/:name/historyHistorique brut
GET /api/scenarios/:name/export/jsonExport JSON
GET /api/scenarios/:name/export/csvExport CSV
GET /api/healthHealth check
GET /api/metricsFormat Prometheus/OpenMetrics

Métriques Prometheus

L’endpoint /api/metrics expose au format OpenMetrics :

# HELP scenarii_scenario_runs_total Total number of scenario runs
# TYPE scenarii_scenario_runs_total counter
scenarii_scenario_runs_total{scenario="Ma Boutique"} 142

# HELP scenarii_scenario_duration_ms Latest scenario duration in milliseconds
# TYPE scenarii_scenario_duration_ms gauge
scenarii_scenario_duration_ms{scenario="Ma Boutique"} 2340

# HELP scenarii_scenario_success Latest run success (1=pass, 0=fail)
# TYPE scenarii_scenario_success gauge
scenarii_scenario_success{scenario="Ma Boutique"} 1

# HELP scenarii_step_duration_ms Step execution duration in milliseconds
# TYPE scenarii_step_duration_ms gauge
scenarii_step_duration_ms{scenario="Ma Boutique",step="Page d'accueil",action="http.get"} 320

Idéal pour Grafana : vous pouvez superposer les temps de réponse de vos scénarios avec les métriques système.

Notifications

scenarii notifie en cas de changement d’état : passage de succès à échec (failure), ou de échec à succès (recovery). Pas de spam — uniquement les transitions.

Configuration

notifications:
telegram:
enabled: true
bot_token: "VOTRE_TOKEN"
chat_id: "VOTRE_CHAT_ID"
email:
enabled: true
mailgun:
api_key: "VOTRE_API_KEY"
domain: "VOTRE_DOMAIN"
from: "scenarii <noreply@domain.com>"
to:
- "admin@domain.com"

Les tokens peuvent aussi être passés en variables d’environnement (TELEGRAM_BOT_TOKEN, MAILGUN_API_KEY, etc.) pour éviter de stocker des secrets dans le dépôt.

Un rapport quotidien est également envoyé chaque matin à 8h, résumant l’état de tous les scénarios.

Gestion des scénarios par scénario

Il est possible de surcharger les paramètres par scénario :

scenarios:
mon-scenario-lent:
timeout: 120000
ignoreHTTPSErrors: true
notifications:
enabled: false

Conteneurisation

L’image Docker est construite en multi-stage Alpine (Node.js 26), avec dumb-init pour la gestion des signaux et USER node pour la sécurité :

docker pull ghcr.io/giwi/giwisoft-scenarii:latest

docker run -d \
--name scenarii \
-p 3000:3000 \
-v /chemin/scenarios:/scenarios \
-v /chemin/db:/app/db \
-v /chemin/settings.yaml:/app/settings.yaml:ro \
ghcr.io/giwi/giwisoft-scenarii:latest

Le conteneur expose un HEALTHCHECK qui ping /api/health toutes les 30s, et un volume pour monter vos fichiers YAML de scénarios.

CLI

En plus du mode serveur, scenarii propose plusieurs commandes :

# Valider un fichier YAML
node dist/index.js validate scenarios/mon-test.yml

# Exécuter un scénario immédiatement
node dist/index.js trigger scenarios/mon-test.yml --json

# Voir l'état courant
node dist/index.js status

# Générer un template settings.yaml
node dist/index.js config --init

Conclusion

scenarii est un outil que j’utilise quotidiennement pour m’assurer que mes applications web fonctionnent correctement. Il remplace avantageusement une batterie de scripts shell ou de checks Prometheus quand on a besoin de scénarios multi-étapes.

Ce qui le distingue :

  • YAML comme DSL — facile à versionner, à lire, à écrire
  • HTTP sans navigateur — pas de surcharge pour les scénarios simples
  • Métriques temps réel — WebSocket + Prometheus + dashboard
  • Conteneurisé — un docker run et c’est prêt

Le code est disponible sur GitHub. Contributions et retours bienvenus !