Last verified
Quality · Playwright · dev.cplk.org

E2E test journeys & status.

The living map of what Playwright covers against https://dev.cplk.org — every journey, every role, every backend gap the suite has surfaced. References point at the spec files in e2e/tests/ so a click on a row tells you exactly where to read or edit the test.

Spec files 88 Total tests ~881 Journeys 22 Role projects 10 Last live run 2026-05-13 · 18/18 green on new specs

How to read this page

The Playwright suite is partitioned by role project: each project loads a Keycloak storage state (e2e/.auth/<role>.json) and matches only the specs that role is responsible for. Multi-actor flows capture a Bearer token from a second role's storage state via the captureBearerForRole helper, so a single spec can drive cross-role interactions without context-switching the whole browser.

StatusMeaning
PASSActive — tests pass against the current dev backend.
JOURNEYMulti-step test.describe flow that walks an actor across a lifecycle.
PARTIALHas a documented gap — some tests are test.skip with a tagged reason.
BLOCKEDBackend missing, deferred, or relies on infrastructure (mail, captcha) not available against shared dev.

How to run

All commands are run from e2e/ against the default base URL https://dev.cplk.org (override with CPLK_E2E_BASE_URL).

# first time / refresh role storage states
pnpm test:auth-setup

# everything
pnpm test

# only journeys (~22 files)
pnpm test:journeys

# only one role's projects
npx playwright test --project=agent
npx playwright test --project=property-owner

# only the new journeys added in this round
npx playwright test --project=agent --grep "notification-preferences|system-announcements|support-ticket-lifecycle"

# point at a different env
CPLK_E2E_BASE_URL=https://localhost:3000 npx playwright test
Where the live truth lives. The auto-generated coverage section in docs/E2E_TEST_COVERAGE.md is regenerated by e2e/scripts/coverage-report.mjs. This page is the human-friendly mirror, with the same data formatted for browsing.

Role projects

ProjectStorage stateOwns
setupwrites .auth/<role>.jsonKeycloak UI login for every role; runs first.
anonymousPublic-site specs that need no auth (~660 atomic tests).
anonymous-journeysPublic visitor journey.
agent.auth/agent.jsonProperty creation wizard, daily workflow, boost UI, favorites, the three new journeys.
agency-admin.auth/agency-admin.jsonAgency lifecycle, subscription mgmt, property creation as admin.
agency-super-admin.auth/agency-super-admin.jsonAgency-admin portal, user-invite journey.
super-admin.auth/super-admin.jsonPlatform-wide agency administration.
blog-editor.auth/blog-editor.jsonBlog draft → review → publish workflow.
financial-officer.auth/financial-officer.jsonPayment-slip verification, refund processing.
property-owner.auth/property-owner.jsonPO full UI lifecycle, PO rejection, refund, approver UI variant.

Journeys

A journey is a multi-step test.describe that walks an actor (or a small cast) through a complete lifecycle. Most journeys are self-contained: setup, action, assertion, cleanup. A few open side contexts to act as a second role within the same spec.

Property lifecycle

SpecProjectTestsStatusWhat it covers
journeys/agent-daily-workflow.journey.spec.tsagent5 (1 skip)PARTIALDashboard → list → drill-in → inquiries → favourites in one run.
journeys/property-approval-lifecycle-agent.journey.spec.tsagent3JOURNEYAgent submits, approver approves, agent sees ACTIVE.
journeys/property-approval-lifecycle-po.journey.spec.tsproperty-owner2JOURNEYPO variant of the approval lifecycle.
journeys/property-approval-multirole-ui.journey.spec.tsagent3JOURNEYMulti-role UI flow — agent creates, opens approver context, asserts back in agent.
journeys/property-approver-and-permanent-reject-ui.journey.spec.tsagent · property-owner3 (3 skip)PARTIALUI variants for approver-side controls; PA1/PA2 fixme on dev.
journeys/property-edit-after-approval.journey.spec.tsagent4JOURNEYEdits triggering re-approval, history surfacing in the audit log.
journeys/property-po-full-ui.journey.spec.tsproperty-owner3JOURNEYPO end-to-end: create → pay → publish → review → see in public.
journeys/property-rejection-po.journey.spec.tsproperty-owner1JOURNEYPO sees structured rejection + revise path.
journeys/property-rejection-scenarios.journey.spec.tsagent6JOURNEYReason captured, redirect rules, draft return.
journeys/property-refund-lifecycle.journey.spec.tsproperty-owner4JOURNEYPERMANENTLY_REJECTED → AWAITING_REFUND_DETAILS → REFUND_PENDING → REFUND_COMPLETED.

