ed5680253e
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.
74 lines
3.8 KiB
TypeScript
74 lines
3.8 KiB
TypeScript
/**
|
||
* §3.4 red-day rendering, and the "combined holiday name" trap.
|
||
*
|
||
* The backend (`app/utils/holidays.py::get_swedish_holidays`) returns a
|
||
* COMBINED name like "Påskdagen; Söndag" whenever a fixed public holiday
|
||
* falls on a Sunday — `get_red_days` keeps that combined string (only a
|
||
* *bare* "Söndag" is dropped). A careless frontend filter that splits on
|
||
* ';' and throws away anything containing a weekday name would silently
|
||
* delete Påskdagen/Pingstdagen's own name along with it. This test asserts
|
||
* both holidays render as NAMED red days, by their real name, in the
|
||
* calendar cell's visible text (not hover-only).
|
||
*
|
||
* All dates are computed from "today" (see support/dates.ts) — never a
|
||
* hardcoded year — because Easter/Pentecost's date, and therefore which
|
||
* year's calendar page to look at, changes every run.
|
||
*/
|
||
import { test, expect } from '@playwright/test'
|
||
import { addDays, nextEasterOnOrAfter, whitSunday, toIsoDate } from '../support/dates'
|
||
import { calendarDayCell, goToCalendarMonth } from '../support/calendarNav'
|
||
|
||
const RED_DAY_BG = 'rgb(253, 236, 235)' // .calendar-day--red-day
|
||
const WEEKEND_BG = 'rgb(240, 240, 240)' // .calendar-day--weekend (plain Saturday)
|
||
|
||
test.describe('red days, klämdagar and the combined-holiday-name trap', () => {
|
||
test('Easter Sunday (Påskdagen) renders as a named red day', async ({ page }) => {
|
||
const easter = nextEasterOnOrAfter(new Date())
|
||
await goToCalendarMonth(page, easter)
|
||
|
||
const cell = calendarDayCell(page, toIsoDate(easter))
|
||
await expect(cell).toHaveClass(/calendar-day--red-day/)
|
||
await expect(cell).toHaveCSS('background-color', RED_DAY_BG)
|
||
await expect(cell.getByTestId('calendar-day-holiday-name')).toHaveText('Påskdagen')
|
||
})
|
||
|
||
test('Whit Sunday (Pingstdagen) renders as a named red day', async ({ page }) => {
|
||
const whitsun = whitSunday(nextEasterOnOrAfter(new Date()))
|
||
await goToCalendarMonth(page, whitsun)
|
||
|
||
const cell = calendarDayCell(page, toIsoDate(whitsun))
|
||
await expect(cell).toHaveClass(/calendar-day--red-day/)
|
||
await expect(cell).toHaveCSS('background-color', RED_DAY_BG)
|
||
await expect(cell.getByTestId('calendar-day-holiday-name')).toHaveText('Pingstdagen')
|
||
})
|
||
|
||
test('a plain Sunday is red without a holiday name; a plain Saturday is neutral grey', async ({ page }) => {
|
||
// Two and three weeks before Easter: far enough from Easter's own
|
||
// de-facto cluster (Långfredagen/Påskafton/Påskdagen/Annandag påsk,
|
||
// Easter-2..Easter+1) that neither date is itself a public or de-facto
|
||
// holiday, just an ordinary weekend.
|
||
const easter = nextEasterOnOrAfter(new Date())
|
||
const plainSunday = addDays(easter, -14)
|
||
const plainSaturday = addDays(plainSunday, -1)
|
||
|
||
// Navigate by the Sunday's own month, not Easter's: whatever month
|
||
// `plainSunday` falls in, `plainSaturday` (the day right before it) is
|
||
// guaranteed to appear in that same month's grid too — either as an
|
||
// ordinary day in the month, or as a leading fill-in day completing
|
||
// that first Mon–Sun week row (see Calendar.tsx's `startOffset`) — so
|
||
// this never depends on the two dates sharing a calendar month.
|
||
await goToCalendarMonth(page, plainSunday)
|
||
|
||
const sundayCell = calendarDayCell(page, toIsoDate(plainSunday))
|
||
await expect(sundayCell).toHaveClass(/calendar-day--red-day/)
|
||
await expect(sundayCell).not.toHaveClass(/calendar-day--weekend/)
|
||
await expect(sundayCell).toHaveCSS('background-color', RED_DAY_BG)
|
||
await expect(sundayCell.getByTestId('calendar-day-holiday-name')).toHaveCount(0)
|
||
|
||
const saturdayCell = calendarDayCell(page, toIsoDate(plainSaturday))
|
||
await expect(saturdayCell).toHaveClass(/calendar-day--weekend/)
|
||
await expect(saturdayCell).not.toHaveClass(/calendar-day--red-day/)
|
||
await expect(saturdayCell).toHaveCSS('background-color', WEEKEND_BG)
|
||
})
|
||
})
|