Files
F-r-ldraledigplannerare/frontend/e2e/tests/age4.spec.ts
T
jacobh2 bcc93e5c03 Test the two gestures the rework is actually about
The browser suite checked what the app renders but nothing about authoring,
which is the part that changed. It now registers a fresh account and walks
the wizard, including the case where a partner added mid-wizard has to appear
by name without navigating away first, and it drags a range on the calendar,
deletes the period, and reloads to confirm the days really went. Both are
regressions that were found by hand within the last day and would have been
found here instead.

Doing this surfaced that the age-four spec had been asserting on figures that
moved inside a collapsed section, so it had stopped checking anything. The
stale note about the retired tips page went too.
2026-09-18 00:50:01 +02:00

65 lines
3.3 KiB
TypeScript

/**
* Regression guard for the age-4 savable/expiring arithmetic actually
* reaching the Dashboard UI.
*
* Domain rule (see AGENTS.md "Domain rules" and
* backend/app/config.py's `LeaveRules`): after the child turns 4, only 96
* days may be saved *per child* — for a `couple` workspace with two
* parents, that's a 48-day cap *per parent*, not 96 each. A prior bug
* modelled a two-parent family as able to save 192 days combined by
* applying the per-child cap to each parent independently — see
* `AnalyticsService`'s module docstring, which documents this exact
* failure mode. This test asserts the invariant holds in the API response
* AND that the Dashboard renders those same numbers (not some other,
* separately-computed figure) — the historically-buggy progress bar was a
* *wiring* defect, not a backend one.
*/
import { test, expect } from '@playwright/test'
import { apiGetOverview, apiLogin, DEMO_EMAIL, DEMO_PASSWORD } from '../support/api'
import { loadSeedFixture } from '../support/fixture'
test('per-parent expiring/savable figures respect the 48/96 age-4 cap, and the Dashboard shows the same numbers', async ({
page,
}) => {
const fixture = loadSeedFixture()
const token = await apiLogin(DEMO_EMAIL, DEMO_PASSWORD)
const overview = await apiGetOverview(token, fixture.workspaceId, fixture.childId)
// Ground truth from the API, independent of anything rendered.
expect(overview.parent_projections.length).toBe(2) // seed_demo.py: Alex + Sam
for (const projection of overview.parent_projections) {
expect(projection.savable_after_b4).toBeLessThanOrEqual(projection.savable_cap_at_b4)
expect(projection.savable_after_b4).toBeGreaterThanOrEqual(0)
expect(projection.expiring_at_b4).toBeGreaterThanOrEqual(0)
}
// The literal regression this guards: a two-parent workspace's per-parent
// caps must sum to the per-CHILD ceiling (96), never double it (192).
const capSum = overview.parent_projections.reduce((sum, p) => sum + p.savable_cap_at_b4, 0)
expect(capSum).toBeLessThanOrEqual(96)
const savableSum = overview.parent_projections.reduce((sum, p) => sum + p.savable_after_b4, 0)
expect(savableSum).toBeLessThanOrEqual(96)
// Now confirm the Dashboard actually surfaces these same figures.
await page.goto('/')
await expect(page.getByTestId('dashboard')).toBeVisible()
// The per-parent/combined metrics live inside the collapsed "Fler
// detaljer" <details> disclosure (Dashboard.tsx's
// `dashboard-more-details`) — open it before asserting anything inside,
// otherwise every element in there is genuinely hidden (native <details>
// collapse, not just scrolled out of view).
await page.locator('[data-testid="dashboard-more-details"] summary').click()
for (const projection of overview.parent_projections) {
const metric = page.getByTestId(`metric-expiring-parent-${projection.personal_data_uuid}`)
await expect(metric).toBeVisible()
const value = metric.locator('[data-testid^="metric-value-"]')
await expect(value).toHaveText(String(projection.expiring_at_b4))
}
const combinedMetric = page.getByTestId('metric-expiring-combined')
await expect(combinedMetric).toBeVisible()
const combinedValue = combinedMetric.locator('[data-testid^="metric-value-"]')
await expect(combinedValue).toHaveText(String(overview.combined_expiring_at_b4))
})