Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
schema: spec-driven
created: 2026-08-31
skip_specs: true
21 changes: 21 additions & 0 deletions openspec/changes/deterministic-session-date-buckets/proposal.md
Original file line number Diff line number Diff line change
@@ -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.
9 changes: 9 additions & 0 deletions openspec/changes/deterministic-session-date-buckets/tasks.md
Original file line number Diff line number Diff line change
@@ -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.
Loading