Skip to content
Merged
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 numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
{
"version": 2,
"id": "67bf71cf-25cb-40d9-a8a2-bbf993bf6b29",
"createdOn": "2026-08-21",
"action": "add",
"payload": {
"pri": "P2",
"type": "issue",
"summary": "Five npm run test failures reported on Windows at cdfcbaccd do not reproduce on Linux; full suite is green, and none are eligible for the Playwright-only flake ledger",
"detail": "Reported on a clean Windows workstation (D:\\Repos\\Database, main at cdfcbaccd, empty working tree): npm run test exited 1 with 4 files / 5 tests failed (tests/codex-cloud-setup.test.ts 'writes managed shell policy behaviorally and preserves unrelated Codex config'; tests/hosted-migration-role-guard.test.ts 'accepts the current repository state'; tests/http-readiness.test.ts 'honours the overall deadline when every response remains open'; tests/document-viewer-page-virtualization.dom.test.tsx 'reads exactly one page ahead and one behind, and only once idle' and 'collapses render-ahead to the reader's page alone when one canvas costs the whole budget', both failing at flushIdle() line 80 on await waitFor(() => expect(idleCallbacks.length).toBeGreaterThan(0))). VERIFIED ON LINUX at HEAD 1155041: all five pass individually, and a full GATE_RECEIPTS=off npm run test is green (696 files / 7770 tests passed, 4 skipped, exit 0, 196s). The document-viewer pair also passed 3/3 consecutive runs under 3x CPU oversubscription (12 spinners on 4 cores), so ordinary load does not reproduce it. git diff cdfcbaccd..1155041 shows none of the four test files, nor their subjects (scripts/check-hosted-migration-role.mjs, scripts/setup-codex-cloud.sh, supabase/**, src/components/document-viewer/**), changed between the reported SHA and HEAD, so the Linux green applies to cdfcbaccd itself and the three intervening commits did not fix these. CONCLUSION SO FAR: no genuine breakage on main is detectable from Linux; the failures are specific to that Windows workstation. NOT YET CLASSIFIED: whether each is environmental noise or a real Windows-only defect. Items 3-5 are timing shapes and are plausibly load-induced (the reported run took 601s vs 196s here). Items 1 and 2 are NOT timing shapes - they are deterministic state assertions - so a Windows-only failure there is a real Windows-only defect in either the test's Windows handling or the guard itself, and should not be dismissed as environmental. Needed to close this out: the actual assertion text from the Windows run (npx vitest run tests/hosted-migration-role-guard.test.ts tests/codex-cloud-setup.test.ts on that machine). CONCRETE LEADS: (a) hosted-migration-role-guard's validateRepository() calls repositoryEntries(), which runs git ls-files --cached --others --exclude-standard, so it grades UNTRACKED non-ignored files too - any stray file under scripts/, supabase/migrations/, .github/workflows/, or the guarded exact paths whose name or content matches the reserved role flips this test red, as would a nested git worktree directory under the repo root (readFileSync on a directory entry throws EISDIR); it also SHA-256s the on-disk bytes of supabase/migrations/20260713102000_revoke_supabase_admin_default_privileges.sql, so CRLF in the working tree would break it, though .gitattributes '* text=auto eol=lf' should prevent that and the bytes hash correctly here. (b) codex-cloud-setup's failing case shells out to Git Bash (C:\\Program Files\\Git\\bin\\bash.exe) with msys drive-letter path translation and asserts idempotency across two setup runs; only 1 of that file's 39 tests failed, so it is not a systemic bash/path breakage. (c) The document-viewer pair's shared failure point is structurally fragile independent of load: flushIdle() waits for requestIdleCallback to have been scheduled, but the viewer's render-ahead effect (src/components/document-viewer/pdf-canvas-viewer.tsx:781-792) returns early WITHOUT scheduling whenever liveCanvasLimit <= 1, and resolveLiveCanvasWindow returns 1 whenever perCanvasPixels is 0 - which is what jsdom's zero-width layout measurement yields before the ResizeObserver-driven contentWidth lands. The test's cancelIdleCallback stub is a no-op, so idleCallbacks only ever accumulates callbacks from earlier effect runs; if the first effect run measures a zero-width canvas, no callback is ever pushed and flushIdle times out at waitFor's 1000ms default regardless of machine speed. FLAKE POLICY DOES NOT APPLY: tests/flake-ledger.json is explicitly Playwright-only ('Only reproduced @quarantine Playwright tests belong here', entries need an exact spec+title and a @quarantine tag), and all five failures are Vitest. None of these can be quarantined there; they must be diagnosed or fixed. Also note the previously known local-Windows failures (tests/session-start-hook.test.ts, worker-observability) PASSED in the reported run, so any note calling those the known environmental set is stale.",
"source": "Session investigation on Linux cloud container at HEAD 1155041; full-suite log /tmp scratchpad fulltest.log; reported Windows run at cdfcbaccd",
"issueUlid": "01M0JVX4NP97J5B4FG2V62GNJZ"
}
}
23 changes: 22 additions & 1 deletion tests/document-viewer-page-virtualization.dom.test.tsx
Original file line numberDiff line numberDiff line change
Expand Up@@ -77,7 +77,28 @@ let animationFrameCallbacks = new Map<number, FrameRequestCallback>();
let nextAnimationFrame = 1;

async function flushIdle() {
await waitFor(() => expect(idleCallbacks.length).toBeGreaterThan(0));
try {
await waitFor(() => expect(idleCallbacks.length).toBeGreaterThan(0));
} catch (cause) {
// `waitFor` alone reports "expected 0 to be greater than 0", which reads as
// a slow machine and is usually not one. The viewer schedules render-ahead
// ONLY when `liveCanvasLimit > 1`, and `resolveLiveCanvasWindow` collapses
// that to 1 whenever `perCanvasPixels` is 0 — which is exactly what jsdom's
// zero-width layout measurement yields before `contentWidth` lands. In that
// case no callback is ever scheduled and no amount of waiting produces one,
// so say which of the two happened instead of timing out opaquely.
const slots = screen.queryAllByTestId("pdf-page-slot");
throw new Error(
"No render-ahead idle callback was scheduled within the waitFor window. " +
"The viewer schedules one only while the canvas budget allows more than one live " +
"canvas; a zero-width measurement collapses that budget to the reader's page alone " +
"and skips scheduling entirely. Observed at timeout: " +
`${slots.length} page slot(s), ` +
`${slots.filter((slot) => slot.getAttribute("data-rendered") === "true").length} rendered, ` +
`${observers.length} intersection observer(s).`,
{ cause },
);
}
const pending = idleCallbacks;
idleCallbacks = [];
await act(async () => {
Expand Down
Loading