Date & Time Traps
Date bugs are the quietest suite-killers: a spec that passes all month and dies on the 1st, an assertion written in your timezone, a "tomorrow" that changed at midnight. Four widgets that reward page.clock, ISO attributes, and timezone-explicit assertions. New to calendars? Start with the basic date picker widget.
Custom calendar
Weekends and past dates are disabled. Every day button carries an ISO data-date, the honest locator target.
Picked: nothing yet
Check-in / check-out range
Checkout must be after check-in; the nights count is computed, so assert the math, not the inputs.
Check-out must be after check-in
Stay: 0 night(s)
Meeting scheduler (the midnight trap)
The summary renders a relative day ("today", "tomorrow", "in N days") computed from the real clock: the classic spec that breaks at midnight. Tame it with page.clock.setFixedTime.
Pick a date and a time.
One instant, three clocks
A flight departs at a fixed UTC instant. The same moment reads differently in every timezone, including yours, which is exactly why assertions must name their zone.
Departure instant: 2030-01-15T18:30:00Z
| Clock | Reads |
|---|---|
| UTC | - |
| India (Asia/Kolkata) | - |
| Your browser (-) | - |
Drills
- ISO beats text. Pick the 15th of next month by
data-dateattribute, never by the visible "15" (two months on screen both have a 15th someday). Assert the picked line. - Disabled logic. Assert a weekend button is disabled AND has the strike-through class, then assert clicking it changes nothing.
- Range math. Book 3 nights and assert the count; then invert the range and assert the error line plus a zeroed count.
- Freeze the clock. With
page.clock.setFixedTime, set "today" to a known date, schedule a meeting 2 days out, and assert the summary says "in 2 days". Rerun with a different fixed date to prove independence from the real calendar. - Timezone-proof assertion. Assert the IST cell equals the UTC instant shifted by +05:30 without ever reading your machine's zone; then assert the local row using
Intl.DateTimeFormat().resolvedOptions().timeZoneinsideevaluate.