Ce que je fais
Je fournis un contrôle complet d'un navigateur réel (Chrome/Chromium) qui te permet de :
- Tester l'interface : Valider visuellement le rendu des composants et thèmes
- Vérifier l'accessibilité : Analyser l'arbre a11y (roles, labels, aria-*)
- Débugger : Reproduire bugs visuels et capturer screenshots + console logs
- Scraper des données : Extraire du contenu depuis des sites web externes
- Valider des workflows : Tester des parcours utilisateurs complets
- Tester PWA : Vérifier installation, mode offline, notifications
Quand m'utiliser
Utilise-moi dans les situations suivantes :
🎨 Tests visuels et UI
- Validation de thèmes : Tester l'apparence des 10 thèmes daisyUI
- Tests de composants : Vérifier le rendu visuel de nouveaux composants
- Tests de responsive : Valider sur différentes tailles d'écran
- Vérification de layout : S'assurer que le layout est correct
♿ Accessibilité
- Audit a11y : Analyser l'arbre d'accessibilité complet
- Validation ARIA : Vérifier roles, labels, aria-* attributes
- Tests keyboard : Valider navigation au clavier
- Tests screen reader : Vérifier structure sémantique
🐛 Debugging
- Reproduire bugs : Automatiser les steps pour reproduire un bug visuel
- Capturer état : Screenshots + console logs pour analyse
- Tests de regression : Vérifier que les bugs ne reviennent pas
🌐 Scraping et extraction
- Import de questions : Extraire des questions depuis des sites externes
- Collecte de données : Récupérer du contenu web structuré
- Monitoring : Vérifier disponibilité de ressources externes
✅ Tests d'intégration
- Workflows utilisateur : Tester parcours complets (quiz, import, settings)
- PWA features : Valider installation, offline, cache
- Interactions complexes : Drag & drop, gestures, animations
Comment m'utiliser
1. Navigation
// Naviguer vers une URL
browsermcp_browser_navigate({
url: 'http://localhost:5173',
})
// Navigation arrière/avant
browsermcp_browser_go_back()
browsermcp_browser_go_forward()
⚠️ Important : Le serveur dev doit être actif (bun dev) pour tester l'application locale
2. Analyse de la page
// Capturer snapshot d'accessibilité (structure complète)
const snapshot = await browsermcp_browser_snapshot()
// Retourne l'arbre a11y avec refs pour interactions
// Exemple de snapshot:
// {
// "role": "WebArea",
// "name": "Chiropraxie QCM",
// "children": [
// {
// "role": "button",
// "name": "Démarrer le quiz",
// "ref": "btn-start-quiz"
// },
// {
// "role": "combobox",
// "name": "Sélecteur de thème",
// "ref": "theme-select"
// }
// ]
// }
3. Interactions
// CLIQUER sur un élément
browsermcp_browser_click({
element: 'Button "Démarrer le quiz"',
ref: 'btn-start-quiz', // Référence depuis le snapshot
})
// SURVOLER un élément
browsermcp_browser_hover({
element: 'Theme selector dropdown',
ref: 'theme-select',
})
// TAPER du texte
browsermcp_browser_type({
element: 'Search input',
ref: 'search-input',
text: 'anatomie',
submit: false, // true pour presser Enter après
})
// SÉLECTIONNER option(s) dans dropdown
browsermcp_browser_select_option({
element: 'Theme dropdown',
ref: 'theme-select',
values: ['nocturne'], // Peut être un array pour sélection multiple
})
// PRESSER une touche
browsermcp_browser_press_key({
key: 'Escape', // 'ArrowLeft', 'Enter', 'Tab', etc.
})
⚠️ Refs volatiles : Les refs changent à chaque render. Toujours recapturer un snapshot après interactions importantes.
4. Attente et timing
// Attendre un délai fixe (en secondes)
browsermcp_browser_wait({
time: 2,
})
💡 Best practice : Utiliser browser_wait() après actions qui déclenchent :
- Animations CSS/JS
- Fetch API / appels Ollama
- Transitions de page
- Updates de state React
5. Capture et logs
// Screenshot de la page actuelle
const screenshot = await browsermcp_browser_screenshot()
// Retourne image base64
// Récupérer logs console
const logs = await browsermcp_browser_get_console_logs()
// Retourne array de {level: 'log'|'warn'|'error', message: string}
Workflow recommandé
Workflow de base
┌─────────────────────────────────┐
│ 1. Lancer serveur dev │
│ bun dev │
└─────────────┬───────────────────┘
│
▼
┌─────────────────────────────────┐
│ 2. browser_navigate() │
│ http://localhost:5173 │
└─────────────┬───────────────────┘
│
▼
┌─────────────────────────────────┐
│ 3. browser_snapshot() │
│ Capturer structure page │
└─────────────┬───────────────────┘
│
▼
┌─────────────────────────────────┐
│ 4. Interactions │
│ click, type, select, etc. │
└─────────────┬───────────────────┘
│
▼
┌─────────────────────────────────┐
│ 5. browser_screenshot() │
│ Capturer résultat visuel │
└─────────────────────────────────┘
Workflow avec vérification
┌─────────────────────────────────┐
│ 1. Navigation │
└─────────────┬───────────────────┘
│
▼
┌─────────────────────────────────┐
│ 2. Snapshot initial │
└─────────────┬───────────────────┘
│
▼
┌─────────────────────────────────┐
│ 3. Interactions │
└─────────────┬───────────────────┘
│
▼
┌─────────────────────────────────┐
│ 4. Attente (si nécessaire) │
│ browser_wait() │
└─────────────┬───────────────────┘
│
▼
┌─────────────────────────────────┐
│ 5. Snapshot de vérification │
│ Valider changements │
└─────────────┬───────────────────┘
│
▼
┌─────────────────────────────────┐
│ 6. Screenshot + logs │
│ Documentation/debug │
└─────────────────────────────────┘
Cas d'usage typiques
1. Valider tous les thèmes visuellement
// Navigation
await browsermcp_browser_navigate({ url: 'http://localhost:5173' })
// Snapshot pour trouver le sélecteur
const snapshot = await browsermcp_browser_snapshot()
// Boucle sur les 10 thèmes
const themes = [
'toulouse',
'nocturne',
'clown',
'azure',
'forest',
'sunset',
'ocean',
'medical',
'lavande',
'cupcake',
]
for (const theme of themes) {
// Sélectionner le thème
await browsermcp_browser_select_option({
element: 'Theme selector',
ref: 'theme-select',
values: [theme],
})
// Attendre transition CSS
await browsermcp_browser_wait({ time: 0.5 })
// Capturer screenshot pour validation
const screenshot = await browsermcp_browser_screenshot()
console.log(`Theme ${theme} captured`)
}
2. Tester workflow complet de quiz
// 1. Navigation
await browsermcp_browser_navigate({ url: 'http://localhost:5173' })
// 2. Snapshot pour identifier éléments
const homeSnapshot = await browsermcp_browser_snapshot()
// 3. Démarrer quiz
await browsermcp_browser_click({
element: 'Start quiz button',
ref: 'btn-start',
})
// 4. Attendre chargement
await browsermcp_browser_wait({ time: 1 })
// 5. Snapshot de la page quiz
const quizSnapshot = await browsermcp_browser_snapshot()
// 6. Répondre à la question
await browsermcp_browser_click({
element: 'Choice A',
ref: 'choice-a',
})
// 7. Valider la réponse
await browsermcp_browser_click({
element: 'Submit answer button',
ref: 'btn-submit',
})
// 8. Screenshot du résultat
await browsermcp_browser_screenshot()
// 9. Vérifier console logs (pas d'erreurs)
const logs = await browsermcp_browser_get_console_logs()
const errors = logs.filter(log => log.level === 'error')
if (errors.length > 0) {
console.error('Errors found:', errors)
}
3. Vérifier l'accessibilité
// Navigation
await browsermcp_browser_navigate({ url: 'http://localhost:5173/quiz' })
// Snapshot retourne arbre a11y complet
const a11yTree = await browsermcp_browser_snapshot()
// Vérifications manuelles ou automatiques:
// - Tous les boutons ont un role="button"
// - Tous les inputs ont des labels
// - Navigation possible au clavier
// - ARIA attributes appropriés
// - Structure sémantique correcte
// Exemple: Vérifier que le bouton start existe
const startButton = findInTree(a11yTree, {
role: 'button',
name: /démarrer|start/i,
})
if (!startButton) {
console.error('Start button not found in a11y tree')
}
4. Scraper des questions depuis un site externe
// Navigation vers site public
await browsermcp_browser_navigate({
url: 'https://example.com/chiropraxie-questions',
})
// Snapshot pour analyser structure
const snapshot = await browsermcp_browser_snapshot()
// Cliquer sur une catégorie
await browsermcp_browser_click({
element: 'Anatomie category',
ref: 'cat-anatomie',
})
// Attendre chargement des questions
await browsermcp_browser_wait({ time: 2 })
// Re-snapshot pour obtenir les questions
const questionsSnapshot = await browsermcp_browser_snapshot()
// Parser le snapshot pour extraire questions
// (logique custom selon structure du site)
const questions = parseQuestionsFromSnapshot(questionsSnapshot)
5. Debugger un bug visuel
// Reproduire état problématique
await browsermcp_browser_navigate({ url: 'http://localhost:5173/quiz' })
// Appliquer thème problématique
await browsermcp_browser_click({
element: 'Theme nocturne',
ref: 'theme-nocturne',
})
// Déclencher l'action qui cause le bug
await browsermcp_browser_click({
element: 'Start quiz',
ref: 'btn-start',
})
// Attendre que le bug apparaisse
await browsermcp_browser_wait({ time: 1 })
// Screenshot pour voir le bug
const screenshot = await browsermcp_browser_screenshot()
// Logs console pour erreurs JS
const logs = await browsermcp_browser_get_console_logs()
const errors = logs.filter(log => log.level === 'error')
// Analyser et documenter
console.log('Bug screenshot captured')
console.log('Console errors:', errors)
6. Tester les fonctionnalités PWA
// 1. Vérifier installation PWA
await browsermcp_browser_navigate({ url: 'http://localhost:5173' })
// 2. Screenshot de la page d'accueil
await browsermcp_browser_screenshot()
// 3. Tester mode offline (nécessite service worker actif)
// Note: Simulation d'offline non supportée directement,
// mais on peut vérifier que l'app charge sans erreurs
// 4. Vérifier manifest et icons
const logs = await browsermcp_browser_get_console_logs()
const manifestWarnings = logs.filter(
log => log.message.includes('manifest') || log.message.includes('icon')
)
if (manifestWarnings.length > 0) {
console.warn('PWA manifest warnings:', manifestWarnings)
}
Capacités du serveur MCP
Ce skill s'appuie sur le serveur MCP browsermcp configuré dans ton opencode.json :
{
"browsermcp": {
"type": "local",
"command": ["npx", "-y", "@executeautomation/browser-mcp"],
"enabled": true
}
}
Tools disponibles :
browser_navigate: Navigation vers URLbrowser_go_back/browser_go_forward: Navigation historiquebrowser_snapshot: Capture arbre d'accessibilitébrowser_click: Clic sur élémentbrowser_hover: Survol d'élémentbrowser_type: Saisie de textebrowser_select_option: Sélection dans dropdownbrowser_press_key: Pression de touche clavierbrowser_wait: Attente temporiséebrowser_screenshot: Capture d'écranbrowser_get_console_logs: Récupération logs console
Bonnes pratiques
✅ À FAIRE
- Lancer le serveur dev AVANT :
bun devdoit être actif - Toujours snapshot avant interactions : Les refs sont volatiles
- Attendre après animations : Utiliser
browser_wait()après actions lourdes - Capturer screenshots : Documentation visuelle utile
- Vérifier console logs : Erreurs JS souvent invisibles visuellement
- Descriptions claires : Le paramètre
elementdoit être descriptif - Re-snapshot après changements : Refs peuvent changer après interactions
❌ À ÉVITER
- Utiliser des refs obsolètes : Toujours recapturer après render
- Oublier les attentes : Ne pas enchaîner interactions trop vite
- Ignorer les erreurs console : Peuvent indiquer problèmes cachés
- Tests sans serveur : Browser MCP ne peut pas tester sans serveur actif
- Refs hardcodés : Les refs changent, toujours utiliser ceux du snapshot récent
- Trop de wait() : Optimiser timing, pas attendre aveuglément
Intégration avec MemoAI
// Après validation visuelle d'une feature
await browsermcp_browser_navigate({ url: 'http://localhost:5173' })
// ... tests Browser MCP ...
await browsermcp_browser_screenshot()
// Enregistrer dans MemoAI si OK
await memoai_memo_record({
content:
'Feature: Sélecteur de thème avec 10 options. Testé avec Browser MCP, tous les thèmes appliquent correctement les couleurs. Dropdown fonctionne, persistance localStorage OK.',
type: 'implementation',
context_files: ['src/components/ThemeSelector.tsx', 'src/stores/settingsStore.ts'],
tags: ['ui', 'theming', 'browser-tested'],
})
// Workflow complet: Bug → Browser MCP → Fix → Test → MemoAI
Workflow de debugging avec MemoAI
┌─────────────────────────────────┐
│ PROBLÈME VISUEL IDENTIFIÉ │
└─────────────┬───────────────────┘
│
▼
┌─────────────────────────────────┐
│ 1. RECHERCHE MEMOAI │
│ Bugs similaires passés │
└─────────────┬───────────────────┘
│
▼
┌─────────────────────────────────┐
│ 2. REPRODUCTION BROWSER MCP │
│ Navigate, interact, wait │
└─────────────┬───────────────────┘
│
▼
┌─────────────────────────────────┐
│ 3. CAPTURE │
│ Screenshot + console logs │
└─────────────┬───────────────────┘
│
▼
┌─────────────────────────────────┐
│ 4. FIX + TEST AVEC BROWSER MCP │
│ Valider correction │
└─────────────┬───────────────────┘
│
▼
┌─────────────────────────────────┐
│ 5. ENREGISTREMENT MEMOAI │
│ Bug + solution + screenshots │
└─────────────────────────────────┘
Cas d'usage spécifiques au projet chiropraxie-qcm-v2
Validation des 10 thèmes daisyUI
// Script de validation complète
const themes = [
'toulouse',
'nocturne',
'clown',
'azure',
'forest',
'sunset',
'ocean',
'medical',
'lavande',
'cupcake',
]
for (const theme of themes) {
await browsermcp_browser_select_option({
element: 'Theme selector',
ref: 'theme-select',
values: [theme],
})
await browsermcp_browser_wait({ time: 0.5 })
const screenshot = await browsermcp_browser_screenshot()
// Valider couleurs, contraste, lisibilité
}
Test workflow import Quizlet
// Tester import de questions
await browsermcp_browser_navigate({ url: 'http://localhost:5173/import' })
await browsermcp_browser_snapshot()
// Coller texte Quizlet
await browsermcp_browser_type({
element: 'Import textarea',
ref: 'import-textarea',
text: 'Question 1\tRéponse 1\nQuestion 2\tRéponse 2',
submit: false,
})
// Valider import
await browsermcp_browser_click({
element: 'Import button',
ref: 'btn-import',
})
await browsermcp_browser_wait({ time: 1 })
await browsermcp_browser_screenshot()
// Vérifier console logs (pas d'erreurs parsing)
const logs = await browsermcp_browser_get_console_logs()
Test génération IA avec Ollama
// Vérifier que l'IA génère bien des questions
await browsermcp_browser_navigate({ url: 'http://localhost:5173/generate' })
await browsermcp_browser_snapshot()
// Remplir prompt
await browsermcp_browser_type({
element: 'Prompt input',
ref: 'prompt-input',
text: "Génère 3 questions sur l'anatomie vertébrale",
submit: false,
})
// Lancer génération
await browsermcp_browser_click({
element: 'Generate button',
ref: 'btn-generate',
})
// Attendre réponse Ollama (peut être long)
await browsermcp_browser_wait({ time: 10 })
// Screenshot résultat
await browsermcp_browser_screenshot()
// Vérifier logs (pas d'erreur Ollama)
const logs = await browsermcp_browser_get_console_logs()
const ollamaErrors = logs.filter(log => log.level === 'error' && log.message.includes('ollama'))
Limitations
- Serveur dev requis : Ne peut pas tester build production facilement
- Pas de simulation réseau : Offline mode difficile à tester
- Refs volatiles : Nécessite re-snapshot fréquent
- Timing délicat : Peut nécessiter ajustements de wait()
- Pas de tests headless natifs : Utiliser Playwright pour CI/CD
Complémentarité avec Playwright
- Browser MCP : Tests manuels, validation visuelle, debugging interactif
- Playwright : Tests automatisés, CI/CD, regression testing, headless
Workflow recommandé :
- Développement : Browser MCP pour validation rapide
- Pre-commit : Playwright tests automatiques
- CI/CD : Playwright full suite
Références
- Configuration OpenCode:
.opencode/opencode.json - Documentation Browser MCP: https://github.com/executeautomation/browser-mcp
- Playwright (complémentaire): https://playwright.dev/
Converted and distributed by TomeVault — claim your Tome and manage your conversions.