Agency, content & engagement

SpecProjectTestsStatusWhat it covers
journeys/agency-admin-lifecycle.journey.spec.tsagency-admin5JOURNEYAgency dashboard → team → settings → property list flow.
journeys/agency-user-invite-ui.journey.spec.tsagency-super-admin3JOURNEYInvite mints Keycloak user, role assignment, deactivation.
journeys/blog-editor-workflow.journey.spec.tsblog-editor6JOURNEYDraft → submit → approve / reject → published edit (BE1–BE5).
journeys/boost-purchase-ui.journey.spec.tsagent3 (6 skip)PARTIALBoostModal flow; some skips guard on stable seed boostable listing.
journeys/favorites-flow.journey.spec.tsagent7 (3 skip)PARTIALAuth-gated favourite from anonymous → favourite from agent → list view.
journeys/inquiry-handling-multirole-ui.journey.spec.tsagent7 (4 skip)PARTIALInquiry submit → assign → respond → close, across roles.
journeys/public-visitor.journey.spec.tsanonymous-journeys6 (1 skip)PARTIALPublic search, filter, slug detail, inquiry submit.

New journeys added in this round

Three additional journeys close real coverage gaps on dev. All three exercise public REST contracts that previously had unit-test coverage only.

SpecProjectTestsStatusWhat it covers
journeys/notification-preferences.journey.spec.ts agent 3 (NP1–NP3) PASS GET defaults · single-type PUT round-trip · bulk PUT round-trip. Hits GET /api/notifications/preferences & PUT /api/notifications/preferences; restores defaults so the test is idempotent.
journeys/system-announcements.journey.spec.ts agent (+ super-admin token) 3 (SA1–SA3) PASS SUPER_ADMIN publishes ALL-targeted announcement → agent sees unread → agent PATCHes {id}/read → agent sees read. SA3 asserts role-isolation (AGENT cannot see FINANCIAL_OFFICER-targeted announcement).
journeys/support-ticket-lifecycle.journey.spec.ts agent (+ super-admin token) 4 (ST1–ST4) PASS Agent creates ticket → external reply → SUPER_ADMIN internal note isolation → NEW → IN_PROGRESS → RESOLVED → reporter REOPENED → CLOSED transitions.
Run verification (2026-05-13). CPLK_E2E_BASE_URL=https://dev.cplk.org npx playwright test --project=agent --grep "notification-preferences|system-announcements|support-ticket-lifecycle"18 passed (auth setup 8 + journey tests 10) in 14.3 s.

Atomic spec areas

Outside the journeys, ~660 atomic specs cover the rest of the surface. The full inventory is in docs/E2E_TEST_COVERAGE.md; below is the summary by area.

