# P5-06 — End-to-end test suite. # # Spec : docs/superpowers/specs/2026-05-07-p5-oss-readiness-design.md # Stack: e2e/compose.e2e.yml (server + agent + rest-server + playwright) # Tests: e2e/playwright/tests/*.spec.ts # # Triggered on every PR into main and on workflow_dispatch. Runs # longer than the unit-test workflow (~3-4 minutes for a clean run); # kept separate so a slow e2e doesn't block the fast lint/test loop. # # Networking note: every interaction with the server (health probe, # Playwright) happens from a container on the compose `rmnet` # network, addressing the server as `http://server:8080`. We can't # rely on `127.0.0.1:8080` because Gitea's runner executes steps # inside its own container, where compose's host port-publish is # not visible. name: e2e on: pull_request: branches: [main] workflow_dispatch: jobs: e2e: name: Playwright vs docker-compose runs-on: ubuntu-latest timeout-minutes: 15 steps: - uses: actions/checkout@v4 - name: Build the e2e stack run: docker compose -f e2e/compose.e2e.yml build - name: Bring up the stack run: docker compose -f e2e/compose.e2e.yml up -d server rest-server source-fixture - name: Wait for server health run: | set -eu for i in $(seq 1 30); do if docker run --rm --network e2e_rmnet curlimages/curl:8.10.1 \ -fsS http://server:8080/api/version >/dev/null 2>&1; then echo "server up"; exit 0 fi sleep 2 done echo "server didn't come up"; docker compose -f e2e/compose.e2e.yml logs server; exit 1 - name: Capture bootstrap token from server logs id: bootstrap run: | set -eu for i in $(seq 1 15); do line=$(docker compose -f e2e/compose.e2e.yml logs server 2>&1 | grep -E 'bootstrap token' -A2 | grep -Eo '[a-zA-Z0-9_-]{40,}' | head -1 || true) if [ -n "$line" ]; then echo "RM_BOOTSTRAP_TOKEN=$line" >> "$GITHUB_ENV" echo "got bootstrap token (${#line} chars)" exit 0 fi sleep 1 done echo "bootstrap token not found in logs" docker compose -f e2e/compose.e2e.yml logs server exit 1 - name: Start the agent run: docker compose -f e2e/compose.e2e.yml up -d agent - name: Prepare report mounts run: | mkdir -p e2e/playwright/playwright-report e2e/playwright/test-results chmod -R a+rwX e2e/playwright/playwright-report e2e/playwright/test-results - name: Run Playwright tests env: RM_BOOTSTRAP_TOKEN: ${{ env.RM_BOOTSTRAP_TOKEN }} run: docker compose -f e2e/compose.e2e.yml run --rm playwright - name: Compose logs (on failure) if: failure() run: | docker compose -f e2e/compose.e2e.yml logs --tail=200 server docker compose -f e2e/compose.e2e.yml logs --tail=200 agent docker compose -f e2e/compose.e2e.yml logs --tail=200 rest-server - name: Upload Playwright report (on failure) if: failure() uses: actions/upload-artifact@v3 with: name: playwright-report path: e2e/playwright/playwright-report retention-days: 7 - name: Tear down if: always() run: docker compose -f e2e/compose.e2e.yml down -v