| name | playwright-qa |
| description | Live QA audit of a web app with playwright-cli — headed browser, video recording with chapters, console errors, mobile viewport, internal link check, and HTML report. Use when you want a recorded QA session on a live URL, not automated CI tests. |
| allowed-tools | Bash Read Write |
| license | MIT |
| metadata | {"source":"https://github.com/shubham-sharma-dev/playwright-qa (adaptation ulk)","maintainer":"izo"} |
Run a complete QA audit on a live web app using playwright-cli. Records a .webm video with named chapters, captures console errors, tests mobile viewport, audits internal links, checks images, then generates a self-contained HTML report.
Prerequisite — playwright-cli must be installed:
command -v playwright-cli >/dev/null 2>&1 || npm install -g playwright-cli
Distinct from the e2e agent (which writes @playwright/test suites for CI). This skill runs a live, recorded, human-readable audit session.
- `$ARGUMENTS` — the URL to audit (required). Example: `https://myapp.com`
- If no URL provided: ask the user before proceeding.
```bash
# 1. Check playwright-cli
command -v playwright-cli >/dev/null 2>&1 || { echo "Installing playwright-cli…"; npm install -g playwright-cli; }
2. Derive a short slug from the URL for file naming
SLUG=$(echo "$ARGUMENTS" | sed 's|https?://||;s|/.*||;s|[^a-zA-Z0-9]|-|g' | cut -c1-30)
VIDEO_PATH="/tmp/qa-${SLUG}.webm"
REPORT_PATH="/tmp/qa-report-${SLUG}.html"
3. Open browser and start recording
playwright-cli open "$ARGUMENTS" --browser=chrome --headed
playwright-cli video-start "$VIDEO_PATH"
</setup>
<chapters>
## Chapter 1 — Homepage: visual audit & console errors
```bash
playwright-cli video-chapter "Homepage — audit visuel & console" \
--description="Capture d'écran homepage + relevé erreurs console" --duration=3000
playwright-cli console # capture ALL warnings and errors — note every entry
playwright-cli screenshot /tmp/qa-${SLUG}-homepage.png
Chapter 2 — Mobile viewport: burger menu
playwright-cli video-chapter "Mobile — menu burger" \
--description="Viewport 390×844, test menu burger" --duration=3000
playwright-cli resize 390 844
playwright-cli highlight "[data-menu], [aria-label*='menu'], .burger, .hamburger" \
--style="outline: 3px solid #e85d26"
sleep 1
playwright-cli mousemove 195 50
sleep 1
playwright-cli click "[data-menu], [aria-label*='menu'], .burger, .hamburger"
playwright-cli screenshot /tmp/qa-${SLUG}-mobile-menu.png
playwright-cli console
Chapter 3 — Interactive elements
playwright-cli video-chapter "Éléments interactifs" \
--description="Filtres, accordéons, animations scroll" --duration=3000
playwright-cli resize 1440 900
playwright-cli --raw eval "
JSON.stringify({
accordions: document.querySelectorAll('[data-accordion], details').length,
filters: document.querySelectorAll('[data-filter], .filter-btn').length,
modals: document.querySelectorAll('[data-modal], [role=dialog]').length
})
"
Chapter 4 — Internal link audit
playwright-cli video-chapter "Audit liens internes" \
--description="Extraction hrefs, vérification HTTP 200" --duration=3000
BASE_URL=$(echo "$ARGUMENTS" | sed 's|\(https\?://[^/]*\).*|\1|')
LINKS=$(playwright-cli --raw eval "
JSON.stringify([...new Set(
[...document.querySelectorAll('a[href]')]
.map(a => a.href)
.filter(h => h.startsWith('${BASE_URL}') && !h.includes('#'))
)])
")
echo "$LINKS" | python3 -c "
import json, sys, urllib.request
links = json.load(sys.stdin)
for url in links[:30]: # cap at 30 to avoid timeout
try:
req = urllib.request.urlopen(url, timeout=5)
print(f'✅ {req.status} {url}')
except Exception as e:
print(f'❌ ERROR {url}: {e}')
" 2>/dev/null || echo "(python3 not available — skip HTTP checks)"
Chapter 5 — Images & lazy-loaded resources
playwright-cli video-chapter "Images & ressources" \
--description="Lazy load scroll + images cassées" --duration=3000
playwright-cli mousewheel 0 3000
sleep 1
playwright-cli mousewheel 0 3000
sleep 1
playwright-cli --raw eval "
JSON.stringify(
[...document.querySelectorAll('img')]
.filter(i => !i.complete || i.naturalWidth === 0)
.map(i => i.src)
)
"
playwright-cli screenshot /tmp/qa-${SLUG}-resources.png
Chapter 6 — Final report & close
playwright-cli video-chapter "Rapport final" \
--description="Clôture session QA" --duration=3000
playwright-cli video-stop
playwright-cli close
<html_report>
After closing the browser, generate $REPORT_PATH using the Write tool.
Structure:
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>QA Report — $SLUG</title>
<style>
body { font-family: system-ui, sans-serif; max-width: 960px; margin: 2rem auto; padding: 0 1rem; color: #1a1a1a; }
h1 { font-size: 1.5rem; border-bottom: 2px solid #e85d26; padding-bottom: .5rem; }
.metrics { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; margin: 1.5rem 0; }
.metric { background: #f5f5f5; border-radius: 8px; padding: 1rem; text-align: center; }
.metric strong { display: block; font-size: 2rem; color: #e85d26; }
.badge { display: inline-block; padding: .2em .6em; border-radius: 4px; font-size: .8rem; font-weight: 600; }
.badge-bug { background: #fee2e2; color: #b91c1c; }
.badge-warn { background: #fef3c7; color: #92400e; }
.badge-ok { background: #d1fae5; color: #065f46; }
.bug { border-left: 4px solid #e85d26; padding: .8rem 1rem; margin: .5rem 0; background: #fff7f5; }
.ok { border-left: 4px solid #22c55e; padding: .8rem 1rem; margin: .5rem 0; background: #f0fdf4; }
.screenshots { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.screenshots img { width: 100%; border-radius: 6px; border: 1px solid #e5e7eb; }
footer { margin-top: 3rem; font-size: .8rem; color: #6b7280; border-top: 1px solid #e5e7eb; padding-top: 1rem; }
</style>
</head>
<body>
<h1>QA Report — [URL testée]</h1>
<p><strong>Date :</strong> [date] · <strong>Environnement :</strong> Chrome headless → headed · <strong>Viewport :</strong> 1440×900 + 390×844</p>
<div class="metrics">
<div class="metric"><strong>[N]</strong>Pages testées</div>
<div class="metric"><strong>[N]</strong>Erreurs console</div>
<div class="metric"><strong>[N]</strong>Bugs trouvés</div>
<div class="metric"><strong>[N]</strong>Warnings</div>
</div>
<h2>Vidéo</h2>
<p>📹 <code>[VIDEO_PATH]</code></p>
<ul>
<li>00:00 — Homepage — audit visuel & console</li>
<li>00:XX — Mobile — menu burger</li>
<li>00:XX — Éléments interactifs</li>
<li>00:XX — Audit liens internes</li>
<li>00:XX — Images & ressources</li>
</ul>
<h2>Bugs trouvés</h2>
<div class="bug">
<span class="badge badge-bug">Bug</span>
<strong>[Titre]</strong>
<p>[Description technique avec sélecteur CSS ou URL]</p>
</div>
<h2>Warnings</h2>
<h2>✅ Ce qui fonctionne</h2>
<h2>Screenshots</h2>
<div class="screenshots">
</div>
<footer>Généré par Claude Code + playwright-cli · [date]</footer>
</body>
</html>
Embed screenshots as base64:
base64 /tmp/qa-${SLUG}-homepage.png 2>/dev/null
Then open the report:
open "$REPORT_PATH"
</html_report>
<navigation_rules>
OBLIGATOIRE pour chaque interaction UI :
playwright-cli highlight [sélecteur] --style="outline: 3px solid #e85d26" → sleep 1
playwright-cli mousemove [y] → sleep 1
- Action seulement après :
click / type / scroll
playwright-cli video-chapter entre chaque section (toujours avec --description et --duration)
</navigation_rules>
- `$VIDEO_PATH` — recording .webm complet avec chapters
- `$REPORT_PATH` — rapport HTML auto-contenu (screenshots base64, badges, métriques)
- Console: résumé des erreurs et warnings trouvés