End-to-End Testing
Citadel uses Playwright for comprehensive end-to-end (E2E) testing across the entire platform.
Note: Each individual application and package (e.g.,
iam,go-commons) runs its own suite of unit and integration tests. This document specifically covers the developer E2E script used to spin up the entire suite of services and run browser-based flows.
These tests verify the integration between the Shell App, Identity Provider (Keycloak), and various backend services.
Location & Structure
All E2E tests are located in scripts/tests:
scripts/tests/smoke.spec.ts: Infrastructure health checks (probes every service).scripts/tests/ui/: UI-driven flows (Playwright specs).shell-login.spec.ts: Authentication and shell navigation.onboarding-direct.spec.ts: Simple user signup.high-touch-onboarding.spec.ts: Complex onboarding with KYC and payments.onboarding-workflow.spec.ts: Async workflow polling.invitation-flow.spec.ts: Tenant invitation and acceptance.
Prerequisites
Before running the tests, ensure the Citadel platform is running:
# In the root directory
# Ensure you are in the Dev Container or have the environment set up
pnpm install
pnpm run setup:keycloak
pnpm exec playwright install --with-deps
Running Tests
All interdependent starting, database resetting, and configuration of all apps for E2E testing is handled automatically by the single entry point script.
1. Run the Entire Suite
To run the full suite (Smoke Tests + UI Tests) headlessly:
# Must be executed within the devcontainer
./scripts/e2e.sh
2. Run with Playwright UI
To debug tests, inspect the DOM, or watch them execute step-by-step, run in UI mode:
./scripts/e2e.sh --ui
3. Direct Playwright Commands (Advanced)
If you already have the services running (e.g., you used ./scripts/start-all.sh to spin up the local development environment without clearing databases), you can target specific tests without the setup/teardown overhead:
# Simple Smoke Test
npx playwright test scripts/tests/smoke.spec.ts
# Run a Specific UI Test
npx playwright test scripts/tests/ui/shell-login.spec.ts
Key Test Patterns
Handling Authentication
Most tests require an authenticated state. We use a shared helper performLogin (found in shell-login.spec.ts) that interacts with the Keycloak login page using default development credentials.
Testing Async Workflows
For services like the Workflow Service, we test "polling steps" where the UI waits for a backend process (via Temporal) to complete before transitioning to the next state.
Example from onboarding-workflow.spec.ts:
await expect(page.getByText('We are setting up your account...')).toBeVisible();
await expect(page.getByRole('heading', { name: 'Completed' })).toBeVisible({ timeout: 10000 });
Mailpit Integration
For flows involving Email OTP (like High-Touch Onboarding), we use the Mailpit API to programmatically fetch the OTP code from the virtual mailbox.
const otp = await fetchOtpFromMailpit(request, email);
await page.getByLabel('Verification Code').fill(otp);
Environment Variables
The tests rely on certain environment variables, typically pre-configured in the Dev Container:
| Variable | Description |
|---|---|
E2E_DEFAULT_TENANT_ID | The ID of the default tenant used for registration flows. |
MAILPIT_API_URL | URL for the Mailpit API (default: http://mailpit:8025). |
PLAYWRIGHT_BASE_URL | The URL of the Shell App (default: http://localhost:5000). |