Files
jacobh2 ae6db7e16f Redesign the setup flow and consolidate the CSS into one primitives layer
Onboarding asks explicitly for one or two parents and shows one card per
parent for balances; the balance form is per parent with inline
validation; the partner can be filled from the FK deduction or added
from it. Settings and Dashboard reuse the same form.

CSS: bare buttons carry no colour any more; buttons, cards, choice
cards, fields, alerts, badges, eyebrow and modal chrome are defined once
in primitives.css. Media queries live only in responsive.css. A style
guard test blocks hex, !important and stray media queries. Bilingual
fixes: calendar selects size by content, header no longer wraps. Vitest
is capped at four workers.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-19 12:27:29 +02:00

72 lines
3.2 KiB
TypeScript

/**
* The other authoring gesture nothing end-to-end covers yet: registering a
* brand-new account and walking the 3-step onboarding wizard (child ->
* optional partner -> balances). Runs with an empty `storageState` —
* deliberately NOT the shared demo session `auth.setup.ts` produces for the
* rest of the suite — since registering a fresh account is exactly what's
* under test.
*
* Every date used here is derived from "today", never a hardcoded year (see
* `support/dates.ts`'s module doc for why).
*/
import { test, expect } from '@playwright/test'
import {
uniqueEmail,
registerAndReachOnboarding,
fillChildStep,
continueSoloAndSkipBalances,
chooseTwoParents,
enterBalancesFor,
} from '../support/onboarding'
test.use({ storageState: { cookies: [], origins: [] } })
test.describe('onboarding wizard', () => {
test('skipping the balances step still reaches the dashboard with the estimated badge', async ({ page }) => {
await registerAndReachOnboarding(page, uniqueEmail('onboarding-skip'), 'Alex Testsson')
await fillChildStep(page, 'Nova')
// Adding a partner is optional — nothing to change here.
await continueSoloAndSkipBalances(page)
await expect(page.getByTestId('dashboard-estimate-badge')).toHaveText('Uppskattat')
})
test('a partner added mid-wizard shows their name on Översikt with no navigation in between', async ({ page }) => {
await registerAndReachOnboarding(page, uniqueEmail('onboarding-couple'), 'Sam Testsson')
await fillChildStep(page, 'Nova')
await chooseTwoParents(page, 'Kim')
await expect(page.getByTestId('onboarding-parent-card')).toHaveCount(2)
await page.getByTestId('onboarding-finish').click()
// The regression this guards: finishing the wizard flips
// WorkspaceContext's `children` from empty to non-empty, which
// re-renders this SAME Dashboard mount straight past the onboarding
// branch — there is no `navigate()` call in between. A previously
// fetched, now-stale members list used to leave the partner showing as
// the generic "Förälder N" fallback until a manual navigation away and
// back refetched it (see Dashboard.tsx's `wasAwaitingFirstChildRef`
// effect, and `nameResolver`/`parentDisplayName`). Asserting
// immediately — no reload, no extra navigation — is what would have
// caught that.
await expect(page.getByTestId('dashboard')).toBeVisible({ timeout: 15_000 })
const age4Bars = page.getByTestId('age4-bars')
await expect(age4Bars).toBeVisible()
await expect(age4Bars).toContainText('Kim')
await expect(age4Bars).not.toContainText('Förälder')
})
test('entering balances for both parents during the couple path carries through to Översikt', async ({ page }) => {
await registerAndReachOnboarding(page, uniqueEmail('onboarding-couple-balances'), 'Robin Testsson')
await fillChildStep(page, 'Nova')
await chooseTwoParents(page, 'Kim')
await enterBalancesFor(page, 'Robin Testsson', { sjukpenning: 150, lagsta: 30, dubbeldagar: 20 })
await enterBalancesFor(page, 'Kim', { sjukpenning: 100, lagsta: 20, dubbeldagar: 10 })
await page.getByTestId('onboarding-finish').click()
await expect(page.getByTestId('dashboard')).toBeVisible({ timeout: 15_000 })
})
})