name: E2E on: pull_request: push: branches: [main] jobs: e2e: name: Playwright E2E (chromium + webkit) runs-on: ubuntu-latest timeout-minutes: 30 steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '22' cache: 'npm' cache-dependency-path: 'e2e/package.json' - name: Install e2e deps working-directory: ./e2e run: npm install - name: Install Playwright browsers working-directory: ./e2e run: npx playwright install --with-deps chromium webkit - name: Bring up the test stack working-directory: ./e2e run: docker compose -f docker-compose.test.yml up -d --build - name: Wait for stack health working-directory: ./e2e run: | for i in $(seq 1 60); do if curl -fsS http://localhost:3101/health > /dev/null; then exit 0; fi sleep 2 done echo "Stack never became healthy. Dumping logs:" docker compose -f docker-compose.test.yml logs exit 1 - name: Run E2E tests working-directory: ./e2e run: npm run test:e2e -- --project=chromium-desktop # 09-mobile is `testIgnore`d on chromium-desktop (it needs hasTouch + a phone viewport), so # running only that project left 22 tests — focus traps, touch targets, safe-area insets, # viewport reflow, upload-cancel — never executing in CI. On a phone-first event app, where # essentially every real guest is on a phone, that was the wrong half of the suite to skip. - name: Run E2E tests (mobile) working-directory: ./e2e run: npm run test:e2e -- --project=chromium-mobile # iOS Safari is the app's stated primary user (a wedding guest opening a QR link), and # WebKit is the ONLY engine here that reproduces two of its behaviours: # - it enforces X-Frame-Options on the download iframe, so a site-wide `DENY` makes the # keepsake download silently do nothing. Blink hands attachments to the download # manager first and never notices. That shipped once already. # - it abandons a