110 lines
4.1 KiB
Bash
Executable File
110 lines
4.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# export-visual-screenshots.sh
|
|
#
|
|
# Collects visual regression screenshots and test-results (diffs) into a
|
|
# structured folder for AI review.
|
|
#
|
|
# Usage:
|
|
# ./scripts/export-visual-screenshots.sh [output-dir]
|
|
#
|
|
# Default output: visual-review/
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
OUTPUT_DIR="${1:-$PROJECT_ROOT/visual-review}"
|
|
|
|
# Read project name from .env
|
|
PROJECT_NAME="tibi-project"
|
|
if [[ -f "$PROJECT_ROOT/.env" ]]; then
|
|
PROJECT_NAME=$(grep -E '^PROJECT_NAME=' "$PROJECT_ROOT/.env" | cut -d= -f2 || echo "tibi-project")
|
|
fi
|
|
|
|
SCREENSHOTS_DIR="$PROJECT_ROOT/tests/e2e-visual/__screenshots__"
|
|
TEST_RESULTS_DIR="$PROJECT_ROOT/test-results"
|
|
|
|
rm -rf "$OUTPUT_DIR"
|
|
mkdir -p "$OUTPUT_DIR/baselines" "$OUTPUT_DIR/diffs"
|
|
|
|
echo "📸 Exporting visual regression data to $OUTPUT_DIR"
|
|
echo ""
|
|
|
|
if [[ -d "$SCREENSHOTS_DIR" ]]; then
|
|
echo " ✓ Copying baseline screenshots..."
|
|
cp -r "$SCREENSHOTS_DIR"/* "$OUTPUT_DIR/baselines/" 2>/dev/null || true
|
|
else
|
|
echo " ⚠ No baseline screenshots found at $SCREENSHOTS_DIR"
|
|
echo " Run: yarn test:visual:update to generate baseline screenshots first."
|
|
fi
|
|
|
|
DIFF_COUNT=0
|
|
if [[ -d "$TEST_RESULTS_DIR" ]]; then
|
|
while IFS= read -r -d '' file; do
|
|
rel="${file#$TEST_RESULTS_DIR/}"
|
|
dest_dir="$OUTPUT_DIR/diffs/$(dirname "$rel")"
|
|
mkdir -p "$dest_dir"
|
|
cp "$file" "$dest_dir/"
|
|
((DIFF_COUNT++)) || true
|
|
done < <(find "$TEST_RESULTS_DIR" \( -name "*-actual.png" -o -name "*-expected.png" -o -name "*-diff.png" \) -print0 2>/dev/null)
|
|
fi
|
|
|
|
echo " ✓ Generating manifest.json..."
|
|
|
|
MANIFEST="$OUTPUT_DIR/manifest.json"
|
|
echo "{" > "$MANIFEST"
|
|
echo ' "generated": "'"$(date -u +"%Y-%m-%dT%H:%M:%SZ")"'",' >> "$MANIFEST"
|
|
echo ' "project": "'"$PROJECT_NAME"'",' >> "$MANIFEST"
|
|
echo ' "viewports": {' >> "$MANIFEST"
|
|
echo ' "visual-desktop": { "width": 1280, "height": 720, "device": "Desktop Chrome" },' >> "$MANIFEST"
|
|
echo ' "visual-iphonese": { "width": 375, "height": 667, "device": "iPhone SE" },' >> "$MANIFEST"
|
|
echo ' "visual-ipad": { "width": 768, "height": 1024, "device": "iPad Mini" }' >> "$MANIFEST"
|
|
echo ' },' >> "$MANIFEST"
|
|
|
|
echo ' "baselines": [' >> "$MANIFEST"
|
|
FIRST=true
|
|
if [[ -d "$OUTPUT_DIR/baselines" ]]; then
|
|
while IFS= read -r -d '' file; do
|
|
rel="${file#$OUTPUT_DIR/}"
|
|
project=$(echo "$rel" | cut -d'/' -f2)
|
|
if [[ "$FIRST" == "true" ]]; then
|
|
FIRST=false
|
|
else
|
|
echo "," >> "$MANIFEST"
|
|
fi
|
|
printf ' { "path": "%s", "project": "%s" }' "$rel" "$project" >> "$MANIFEST"
|
|
done < <(find "$OUTPUT_DIR/baselines" -name "*.png" -print0 2>/dev/null | sort -z)
|
|
fi
|
|
echo "" >> "$MANIFEST"
|
|
echo ' ],' >> "$MANIFEST"
|
|
|
|
echo ' "diffs": [' >> "$MANIFEST"
|
|
FIRST=true
|
|
if [[ -d "$OUTPUT_DIR/diffs" ]] && [[ $DIFF_COUNT -gt 0 ]]; then
|
|
while IFS= read -r -d '' file; do
|
|
rel="${file#$OUTPUT_DIR/}"
|
|
if [[ "$FIRST" == "true" ]]; then
|
|
FIRST=false
|
|
else
|
|
echo "," >> "$MANIFEST"
|
|
fi
|
|
printf ' { "path": "%s" }' "$rel" >> "$MANIFEST"
|
|
done < <(find "$OUTPUT_DIR/diffs" -name "*.png" -print0 2>/dev/null | sort -z)
|
|
fi
|
|
echo "" >> "$MANIFEST"
|
|
echo ' ],' >> "$MANIFEST"
|
|
|
|
echo " \"diffCount\": $DIFF_COUNT" >> "$MANIFEST"
|
|
echo "}" >> "$MANIFEST"
|
|
|
|
BASELINE_COUNT=$(find "$OUTPUT_DIR/baselines" -name "*.png" 2>/dev/null | wc -l)
|
|
echo ""
|
|
echo " 📊 Summary:"
|
|
echo " Baselines: $BASELINE_COUNT screenshots"
|
|
echo " Diffs: $DIFF_COUNT images (actual/expected/diff)"
|
|
echo " Manifest: $MANIFEST"
|
|
echo ""
|
|
echo " 💡 Review files in $OUTPUT_DIR/"
|
|
echo " Or attach screenshots to a Copilot Chat for AI review."
|