feat(frontend): Phase 20-P1 UX polish — modal focus trap + OAuth hier… #28
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: E2E | |
| # Playwright end-to-end tests. Boots the full docker-compose stack | |
| # (backend + frontend + runner image), then drives the app via headless | |
| # Chromium. OpenAI is mocked at the network layer — no real API hits from CI. | |
| # | |
| # Kept as a separate workflow (not a job in ci.yml) because this one needs | |
| # Docker + the full runner image build, which is materially slower than the | |
| # lint/typecheck/unit jobs. Keeping them apart means a broken e2e run does | |
| # not block the fast-feedback signal on unit tests. | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| concurrency: | |
| group: e2e-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| e2e: | |
| name: Playwright (chromium) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| # Phase 18d: cloud-only Supabase model. These feed both docker compose | |
| # (which reads process env for ${VAR} interpolation in docker-compose.yml) | |
| # and the Playwright specs (fixtures + auth.spec.ts read process.env). | |
| # Values come from the codetutor-dev project — see docs/DEVELOPMENT.md. | |
| env: | |
| SUPABASE_URL: ${{ secrets.SUPABASE_URL }} | |
| SUPABASE_ANON_KEY: ${{ secrets.SUPABASE_ANON_KEY }} | |
| SUPABASE_SERVICE_ROLE_KEY: ${{ secrets.SUPABASE_SERVICE_ROLE_KEY }} | |
| VITE_SUPABASE_URL: ${{ secrets.VITE_SUPABASE_URL }} | |
| VITE_SUPABASE_ANON_KEY: ${{ secrets.VITE_SUPABASE_ANON_KEY }} | |
| DATABASE_URL: ${{ secrets.DATABASE_URL }} | |
| BYOK_ENCRYPTION_KEY: ${{ secrets.BYOK_ENCRYPTION_KEY }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: npm | |
| cache-dependency-path: e2e/package-lock.json | |
| - name: Boot docker-compose stack | |
| run: docker compose up -d backend frontend | |
| - name: Install e2e deps | |
| working-directory: e2e | |
| run: npm ci | |
| - name: Cache Playwright browsers | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.cache/ms-playwright | |
| key: ${{ runner.os }}-playwright-${{ hashFiles('e2e/package-lock.json') }} | |
| restore-keys: | | |
| ${{ runner.os }}-playwright- | |
| - name: Install Playwright browsers | |
| working-directory: e2e | |
| run: npx playwright install --with-deps chromium | |
| - name: Run Playwright tests | |
| working-directory: e2e | |
| run: npx playwright test | |
| - name: Dump docker-compose logs on failure | |
| if: failure() | |
| run: docker compose logs --no-color --tail=300 | |
| - name: Upload Playwright report | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: playwright-report | |
| path: e2e/playwright-report | |
| retention-days: 14 | |
| if-no-files-found: ignore | |
| - name: Upload Playwright traces/videos | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: playwright-traces | |
| path: e2e/test-results | |
| retention-days: 14 | |
| if-no-files-found: ignore | |
| - name: Tear down docker-compose | |
| if: always() | |
| run: docker compose down -v |