Étude de cas : marble-minotaur
URL → Browser (Playwright) → Auth Detect → BFS Crawler → Page Analysis → HTML Report / CI Gate
Marble Minotaur
Auditeur web automatisé
Crawler BFS qui explore des applications web et génère des rapports d'audit complets. 7 auditors modulaires (SEO, accessibilité, performance, sécurité, formulaires, i18n, images). Mode CI/CD avec scoring et quality gates. Conçu pour alimenter Granit Golem.
marble-minotaur est un auditeur web automatisé qui explore le labyrinthe (l'application) et rapporte chaque problème. Plutôt que d'auditer manuellement chaque page, le Minotaure parcourt l'app en BFS et génère des rapports complets.
1. Contexte et objectifs
Problématique
Automatiser les audits qualité web. Plutôt que d'auditer manuellement chaque page d'une application, le Minotaure explore le labyrinthe (l'app) et rapporte chaque problème trouvé.
- Crawl automatique de toutes les pages accessibles
- Audit multi-critères : SEO, accessibilité, performance, sécurité, formulaires, i18n, images
- Rapports HTML interactifs avec screenshots
- Mode CI/CD avec scoring et quality gates
- Alimentation de Granit Golem pour le monitoring continu
Pourquoi Playwright comme library ?
Vrai navigateur
Chromium complet pour un rendu fidèle, JS exécuté, SPA supportées nativement.
Auth automatique
Détection et remplissage automatique des formulaires de login avant le crawl.
Screenshots
Capture d'écran de chaque page auditée pour les rapports visuels.
API flexible
Utilisé comme library, pas comme test runner. Contrôle total sur le cycle de vie du navigateur.
2. Architecture modulaire
Structure du projet
src/
├── cli.ts # CLI entry (Commander)
├── engine.ts # Core orchestrator
├── auditors/ # 7 auditors pluggables
│ ├── accessibility.auditor.ts # axe-core + ARIA
│ ├── seo.auditor.ts # title, meta, h1, og:tags
│ ├── performance.auditor.ts # Core Web Vitals (LCP, CLS)
│ ├── security-headers.auditor.ts # HSTS, CSP, X-Frame
│ ├── forms.auditor.ts # Form field validation
│ ├── i18n.auditor.ts # Translation key check
│ └── images.auditor.ts # src/alt validation
├── services/
│ ├── crawler.service.ts # BFS traversal engine
│ ├── auth.service.ts # Automatic login detection
│ ├── gate.service.ts # Quality gate scoring
│ └── llm-scenario-planner.service.ts # GPT form workflows
├── scenarios/
│ └── granit-golem.scenario.ts # Pre-configured crawl
└── report/
├── console.reporter.ts # Terminal output
└── html.reporter.ts # Interactive HTML reports Interface Auditor
Chaque auditor implémente la même interface. Facile d'en ajouter de nouveaux sans toucher au code existant :
Contrat uniforme
Tous les auditors partagent la même interface : un nom, une méthode audit() qui reçoit une page Playwright et retourne un score 0-100 avec les issues trouvées.
export interface Auditor {
name: string;
audit(page: Page, url: string): Promise<AuditResult>;
}
export interface AuditResult {
auditor: string;
score: number; // 0-100
issues: AuditIssue[];
metadata?: Record<string, unknown>;
} Les 7 auditors
Accessibility
axe-core + vérification ARIA. Détecte les violations WCAG 2.1 AA : contraste, labels, structure sémantique.
SEO
Title, meta description, H1 unique, og:tags, canonical URL. Vérifie les bonnes pratiques de référencement.
Performance
Core Web Vitals : LCP (Largest Contentful Paint), CLS (Cumulative Layout Shift). Métriques de performance réelles.
Security Headers
HSTS, CSP, X-Frame-Options, X-Content-Type-Options. Vérifie les headers de sécurité HTTP.
Forms
Validation des champs de formulaire : labels associés, types corrects, attributs autocomplete.
i18n
Détection de clés de traduction non résolues (textes affichés comme "key.path.label").
Images
Vérification des attributs src et alt. Détecte les images sans texte alternatif ou avec des src cassés.
3. BFS Crawler
Le crawler parcourt l'application en largeur d'abord (BFS), garantissant une couverture de surface optimale :
Détection de liens internes
Extraction automatique des liens <a href> internes, filtrage des liens externes et ancres.
Anti-boucles
Suivi des URLs déjà visitées pour éviter les boucles infinies dans la navigation.
Max-pages configurable
Limite le nombre de pages crawlées pour contrôler la durée et les ressources.
Auth automatique
Détecte les formulaires de login et s'authentifie automatiquement avant de crawler les pages protégées.
4. Mode CI/CD
marble-minotaur s'intègre dans les pipelines CI/CD avec un mode dédié : score global, seuil configurable, et exit code pour bloquer les déploiements si la qualité n'est pas au rendez-vous.
# Utilisation CI
npx tsx src/cli.ts https://app.example.com \
--ci --ci-threshold 70 \
--output json --output-path report.json
# Exit 0 si score >= 70, exit 1 sinon Score global pondéré
Chaque auditor retourne un score 0-100. Le score global est une moyenne pondérée configurable.
Quality gate
Seuil configurable via --ci-threshold. Exit 0 si le score est au-dessus, exit 1 sinon.
Output JSON
Export des résultats en JSON pour intégration avec d'autres outils (Granit Golem, dashboards).
5. Intégration Granit Golem
marble-minotaur est conçu pour alimenter la plateforme de monitoring Granit Golem. Les scénarios pré-configurés génèrent des rapports qui deviennent des audits dans le système de monitoring.
Scénario pré-configuré
granit-golem.scenario.ts définit les URLs, auth et auditors
Crawl + Audit
marble-minotaur explore et audite l'application
Rapport JSON
Export structuré des résultats avec scores
Granit Golem
Import comme audit avec historique et tendances
6. LLM Scenario Planner
Utilisation optionnelle de GPT-4o-mini pour planifier les scénarios de remplissage de formulaires lors du crawl. Quand le crawler rencontre un formulaire, le LLM génère un plan de remplissage intelligent basé sur le contexte de la page.
7. Configuration CLAUDE.md
Le CLAUDE.md de marble-minotaur contient un piège important spécifique à l'utilisation de Playwright comme library avec esbuild/tsx :
CLAUDE.md Piège Playwright ## Playwright rules (MANDATORY)
### page.evaluate()
- MUST receive a string, NEVER a closure/arrow function
- tsx/esbuild injects `__name` that breaks browser context
BAD:
```typescript
await page.evaluate(() => document.title);
```
GOOD:
```typescript
await page.evaluate('document.title');
```
### Playwright usage
- Playwright is used as a LIBRARY, not a test runner
- Do NOT use expect() from @playwright/test
- Use Playwright browser automation APIs only
### Testing
- Run `vitest run` before considering code done
- Target: maintain 55%+ coverage
- Track technical debt via `// DEBT:` comments 8. Métriques
Fonctionnalités clés
| Fonctionnalité | Statut | Détails |
|---|---|---|
| BFS Crawler | Opérationnel | Parcours en largeur, anti-boucles, max-pages |
| 7 Auditors | Opérationnel | SEO, A11y, Perf, Security, Forms, i18n, Images |
| Mode CI/CD | Opérationnel | Quality gates avec seuil configurable |
| Rapports HTML | Opérationnel | Interactifs avec screenshots |
| Auth automatique | Opérationnel | Détection et login automatique |
| LLM Scenario Planner | Optionnel | GPT-4o-mini pour remplissage de formulaires |
| Technical debt tracking | Opérationnel | Via commentaires // DEBT: |
9. Enseignements
Playwright comme library > comme test runner
Pour du tooling (crawl, audit, scraping), Playwright en library offre un contrôle total sur le cycle de vie du navigateur, sans les contraintes du test runner.
Auditors pluggables = extensibilité sans régression
L'interface Auditor permet d'ajouter de nouveaux auditors sans toucher au code existant. Chaque auditor est testable indépendamment.
BFS > DFS pour la couverture de surface
Le parcours en largeur couvre plus rapidement les pages principales, donnant des résultats exploitables même si le crawl est interrompu.
CLAUDE.md prévient les bugs subtils
Le piège page.evaluate() avec esbuild est un excellent exemple de bug que le compilateur ne détecte pas mais que CLAUDE.md prévient efficacement.