name: E2E Tests on: push: branches: [main] pull_request: branches: [main] jobs: e2e: timeout-minutes: 30 runs-on: ubuntu-latest env: API_URL: http://127.0.0.1:8000 VITE_API_URL: http://127.0.0.1:8000 BASE_URL: http://127.0.0.1:5173 DATABASE_URL: sqlite:///./e2e.sqlite3 SECRET_KEY: e2e-secret-key-for-github-actions-only AUTH_COOKIE_SECURE: "false" AUTH_COOKIE_SAMESITE: lax CORS_ORIGINS: http://127.0.0.1:5173 FRONTEND_URL: http://127.0.0.1:5173 steps: - uses: actions/checkout@v6 - uses: actions/setup-python@v6 with: python-version: '3.11' cache: 'pip' cache-dependency-path: backend/requirements.txt - name: Install backend dependencies working-directory: ./backend run: python -m pip install -r requirements.txt - name: Seed E2E users working-directory: ./backend run: python -m app.scripts.seed_e2e - name: Start backend working-directory: ./backend run: | python -m uvicorn app.main:app --host 127.0.0.1 --port 8000 > /tmp/gateprep-api.log 2>&1 & echo $! > /tmp/gateprep-api.pid - name: Wait for backend run: curl --fail --retry 30 --retry-all-errors --retry-delay 2 http://127.0.0.1:8000/health - uses: actions/setup-node@v6 with: node-version: 24 cache: 'npm' cache-dependency-path: frontend/package-lock.json - name: Install dependencies working-directory: ./frontend run: npm ci - name: Install Playwright browsers working-directory: ./frontend run: npx playwright install --with-deps chromium - name: Run E2E tests working-directory: ./frontend run: npx playwright test - name: Show backend logs if: ${{ failure() }} run: | if [ -f /tmp/gateprep-api.log ]; then tail -200 /tmp/gateprep-api.log else echo "Backend log not found; backend may not have started." fi - name: Upload test report uses: actions/upload-artifact@v7 if: ${{ !cancelled() }} with: name: playwright-report path: frontend/playwright-report/ if-no-files-found: ignore retention-days: 14 - name: Upload test results uses: actions/upload-artifact@v7 if: ${{ !cancelled() }} with: name: test-results path: frontend/test-results/ if-no-files-found: ignore retention-days: 7 backend-test: timeout-minutes: 10 runs-on: ubuntu-latest env: DATABASE_URL: sqlite:///./test.sqlite3 SECRET_KEY: ci-backend-test-secret-key-that-is-long-enough-for-validation AUTH_COOKIE_SECURE: "false" CORS_ORIGINS: "http://127.0.0.1:5173" steps: - uses: actions/checkout@v6 - uses: actions/setup-python@v6 with: python-version: '3.11' cache: 'pip' cache-dependency-path: backend/requirements.txt - name: Install backend dependencies working-directory: ./backend run: python -m pip install -r requirements.txt - name: Run backend tests working-directory: ./backend run: python -m pytest -q tests frontend-audit: timeout-minutes: 10 runs-on: ubuntu-latest continue-on-error: true steps: - uses: actions/checkout@v6 - uses: actions/setup-node@v6 with: node-version: 24 cache: 'npm' cache-dependency-path: frontend/package-lock.json - name: Install dependencies working-directory: ./frontend run: npm ci - name: Run contrast audit working-directory: ./frontend run: npm run audit:contrast