All checks were successful
CD / Build and push images (push) Successful in 2m36s
CI / Lint, typecheck, test (push) Successful in 1m50s
CI / Auth e2e pack (push) Successful in 1m58s
CI / Build container images (push) Has been skipped
CD / Deploy to Test (push) Successful in 9s
CD / Smoke tests against Test (push) Successful in 1m13s
CD / Promote to Int (push) Successful in 11s
Bootstrap apps/collab as a Hocuspocus WebSocket server (ADR 0003): - pino JSON logging (service=collab) and shared Zod env validation (collabEnvSchema); structured connection open/close logs. - /healthz endpoint (process liveness + PostgreSQL ping) served via the onRequest hook, matching the container-internal path and the proxied /collab/healthz path; any WebSocket handshake is accepted for now (authentication arrives with #34, persistence with #35). - Dockerfile (ESM workspace build) and a compose service on the frontend and internal networks with a healthcheck; dev overlay service and a new COLLAB_PORT variable. - CD builds, pushes, and promotes the collab image; CI builds it on PRs; the smoke suite asserts /collab/healthz through the reverse proxy. - deployment.md/stages.md: proxy routing, per-stage COLLAB_PORT, checklist. Closes #33 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
36 lines
1.4 KiB
TypeScript
36 lines
1.4 KiB
TypeScript
import { expect, test } from '@playwright/test';
|
|
|
|
// Walking-skeleton smoke suite: proves the deployed stage serves the SPA,
|
|
// the reverse proxy routes /api, and the api is ready (db + migrations).
|
|
// Feature e2e packs (issues #20, #32, …) build on this file's patterns.
|
|
|
|
test('SPA shell loads', async ({ page }) => {
|
|
await page.goto('/');
|
|
await expect(page).toHaveTitle(/Dorfteich/);
|
|
await expect(page.getByRole('heading', { level: 1 })).toBeVisible();
|
|
});
|
|
|
|
test('web liveness endpoint responds', async ({ request }) => {
|
|
const res = await request.get('/healthz');
|
|
expect(res.ok()).toBeTruthy();
|
|
});
|
|
|
|
test('api is live and ready', async ({ request }) => {
|
|
const healthz = await request.get('/api/v1/healthz');
|
|
expect(healthz.ok()).toBeTruthy();
|
|
expect((await healthz.json()).status).toBe('ok');
|
|
|
|
const readyz = await request.get('/api/v1/readyz');
|
|
expect(readyz.ok(), `readyz: ${await readyz.text()}`).toBeTruthy();
|
|
});
|
|
|
|
test('collab service is live and reachable through the proxy', async ({ request }) => {
|
|
// The reverse proxy routes /collab to the Hocuspocus container (issue #33);
|
|
// its /healthz also pings the database, so 200 proves the whole path works.
|
|
const res = await request.get('/collab/healthz');
|
|
expect(res.ok(), `collab healthz: ${await res.text()}`).toBeTruthy();
|
|
const body = await res.json();
|
|
expect(body.status).toBe('ok');
|
|
expect(body.service).toBe('collab');
|
|
});
|