Sifa professional network frontend (Next.js, React, TailwindCSS) sifa.id/
at main 175 lines 6.5 kB view raw
1name: E2E Tests 2 3on: 4 push: 5 branches: [main] 6 pull_request: 7 paths: 8 - 'src/**' 9 - 'e2e/**' 10 - 'public/**' 11 - 'playwright.config.ts' 12 - 'package.json' 13 - 'pnpm-lock.yaml' 14 - 'next.config.*' 15 - 'tailwind.config.*' 16 - 'tsconfig.json' 17 - '.github/workflows/e2e.yml' 18 19jobs: 20 e2e: 21 runs-on: ubuntu-latest 22 timeout-minutes: 30 23 permissions: 24 contents: read 25 pull-requests: write 26 steps: 27 - uses: actions/checkout@v4 28 29 - uses: actions/setup-node@v4 30 with: 31 node-version: 25 32 33 - name: Install pnpm 34 run: corepack enable && corepack prepare pnpm@10 --activate 35 36 - name: Install dependencies 37 run: pnpm install --frozen-lockfile 38 39 - name: Install Playwright browsers 40 run: pnpm exec playwright install --with-deps chromium webkit 41 42 - name: Detect affected pages 43 id: affected 44 if: github.event_name == 'pull_request' 45 run: | 46 CHANGED=$(gh pr diff "${{ github.event.pull_request.number }}" --name-only) 47 48 # Shared files that affect ALL pages (layouts, components, styles, config, public assets) 49 if echo "$CHANGED" | grep -qE '^(src/app/layout\.tsx|src/app/\(main\)/layout\.tsx|src/components/|src/styles/|src/lib/|src/i18n/|public/|tailwind\.config|next\.config|src/app/globals\.css)'; then 50 echo "pages=all" >> "$GITHUB_OUTPUT" 51 echo "frontend_changed=true" >> "$GITHUB_OUTPUT" 52 exit 0 53 fi 54 55 # Map route-specific files to page names 56 PAGES="" 57 while IFS= read -r file; do 58 case "$file" in 59 src/app/\(main\)/page.tsx) PAGES="$PAGES,homepage" ;; 60 src/app/\(main\)/about/*) PAGES="$PAGES,about" ;; 61 src/app/\(main\)/privacy/*) PAGES="$PAGES,privacy" ;; 62 src/app/\(main\)/terms/*) PAGES="$PAGES,terms" ;; 63 src/app/\(main\)/login/*) PAGES="$PAGES,login" ;; 64 src/app/\(main\)/embed/*) PAGES="$PAGES,embed" ;; 65 src/app/\(embed\)/*) PAGES="$PAGES,embed" ;; 66 src/app/\(main\)/search/*) PAGES="$PAGES,search" ;; 67 src/app/\(main\)/experts/*) PAGES="$PAGES,experts" ;; 68 69 esac 70 done <<< "$CHANGED" 71 72 # Deduplicate and trim leading comma 73 PAGES=$(echo "$PAGES" | tr ',' '\n' | sort -u | paste -sd ',' - | sed 's/^,//') 74 75 if [ -z "$PAGES" ]; then 76 echo "pages=none" >> "$GITHUB_OUTPUT" 77 echo "frontend_changed=false" >> "$GITHUB_OUTPUT" 78 else 79 echo "pages=$PAGES" >> "$GITHUB_OUTPUT" 80 echo "frontend_changed=true" >> "$GITHUB_OUTPUT" 81 fi 82 env: 83 GH_TOKEN: ${{ github.token }} 84 85 - name: Build application 86 run: pnpm build 87 88 - name: Run E2E tests 89 run: pnpm exec playwright test --grep-invert "Visual regression" 90 env: 91 PLAYWRIGHT_BASE_URL: http://localhost:3000 92 QA_SCREENSHOTS: ${{ (github.event_name == 'push' || steps.affected.outputs.frontend_changed == 'true') && '1' || '0' }} 93 AFFECTED_PAGES: ${{ steps.affected.outputs.pages || 'all' }} 94 95 - name: Run visual regression (update baselines if missing) 96 if: ${{ github.event_name == 'push' || steps.affected.outputs.pages != 'none' }} 97 run: pnpm exec playwright test e2e/visual-regression.spec.ts --update-snapshots --reporter=line 98 env: 99 PLAYWRIGHT_BASE_URL: http://localhost:3000 100 AFFECTED_PAGES: ${{ steps.affected.outputs.pages || 'all' }} 101 102 - name: Upload test report 103 uses: actions/upload-artifact@v4 104 if: ${{ !cancelled() }} 105 with: 106 name: playwright-report 107 path: e2e/playwright-report/ 108 retention-days: 14 109 110 - name: Upload QA screenshots 111 uses: actions/upload-artifact@v4 112 if: ${{ !cancelled() }} 113 with: 114 name: qa-screenshots 115 path: e2e/qa-screenshots/ 116 retention-days: 14 117 118 - name: Publish screenshots to VPS 119 if: ${{ !cancelled() && hashFiles('e2e/qa-screenshots/**') != '' }} 120 env: 121 VPS_HOST: ${{ secrets.VPS_HOST }} 122 VPS_USER: ${{ secrets.VPS_USER }} 123 VPS_SSH_KEY: ${{ secrets.VPS_SSH_KEY }} 124 PR_NUMBER: ${{ github.event.pull_request.number }} 125 RUN_ID: ${{ github.run_id }} 126 GH_TOKEN: ${{ github.token }} 127 run: | 128 # Set up SSH 129 mkdir -p ~/.ssh 130 echo "$VPS_SSH_KEY" > ~/.ssh/deploy_key 131 chmod 600 ~/.ssh/deploy_key 132 ssh-keyscan -H "$VPS_HOST" >> ~/.ssh/known_hosts 2>/dev/null 133 134 # Upload to VPS: /var/www/screenshots/pr-<number>-run-<id>/ 135 DEST="pr-${PR_NUMBER}-run-${RUN_ID}" 136 ssh -i ~/.ssh/deploy_key "$VPS_USER@$VPS_HOST" "mkdir -p /var/www/screenshots/$DEST" 137 scp -i ~/.ssh/deploy_key -r e2e/qa-screenshots/. "$VPS_USER@$VPS_HOST:/var/www/screenshots/$DEST/" 138 139 # Build markdown comment body 140 BASE_URL="https://sifa.id/screenshots/$DEST" 141 BODY="## E2E Screenshots\n\nViewports tested: desktop-chrome, mobile-safari (iPhone 14), tablet (iPad Mini)\n\n" 142 for f in $(ssh -i ~/.ssh/deploy_key "$VPS_USER@$VPS_HOST" "find /var/www/screenshots/$DEST -name '*.png' | sort"); do 143 FILENAME=$(basename "$f") 144 LABEL="${FILENAME%.png}" 145 BODY+="### $LABEL\n![$LABEL]($BASE_URL/$FILENAME)\n\n" 146 done 147 148 # Post comment on the PR 149 if [ -n "$PR_NUMBER" ]; then 150 printf "%b" "$BODY" | gh pr comment "$PR_NUMBER" --repo "$GITHUB_REPOSITORY" --body-file - 151 fi 152 153 - name: Upload test traces 154 uses: actions/upload-artifact@v4 155 if: failure() 156 with: 157 name: playwright-traces 158 path: e2e/test-results/ 159 retention-days: 7 160 161 - name: Upload visual regression snapshots 162 uses: actions/upload-artifact@v4 163 if: ${{ !cancelled() }} 164 with: 165 name: visual-regression-snapshots 166 path: e2e/visual-regression.spec.ts-snapshots/ 167 retention-days: 14 168 169 - name: Upload visual regression diffs 170 uses: actions/upload-artifact@v4 171 if: failure() 172 with: 173 name: visual-regression-diffs 174 path: e2e/test-results/**/*-diff.png 175 retention-days: 14