Files
F-r-ldraledigplannerare/frontend/e2e/tests/calendar-band.spec.ts
T
jacobh2 ed5680253e Check in a browser what the unit tests cannot see
Every serious defect in this project was found by opening the app, most
recently a feature that rendered blank cards to every user while its tests
passed, and a progress bar labelled in the wrong unit. Five checks now run
without a person: that the age-four figures on screen match what the API
computed, that a multi-week period draws as one bar rather than fragments,
that Sundays and holidays are red where Saturdays are not, that no identifier
leaks into visible text, and that no page logs an error.

Three of them were confirmed by reintroducing the original bug and watching
the right test fail. Dates are derived rather than written down: Easter is
computed independently instead of asked of the system under test, and the
fixture period is placed relative to today, so the suite does not expire.

It runs as its own job and does not block a merge until it has proved itself
stable.
2026-09-17 19:46:17 +02:00

65 lines
3.2 KiB
TypeScript

/**
* A multi-week leave period must render as ONE continuous band across
* `CalendarWeek` rows, not fragment into a separate bar per week row, and
* only the row containing the band's true first/last day gets a rounded
* end cap (see `CalendarWeek.tsx`'s `computeBandSegments`/
* `isBridgeableGap`).
*
* The band under test is created directly via the API in global-setup.ts
* (15 consecutive weekdays, entirely inside one calendar month, dates
* derived from "today" — see that file), not by clicking through the UI,
* so a setup failure here is distinguishable from a real assertion
* failure. Its exact key is reproduced from `CalendarWeek.tsx`'s
* `bandKeyFor` for an ad-hoc (no wish) period: `adhoc:{parent}:{type}:{isDubbeldag}`.
*/
import { test, expect } from '@playwright/test'
import { countWeekRows } from '../support/dates'
import { goToCalendarMonth } from '../support/calendarNav'
import { loadSeedFixture } from '../support/fixture'
test('a multi-week band renders as one continuous bar with caps only at its true ends', async ({ page }) => {
const fixture = loadSeedFixture()
const { startDate, endDate, parentPersonalDataUuid, dayType } = fixture.band
const start = new Date(`${startDate}T00:00:00Z`)
const end = new Date(`${endDate}T00:00:00Z`)
const expectedRows = countWeekRows(start, end)
expect(expectedRows).toBeGreaterThan(1) // otherwise this isn't testing cross-week banding at all
await goToCalendarMonth(page, start)
const bandTestId = `calendar-band-adhoc:${parentPersonalDataUuid}:${dayType}:false::${startDate}`
const bandRows = page.locator(`[data-testid="${bandTestId}"]`)
await expect(bandRows).toHaveCount(expectedRows)
// Not fragmented: every row of this band shares exactly this one
// testid/key — if bridging across a weekend had failed, the run would
// have split into multiple distinct ids instead.
const allTestIds = await page
.locator('[data-testid^="calendar-band-adhoc:"]')
.evaluateAll((els) => els.map((el) => el.getAttribute('data-testid')))
const distinctIds = new Set(allTestIds)
expect(distinctIds.size, `expected exactly one band id, found: ${[...distinctIds].join(', ')}`).toBe(1)
const classNames = await bandRows.evaluateAll((els) => els.map((el) => el.className))
const startFlags = classNames.map((cls) => cls.includes('calendar-band--start'))
const endFlags = classNames.map((cls) => cls.includes('calendar-band--end'))
// Rounded start cap only on the first (true-start) row.
expect(startFlags[0]).toBe(true)
expect(startFlags.slice(1).every((flag) => flag === false)).toBe(true)
// Rounded end cap only on the last (true-end) row.
expect(endFlags[endFlags.length - 1]).toBe(true)
expect(endFlags.slice(0, -1).every((flag) => flag === false)).toBe(true)
// Rendered corner radius follows the class, not just its name.
await expect(bandRows.first()).toHaveCSS('border-top-left-radius', '4px')
await expect(bandRows.last()).toHaveCSS('border-top-right-radius', '4px')
if (expectedRows > 2) {
const middleRow = bandRows.nth(1)
await expect(middleRow).toHaveCSS('border-top-left-radius', '0px')
await expect(middleRow).toHaveCSS('border-top-right-radius', '0px')
}
})