diff --git a/apps/web/src/components/workspace/__tests__/sessions-panel.test.tsx b/apps/web/src/components/workspace/__tests__/sessions-panel.test.tsx index 24938a5c..8e868723 100644 --- a/apps/web/src/components/workspace/__tests__/sessions-panel.test.tsx +++ b/apps/web/src/components/workspace/__tests__/sessions-panel.test.tsx @@ -109,13 +109,23 @@ describe("SessionsPanel", () => { }); it("groups sessions by date buckets", () => { - const now = Date.now(); - const dayMs = 86_400_000; - renderPanel([ - { id: "today-session", title: "Today chat", status: "idle", updatedAt: "now", updatedAtRaw: now }, - { id: "yesterday-session", title: "Yesterday chat", status: "idle", updatedAt: "1d", updatedAtRaw: now - dayMs }, - { id: "old-session", title: "Old chat", status: "idle", updatedAt: "30d", updatedAtRaw: now - 30 * dayMs }, - ]); + // Pin the clock: `now - 30d` must land in the previous calendar month so + // it buckets as "Older" regardless of when the suite runs. A real clock + // fails on month-boundary days (e.g. on the 31st, 30d back stays in-month + // and groups as "This month" instead). + vi.useFakeTimers(); + try { + vi.setSystemTime(new Date("2026-06-17T12:00:00Z")); + const now = Date.now(); + const dayMs = 86_400_000; + renderPanel([ + { id: "today-session", title: "Today chat", status: "idle", updatedAt: "now", updatedAtRaw: now }, + { id: "yesterday-session", title: "Yesterday chat", status: "idle", updatedAt: "1d", updatedAtRaw: now - dayMs }, + { id: "old-session", title: "Old chat", status: "idle", updatedAt: "30d", updatedAtRaw: now - 30 * dayMs }, + ]); + } finally { + vi.useRealTimers(); + } expect(screen.getByText("Today")).toBeTruthy(); expect(screen.getByText("Yesterday")).toBeTruthy(); diff --git a/openspec/changes/deterministic-session-date-buckets/.openspec.yaml b/openspec/changes/deterministic-session-date-buckets/.openspec.yaml new file mode 100644 index 00000000..52a7c58f --- /dev/null +++ b/openspec/changes/deterministic-session-date-buckets/.openspec.yaml @@ -0,0 +1,3 @@ +schema: spec-driven +created: 2026-08-31 +skip_specs: true diff --git a/openspec/changes/deterministic-session-date-buckets/proposal.md b/openspec/changes/deterministic-session-date-buckets/proposal.md new file mode 100644 index 00000000..0faae8a5 --- /dev/null +++ b/openspec/changes/deterministic-session-date-buckets/proposal.md @@ -0,0 +1,21 @@ +## Why + +The `sessions-panel` test "groups sessions by date buckets" broke in CI on 2026-08-31 (and fails locally on the same date) with no code change: its "old" fixture is `Date.now() - 30 days`, and `groupByDateBucket` has a "This month" tier, so whenever `now - 30 days` is still inside the current calendar month — every 31st — the fixture groups as "This month" and the `Older` header never renders. The test depends on the wall calendar instead of being deterministic. + +## What Changes + +- Pin the clock in that single test with `vi.useFakeTimers()` / `vi.setSystemTime()` at a fixed mid-month instant (2026-06-17T12:00Z) so the three fixtures deterministically land in Today, Yesterday, and Older; restore real timers in a `finally`. +- No product, library, or spec-level behavior changes — test-only, so the change opts out of specs (`skip_specs: true`). + +## Capabilities + +### New Capabilities +- (none — no behavior changes.) + +### Modified Capabilities +- (none.) + +## Impact + +- `apps/web/src/components/workspace/__tests__/sessions-panel.test.tsx` — one test made calendar-independent. +- Verified the test passes under `UTC`, `Pacific/Kiritimati` (UTC+14), and `America/New_York`, and on the failure-prone date; suite-wide behavior unchanged. diff --git a/openspec/changes/deterministic-session-date-buckets/tasks.md b/openspec/changes/deterministic-session-date-buckets/tasks.md new file mode 100644 index 00000000..4bf9fffe --- /dev/null +++ b/openspec/changes/deterministic-session-date-buckets/tasks.md @@ -0,0 +1,9 @@ +## 1. Deterministic test + +- [x] 1.1 In `apps/web/src/components/workspace/__tests__/sessions-panel.test.tsx`, pin the clock for "groups sessions by date buckets" via `vi.useFakeTimers()` + `vi.setSystemTime()` (2026-06-17T12:00:00Z), keeping render inside the fake-clock scope and restoring real timers in `finally`. + +## 2. Verification + +- [x] 2.1 Run the file under `UTC`, `Pacific/Kiritimati` (UTC+14), and `America/New_York` — passes in all. +- [x] 2.2 Run the sessions-panel and lib test files — green. +- [ ] 2.3 Run `bash scripts/check-podman-images.sh` from the repo root — unaffected by this change.