test(e2e): approve via the behandel-portal werkbak instead of the admin endpoint (refs #13)
The walking-skeleton happy path now drives the real S-12 flow: after submit, a behandelaar logs in to the behandel portal (medewerker realm), finds the registration in the werkbak by its reference, and clicks Goedkeuren — replacing the temporary domain admin endpoint. Treat the behandel origin as secure too, for its PKCE login. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,9 @@ import { defineConfig, devices } from '@playwright/test';
|
|||||||
// The e2e runs inside the compose network (infra/run-e2e-check.sh); baseURL defaults to the
|
// 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.
|
// self-service service. Keep timeouts generous — the first navigation triggers the DigiD flow.
|
||||||
const baseURL = process.env.SELF_SERVICE_URL ?? 'http://self-service';
|
const baseURL = process.env.SELF_SERVICE_URL ?? 'http://self-service';
|
||||||
|
// The behandel portal is a second origin the happy path visits (staff approve from the werkbak);
|
||||||
|
// it needs the same insecure-origin-as-secure treatment as self-service for the PKCE login (below).
|
||||||
|
const behandelURL = process.env.BEHANDEL_URL ?? 'http://behandel';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
testDir: '.',
|
testDir: '.',
|
||||||
@@ -22,7 +25,9 @@ export default defineConfig({
|
|||||||
// the production HTTPS context. This flag is only honoured by the full Chromium build (new
|
// 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'`.
|
// headless), not Playwright's default headless-shell, so pin `channel: 'chromium'`.
|
||||||
channel: 'chromium',
|
channel: 'chromium',
|
||||||
launchOptions: { args: [`--unsafely-treat-insecure-origin-as-secure=${baseURL}`] },
|
launchOptions: {
|
||||||
|
args: [`--unsafely-treat-insecure-origin-as-secure=${baseURL},${behandelURL}`],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }],
|
projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }],
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import { expect, test } from '@playwright/test';
|
import { expect, test } from '@playwright/test';
|
||||||
|
|
||||||
// Walking-skeleton happy path (S-08d + S-09 + S-09b): a zorgprofessional logs in via mock DigiD and
|
// Walking-skeleton happy path (S-08d + S-09 + S-09b + S-12): a zorgprofessional logs in via mock
|
||||||
// submits through the self-service portal → BFF → domain; the entry appears in the openbaar register
|
// DigiD and submits through the self-service portal → BFF → domain; the entry appears in the openbaar
|
||||||
// as INGEDIEND; a behandelaar approves it via the temporary admin endpoint; the approval flows via the
|
// register as INGEDIEND; a behandelaar then logs in to the behandel portal, finds the registration in
|
||||||
// ACL → NRC → event-subscriber → projection, and the openbaar register then shows it as INGESCHREVEN.
|
// the werkbak, and approves it (goedkeuren); the decision completes the Flowable Beoordelen task and
|
||||||
test('DigiD login → submit → public INGEDIEND → approve → public INGESCHREVEN', async ({ page, request }) => {
|
// flows via the ACL → NRC → event-subscriber → projection, and the openbaar register shows INGESCHREVEN.
|
||||||
|
test('DigiD submit → public INGEDIEND → behandelaar goedkeurt → public INGESCHREVEN', async ({ page }) => {
|
||||||
// Visiting the guarded page redirects to the Keycloak (mock DigiD) login.
|
// Visiting the guarded page redirects to the Keycloak (mock DigiD) login.
|
||||||
await page.goto('/');
|
await page.goto('/');
|
||||||
|
|
||||||
@@ -43,21 +44,33 @@ test('DigiD login → submit → public INGEDIEND → approve → public INGESCH
|
|||||||
await expect(page.getByRole('row', { name: reference }).getByRole('cell', { name: 'INGEDIEND' }))
|
await expect(page.getByRole('row', { name: reference }).getByRole('cell', { name: 'INGEDIEND' }))
|
||||||
.toBeVisible();
|
.toBeVisible();
|
||||||
|
|
||||||
// Approve via the temporary admin endpoint (reached directly on the compose network, as a
|
// A behandelaar picks the registration up in the behandel-portal werkbak and approves it
|
||||||
// behandelaar would until the behandel-portal exists — S-12). The zaak is opened off the request
|
// (goedkeuren) — the S-12 flow that replaces the temporary admin endpoint. Navigating here switches
|
||||||
// path by the worker, so wait for it before approving.
|
// to the medewerker realm (a different Keycloak realm than the citizen's digid session).
|
||||||
|
await page.goto('http://behandel/');
|
||||||
|
await page.locator('#username').fill('merel-behandelaar');
|
||||||
|
await page.locator('#password').fill('test123');
|
||||||
|
await page.locator('#kc-login').click();
|
||||||
|
|
||||||
|
await expect(page.getByRole('heading', { name: /Werkbak/i })).toBeVisible();
|
||||||
|
|
||||||
|
// The registration parks at the Beoordelen user task only after the worker has opened its zaak, so
|
||||||
|
// it appears in the werkbak asynchronously — reload until this reference's row shows up. Target the
|
||||||
|
// decide button by reference (not a generic "Goedkeuren"): the shared verify stack holds other open
|
||||||
|
// tasks, so a positional match could act on someone else's registration.
|
||||||
|
const goedkeuren = page.getByRole('button', { name: `Goedkeuren ${reference}` });
|
||||||
await expect
|
await expect
|
||||||
.poll(async () => {
|
.poll(async () => {
|
||||||
const res = await request.get(`http://domain:8080/registrations/${reference}`);
|
await page.reload();
|
||||||
return res.ok() ? (await res.json()).zaakUrl : null;
|
return goedkeuren.count();
|
||||||
}, { timeout: 30_000, intervals: [1_000, 2_000, 3_000, 5_000] })
|
}, { timeout: 30_000, intervals: [1_000, 2_000, 3_000, 5_000] })
|
||||||
.toBeTruthy();
|
.toBeGreaterThan(0);
|
||||||
|
|
||||||
const approve = await request.post(`http://domain:8080/registrations/${reference}/approve`);
|
await goedkeuren.click();
|
||||||
expect(approve.status()).toBe(204);
|
|
||||||
|
|
||||||
// The approval flows back to the projection; the openbaar register now shows *our* row (matched by
|
// The approval flows back to the projection; back on the openbaar register *our* row (matched by
|
||||||
// its reference) as INGESCHREVEN.
|
// its reference) now shows INGESCHREVEN.
|
||||||
|
await page.goto('http://openbaar/');
|
||||||
await expect
|
await expect
|
||||||
.poll(async () => {
|
.poll(async () => {
|
||||||
await page.reload();
|
await page.reload();
|
||||||
|
|||||||
Reference in New Issue
Block a user