openova/.github/workflows/playwright-smoke.yaml
e3mrah b5c9839da7
feat(phase-8b): sovereign wizard auth-gate + handover JWT minting + Playwright CI fixes (#611)
Squash of PR #611 (feat/607) + PR #615 (feat/605) Phase-8b deliverables:

UI:
- AuthCallbackPage: mode-aware dispatch (catalyst-zero → magic-link server
  callback; sovereign → client-side OIDC token exchange via oidc.ts)
- Router: sovereign console routes (/console/*), DETECTED_MODE index redirect,
  authCallbackRoute dedup fix, authHandoverRoute safety net
- StepSuccess: mints RS256 handover JWT via POST /deployments/{id}/mint-handover-token
  before redirecting operator to Sovereign console (falls back to plain URL on error)

API:
- main.go: wires handoverjwt.LoadOrGenerate signer from CATALYST_HANDOVER_KEY_PATH env
- deployments.go: stamps HandoverJWTPublicKey from signer.PublicJWK() at create time
- provisioner.go: injects HandoverJWTPublicKey into Tofu vars JSON
- auth.go: /auth/handover endpoint for seamless single-identity flow

Infra:
- cloudinit-control-plane.tftpl: writes handover JWT public JWK to /var/lib/catalyst/
- variables.tf: handover_jwt_public_key variable (sensitive, default empty)

Chart:
- api-deployment.yaml / ui-deployment.yaml / values.yaml: expose handover JWT env vars

Playwright CI fixes:
- playwright-smoke.yaml / cosmetic-guards.yaml: health-check URL /sovereign/wizard → /wizard
- playwright.config.ts: BASEPATH default /sovereign → / + baseURL construction fix
- cosmetic-guards.spec.ts: provision URL /sovereign/provision/* → /provision/*
- sovereign-wizard.spec.ts: WIZARD_URL /sovereign/wizard → /wizard

Closes #605, #606, #607. Fixes Playwright CI (#142 sovereign wizard smoke tests).

Co-authored-by: e3mrah <e3mrah@openova.io>
2026-05-02 19:17:56 +04:00

116 lines
3.9 KiB
YAML

name: Playwright UI smoke (Group L — #142, #143, #144)
# Issues #142/#143/#144 — UI smoke tests for the Catalyst sovereign wizard,
# admin voucher (PromoCode) UI, and unified bp-<x> Blueprint card grid.
#
# Per CLAUDE.md Rule 8 ("Playwright MCP for interactive testing; for FILES
# landed in the repo, use plain Playwright"), this workflow uses plain
# Playwright. The tests themselves are defensive: they self-skip when the
# dev server isn't reachable, so this workflow boots the Catalyst UI in the
# background and runs against it.
#
# Per CLAUDE.md Rule 4a ("GitHub Actions is the only build path"), this
# workflow does NOT build any container images — it only runs UI smoke
# tests against a freshly-installed dev tree.
#
# Triggers:
# - push to main when UI sources or these tests change
# - pull_request when the same paths change
# - workflow_dispatch for ad-hoc runs
on:
push:
branches: [main]
paths:
- 'products/catalyst/bootstrap/ui/**'
- 'core/admin/**'
- 'core/marketplace/**'
- 'platform/**/blueprint.yaml'
- 'products/**/blueprint.yaml'
- 'tests/e2e/playwright/**'
- '.github/workflows/playwright-smoke.yaml'
pull_request:
paths:
- 'products/catalyst/bootstrap/ui/**'
- 'core/admin/**'
- 'core/marketplace/**'
- 'platform/**/blueprint.yaml'
- 'products/**/blueprint.yaml'
- 'tests/e2e/playwright/**'
- '.github/workflows/playwright-smoke.yaml'
workflow_dispatch:
jobs:
smoke:
name: Playwright UI smoke
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '22'
- name: Install Catalyst UI dependencies
working-directory: products/catalyst/bootstrap/ui
run: npm ci
- name: Install Playwright dependencies
working-directory: tests/e2e/playwright
run: |
npm install
npx playwright install --with-deps chromium
- name: Boot Catalyst UI in background
working-directory: products/catalyst/bootstrap/ui
env:
HOST: 0.0.0.0
run: |
# Vite dev server binds 4321 by default; we keep the default so the
# tests' BASE_URL fallback (http://localhost:5173) works.
nohup npm run dev > /tmp/catalyst-ui-dev.log 2>&1 &
echo $! > /tmp/catalyst-ui.pid
- name: Wait for Catalyst UI to be ready
run: |
# base: '/' since issue #596 — wizard is at /wizard, not /sovereign/wizard.
for i in $(seq 1 60); do
if curl -sf -o /dev/null http://localhost:5173/wizard; then
echo "UI ready after ${i}s"
exit 0
fi
sleep 1
done
echo "UI failed to start in 60s — log follows:"
cat /tmp/catalyst-ui-dev.log || true
exit 1
- name: Run Playwright smoke
working-directory: tests/e2e/playwright
env:
BASE_URL: http://localhost:5173
# ADMIN_BASE_URL / MARKETPLACE_BASE_URL not set — the admin and
# marketplace specs self-skip when their respective apps aren't up,
# which keeps this workflow lean. Booting all three apps requires
# additional CI infra (Postgres, Catalyst API, etc.) and is the
# subject of the full E2E pipeline, not this smoke.
run: npx playwright test --reporter=list
- name: Stop Catalyst UI
if: always()
run: |
if [ -f /tmp/catalyst-ui.pid ]; then
kill "$(cat /tmp/catalyst-ui.pid)" 2>/dev/null || true
fi
- name: Upload Playwright report
if: failure()
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: tests/e2e/playwright/playwright-report/
retention-days: 7