AreaSpecsTestsNotes
Auth498Login, register, password reset, email verification.
Properties13~130Wizard catalog by role, image upload, edit, detail, public detail, status transitions.
Inquiries345Public form, list, detail.
Favorites230Button + page.
Dashboard / Analytics368Dashboard widgets, property analytics, agency analytics.
Notifications336Bell, page, badge increments.
Portal (admin)764Agency admin / super-admin views, subscriptions, boost, financial officer.
Public site6116Homepage, agencies, properties, search, link audit.
SEO219Sitemap, robots, OG tags, structured data, canonicals.
Onboarding641Company agency, individual agent, PO, skip, redirect.
Security / RBAC693API auth errors, validation errors, RBAC denial, cross-agency, blog/article RBAC.
Errors425API 5xx fallback, network, permission, validation.
Accessibility3~18 (16 skip)A11y, form validation, modal focus.
Mobile / responsive212Mobile + tablet viewport runs.
Smoke / core / network59Console-error scan, network audit, smoke.

Known gaps & backend issues

The Playwright suite is also a forcing function for backend issues. Every gap below has a corresponding active or test.skip test, so the suite flips green automatically when the backend ships the fix.

Deferred — infrastructure / shared-env constraints

  • Email-channel notification delivery (requires SMTP / mailbox interception not wired against dev).
  • R2 upload failure retry behaviour (requires S3 5xx mocking).
  • Slow-network / offline behaviour (requires fault-injection harness).
  • Cross-browser (Firefox / WebKit / Edge) — deliberately Chrome-only since the journey redesign.
  • Two users editing the same property / shared ad-slot races (not deterministic on shared dev).

Backend gaps surfaced by the suite

SeverityIssueDiscovered by
CRITICALCross-agency property approve bypass — an agency-admin can approve a property in another agency.security/rbac-denial.spec.ts (S6)
CRITICALCross-agency DELETE — DELETE of another agency's resource succeeds where it should 403.security/api-auth-errors.spec.ts
HIGH500 instead of 400 on POST /api/properties bean validation.security/api-validation-errors.spec.ts (V2–V6)
HIGH500 instead of 400 on PATCH /api/inquiries/{id}/status invalid enum.security/api-validation-errors.spec.ts (V7)
HIGH500 instead of 400 on POST /api/boosts invalid enum.security/api-validation-errors.spec.ts (V12)
HIGHSOLD / LEASED property transition endpoints missing.properties/property-status-transitions.spec.ts (T3–T6 skip)
MEDIUMPOST /properties/{id}/reject does not require a rejection reason.security/api-validation-errors.spec.ts (V13)
MEDIUMValidation runs before role check on POST /api/agencies — leaks field names to non-admins.security/rbac-denial.spec.ts
MEDIUMAuto-renew toggle endpoint missing.portal/subscription.spec.ts (SUB6)
MEDIUMSubscription payment-slip upload flow has no backend.portal/subscription.spec.ts (SUB7)
LOWSitemap can lag behind property publish events.seo/sitemap-and-meta.spec.ts
LOWNo hard DELETE for agencies (suspension only).portal/agencies-admin.spec.ts (AG4)

Conventions in this suite

  • One file per journey. Each journey lives in e2e/tests/journeys/*.journey.spec.ts and is named after the lifecycle it covers.
  • Independent tests. Where possible, journey tests are not serial — each creates its own resource and cleans up in afterEach so a single flake doesn't cascade.
  • Cross-role via Bearer tokens. Multi-actor journeys use captureBearerForRole to pull a JWT from another role's storageState rather than spinning up a second browser session.
  • Unique title prefixes. Test artefacts use [E2E-XX] prefixes (e.g. [E2E-BE] for blog editor, [E2E-ST] for support tickets) so manual cleanup is straightforward if a spec crashes.
  • The coverage-report.mjs script walks tests/**.spec.ts and rewrites the auto-generated section of docs/E2E_TEST_COVERAGE.md between markers. This HTML page is the human-friendly mirror — keep both in sync.

References

  • Playwright confige2e/playwright.config.ts
  • Auth setupe2e/setup/auth.setup.ts
  • Credentials fixturee2e/tests/fixtures/credentials.ts
  • Live coverage runbookdocs/E2E_TEST_COVERAGE.md
  • Backend state machinesbackend/src/main/java/com/cplk/api/config/PropertyStateMachineConfig.java