- Surse complete web (React/Vite) + mobil (React Native/Expo) + extensie (MV3) - Documentație de livrare: ghid utilizare, matrice trasabilitate cerințe, raport testare furnizor - Artefacte binare: imagine Docker didi-frontend:lot3-1.0, APK, extensie v3.2.6 + SHA256SUMS - Configurare adresă platformă externalizată (build args / .env / config.js) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
126 lines
4 KiB
Bash
Executable file
126 lines
4 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# WCAG 2.1 AA audit script — runs Lighthouse + axe-core against key pages.
|
|
#
|
|
# Usage:
|
|
# ./scripts/wcag-audit.sh # Default: https://didi365.eu
|
|
# BASE_URL=http://localhost:5173 ./scripts/wcag-audit.sh
|
|
#
|
|
# Required deps (auto-install if missing):
|
|
# - @axe-core/cli
|
|
# - lighthouse
|
|
#
|
|
# Output:
|
|
# - reports/wcag/<timestamp>/lighthouse-<page>.html
|
|
# - reports/wcag/<timestamp>/axe-<page>.json
|
|
# - reports/wcag/<timestamp>/SUMMARY.md
|
|
#
|
|
# Audit produces a formal report for PNRR recepție (cerință E5 caiet sarcini).
|
|
set -euo pipefail
|
|
|
|
BASE_URL="${BASE_URL:-https://didi365.eu}"
|
|
TIMESTAMP=$(date -u +"%Y%m%d-%H%M%S")
|
|
OUT_DIR="reports/wcag/${TIMESTAMP}"
|
|
mkdir -p "$OUT_DIR"
|
|
|
|
PAGES=(
|
|
"/"
|
|
"/dashboard"
|
|
"/demo"
|
|
"/email-verified"
|
|
)
|
|
|
|
echo "=== WCAG 2.1 AA audit — $(date -u) ==="
|
|
echo "Base URL: $BASE_URL"
|
|
echo "Output: $OUT_DIR"
|
|
echo ""
|
|
|
|
# Auto-install tools if missing
|
|
if ! command -v lighthouse >/dev/null 2>&1; then
|
|
echo "Installing lighthouse globally..."
|
|
npm install -g lighthouse@latest >/dev/null 2>&1
|
|
fi
|
|
if ! command -v axe >/dev/null 2>&1; then
|
|
echo "Installing @axe-core/cli globally..."
|
|
npm install -g @axe-core/cli@latest >/dev/null 2>&1
|
|
fi
|
|
|
|
SUMMARY="$OUT_DIR/SUMMARY.md"
|
|
cat > "$SUMMARY" <<EOF
|
|
# WCAG 2.1 AA Audit — $(date -u +"%Y-%m-%d")
|
|
|
|
Base URL: \`$BASE_URL\`
|
|
Tools: Lighthouse + axe-core (industry-standard a11y testing)
|
|
|
|
## Pages audited
|
|
EOF
|
|
|
|
for page in "${PAGES[@]}"; do
|
|
SAFE_NAME=$(echo "$page" | tr '/' '_' | sed 's/^_//' | sed 's/^$/root/')
|
|
URL="${BASE_URL}${page}"
|
|
echo "--- Auditing $URL ---"
|
|
|
|
# Lighthouse (full performance + a11y + SEO)
|
|
lighthouse "$URL" \
|
|
--only-categories=accessibility,seo \
|
|
--output=html,json \
|
|
--output-path="$OUT_DIR/lighthouse-$SAFE_NAME" \
|
|
--chrome-flags="--headless --no-sandbox" \
|
|
--quiet 2>&1 || echo "Lighthouse failed for $URL"
|
|
|
|
# axe-core (WCAG-specific violations)
|
|
axe "$URL" \
|
|
--tags wcag2a,wcag2aa,wcag21a,wcag21aa \
|
|
--save "$OUT_DIR/axe-$SAFE_NAME.json" \
|
|
--exit 0 2>&1 || echo "Axe failed for $URL"
|
|
|
|
# Extract scores for summary
|
|
if [ -f "$OUT_DIR/lighthouse-$SAFE_NAME.report.json" ]; then
|
|
A11Y_SCORE=$(python3 -c "
|
|
import json
|
|
d = json.load(open('$OUT_DIR/lighthouse-$SAFE_NAME.report.json'))
|
|
print(int(d['categories']['accessibility']['score'] * 100))
|
|
" 2>/dev/null || echo "N/A")
|
|
SEO_SCORE=$(python3 -c "
|
|
import json
|
|
d = json.load(open('$OUT_DIR/lighthouse-$SAFE_NAME.report.json'))
|
|
print(int(d['categories'].get('seo', {}).get('score', 0) * 100))
|
|
" 2>/dev/null || echo "N/A")
|
|
else
|
|
A11Y_SCORE="N/A"; SEO_SCORE="N/A"
|
|
fi
|
|
|
|
AXE_VIOLATIONS=$(python3 -c "
|
|
import json
|
|
try:
|
|
d = json.load(open('$OUT_DIR/axe-$SAFE_NAME.json'))
|
|
if isinstance(d, list) and d:
|
|
d = d[0]
|
|
print(len(d.get('violations', [])))
|
|
except: print('N/A')
|
|
" 2>/dev/null || echo "N/A")
|
|
|
|
echo "" >> "$SUMMARY"
|
|
echo "### \`$page\`" >> "$SUMMARY"
|
|
echo "- Lighthouse A11y score: **$A11Y_SCORE / 100**" >> "$SUMMARY"
|
|
echo "- Lighthouse SEO score: **$SEO_SCORE / 100**" >> "$SUMMARY"
|
|
echo "- Axe-core violations (WCAG 2.1 AA): **$AXE_VIOLATIONS**" >> "$SUMMARY"
|
|
echo "- Reports: [lighthouse]($(basename "$OUT_DIR")/lighthouse-$SAFE_NAME.report.html), [axe]($(basename "$OUT_DIR")/axe-$SAFE_NAME.json)" >> "$SUMMARY"
|
|
done
|
|
|
|
echo "" >> "$SUMMARY"
|
|
echo "## WCAG 2.1 AA Compliance threshold" >> "$SUMMARY"
|
|
echo "" >> "$SUMMARY"
|
|
echo "- **Target**: Lighthouse A11y ≥ 95, axe-core violations = 0" >> "$SUMMARY"
|
|
echo "- **Caiet sarcini cere**: WCAG 2.1 AA demonstrabil (contrast 4.5:1, focus visible, keyboard nav, ARIA, screen readers)" >> "$SUMMARY"
|
|
echo "" >> "$SUMMARY"
|
|
echo "## Next steps if violations found" >> "$SUMMARY"
|
|
echo "" >> "$SUMMARY"
|
|
echo "1. Open \`axe-<page>.json\` — see \`violations[]\` array" >> "$SUMMARY"
|
|
echo "2. Each violation has \`description\`, \`helpUrl\`, \`nodes[]\` with selector" >> "$SUMMARY"
|
|
echo "3. Fix in source code" >> "$SUMMARY"
|
|
echo "4. Re-run script — verify violations = 0" >> "$SUMMARY"
|
|
|
|
echo ""
|
|
echo "=== Audit complete ==="
|
|
echo "Summary: $SUMMARY"
|
|
echo "Open lighthouse HTML reports in browser for visual review."
|