name: Visual Regression Tests on: push: branches: [main, develop] pull_request: branches: [main, develop] schedule: # Run tests daily at 2 AM UTC - cron: '0 2 * * *' workflow_dispatch: inputs: component: description: 'Component to test (optional)' required: false type: string update_snapshots: description: 'Update snapshots' required: false type: boolean default: false permissions: contents: read pull-requests: write jobs: visual-tests: timeout-minutes: 60 runs-on: ubuntu-latest strategy: fail-fast: false matrix: # Test on multiple browsers browser: [chromium, firefox, webkit] # Test on multiple viewports viewport: [desktop, tablet, mobile] steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 # Full history for better diff analysis - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' cache-dependency-path: packages/visual-testing/package-lock.json - name: Install dependencies working-directory: packages/visual-testing run: npm ci - name: Install Playwright browsers working-directory: packages/visual-testing run: npx playwright install --with-deps ${{ matrix.browser }} - name: Install Rust toolchain uses: actions-rs/toolchain@v1 with: profile: minimal toolchain: stable override: true - name: Build Storybook working-directory: packages/leptos run: | npm install npm run build-storybook - name: Start Storybook working-directory: packages/leptos run: | npx http-server storybook-static -p 6006 & sleep 10 - name: Run visual tests id: visual-tests working-directory: packages/visual-testing env: CI: true BROWSER: ${{ matrix.browser }} VIEWPORT: ${{ matrix.viewport }} run: | if [ "${{ github.event.inputs.update_snapshots }}" = "true" ]; then ./scripts/run-visual-tests.sh --update else ./scripts/run-visual-tests.sh fi - name: Upload test results if: always() uses: actions/upload-artifact@v4 with: name: visual-test-results-${{ matrix.browser }}-${{ matrix.viewport }} path: packages/visual-testing/test-results/ retention-days: 30 - name: Upload screenshots if: always() uses: actions/upload-artifact@v4 with: name: visual-screenshots-${{ matrix.browser }}-${{ matrix.viewport }} path: packages/visual-testing/screenshots/ retention-days: 30 - name: Upload Playwright report if: always() uses: actions/upload-artifact@v4 with: name: playwright-report-${{ matrix.browser }}-${{ matrix.viewport }} path: packages/visual-testing/playwright-report/ retention-days: 30 - name: Comment PR with results if: github.event_name == 'pull_request' && matrix.browser == 'chromium' && matrix.viewport == 'desktop' uses: actions/github-script@v7 with: script: | const fs = require('fs'); const resultsPath = 'packages/visual-testing/test-results/results.json'; if (fs.existsSync(resultsPath)) { const results = JSON.parse(fs.readFileSync(resultsPath, 'utf8')); const passed = results.stats?.expected || 0; const failed = results.stats?.unexpected || 0; const total = passed + failed; const body = `## 🎨 Visual Regression Test Results **Browser:** ${{ matrix.browser }} **Viewport:** ${{ matrix.viewport }} | Status | Count | |--------|-------| | ✅ Passed | ${passed} | | ❌ Failed | ${failed} | | 📊 Total | ${total} | ${failed > 0 ? '⚠️ Some visual tests failed. Check the artifacts for details.' : '✅ All visual tests passed!'} [View full report](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) `; github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: body }); } - name: Fail if tests failed if: steps.visual-tests.outputs.exit_code != 0 run: exit 1 # Job to update snapshots if needed update-snapshots: if: github.event.inputs.update_snapshots == 'true' needs: visual-tests runs-on: ubuntu-latest permissions: contents: write steps: - name: Checkout code uses: actions/checkout@v4 - name: Download screenshots uses: actions/download-artifact@v4 with: pattern: visual-screenshots-* path: packages/visual-testing/screenshots/ merge-multiple: true - name: Commit updated snapshots run: | git config --local user.email "github-actions[bot]@users.noreply.github.com" git config --local user.name "github-actions[bot]" git add packages/visual-testing/screenshots/baseline/ git diff --staged --quiet || git commit -m "chore: update visual test snapshots [skip ci]" git push # Summary job summary: if: always() needs: visual-tests runs-on: ubuntu-latest steps: - name: Download all results uses: actions/download-artifact@v4 with: path: all-results/ - name: Generate summary run: | echo "# 🎨 Visual Regression Test Summary" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "## Test Results" >> $GITHUB_STEP_SUMMARY echo "- ✅ Total test suites: ${{ needs.visual-tests.result }}" >> $GITHUB_STEP_SUMMARY echo "- 📊 Browsers tested: chromium, firefox, webkit" >> $GITHUB_STEP_SUMMARY echo "- 📱 Viewports tested: desktop, tablet, mobile" >> $GITHUB_STEP_SUMMARY