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.

TypeScriptPlaywrightCommanderaxe-coreZodVitestOpenAI (optionnel)

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.

Stack TypeScript + Playwright (library)
Architecture CLI modulaire (auditors pluggables)
Tests 333 (55.84% coverage)
Sessions Claude 44
Statut En développement

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

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.

Interface Auditor
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/CD
# 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.

1

Scénario pré-configuré

granit-golem.scenario.ts définit les URLs, auth et auditors

2

Crawl + Audit

marble-minotaur explore et audite l'application

3

Rapport JSON

Export structuré des résultats avec scores

4

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

333 Tests Vitest
55.84% Coverage Lignes couvertes
7 Auditors Modulaires
44 Sessions Claude Développement

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.