diff --git a/docs/frontend-decisions.md b/docs/frontend-decisions.md index 8a54823..9c31125 100644 --- a/docs/frontend-decisions.md +++ b/docs/frontend-decisions.md @@ -91,5 +91,13 @@ with the submit form (S-08c, #67); any deviation from NL DS will be recorded her runtime, so there's no Playwright-image-version pinning to keep in sync. The spec is copied in (`docker cp`), not mounted, so it leaves nothing root-owned on the host. Wired as `verify-e2e` in the `verify-stack` CI job. +- **e2e treats the portal origin as secure.** In-network the portal is served over plain HTTP on a + non-localhost origin (`http://self-service`), which is **not a secure context**, so Web Crypto + (`crypto.subtle`) is unavailable. angular-auth-oidc-client needs it for the PKCE code challenge, so + `authorize()` throws and the login redirect never fires. Production runs behind HTTPS where this is + a non-issue; rather than terminate TLS in the throwaway stack, the Playwright config passes + `--unsafely-treat-insecure-origin-as-secure` (honoured only by the full `channel: 'chromium'` + build, not the default headless-shell). This emulates the production HTTPS secure context without + touching the app or its production config. - `tests/e2e` is a standalone Playwright project (its own `package.json`), not an Nx project — it's a live-stack check like the other `verify-*` runners, not part of the `frontend` unit lane. diff --git a/tests/e2e/playwright.config.ts b/tests/e2e/playwright.config.ts index 45a448f..6f6a37d 100644 --- a/tests/e2e/playwright.config.ts +++ b/tests/e2e/playwright.config.ts @@ -2,6 +2,8 @@ import { defineConfig, devices } from '@playwright/test'; // The e2e runs inside the compose network (infra/run-e2e-check.sh); baseURL defaults to the // self-service service. Keep timeouts generous — the first navigation triggers the DigiD flow. +const baseURL = process.env.SELF_SERVICE_URL ?? 'http://self-service'; + export default defineConfig({ testDir: '.', timeout: 90_000, @@ -9,8 +11,18 @@ export default defineConfig({ retries: 1, reporter: [['list']], use: { - baseURL: process.env.SELF_SERVICE_URL ?? 'http://self-service', + baseURL, trace: 'on-first-retry', + // The portal is served over plain HTTP on a non-localhost origin (http://self-service) inside the + // compose network, so it is NOT a secure context — and Web Crypto (`crypto.subtle`) is undefined + // there. angular-auth-oidc-client needs SubtleCrypto to build the PKCE code challenge, so + // `authorize()` throws and the login redirect never fires (the login form never appears). In + // production the portal runs behind HTTPS, where this works. Rather than terminate TLS in the + // throwaway e2e stack, tell Chromium to treat this origin as secure — which faithfully emulates + // the production HTTPS context. This flag is only honoured by the full Chromium build (new + // headless), not Playwright's default headless-shell, so pin `channel: 'chromium'`. + channel: 'chromium', + launchOptions: { args: [`--unsafely-treat-insecure-origin-as-secure=${baseURL}`] }, }, projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }], });