Files
fusion/packages/dashboard/app/__tests__/onboarding-overlay-layering.test.ts
gsxdsm 2bc3543e77 fix(self-healing): use slim listTasks in maintenance recover loops
Batch 2 of runMaintenance() runs ~10 recover passes back-to-back, each
calling listTasks({ column: ... }) without slim. On busy boards this
materializes every task's activity log into memory ~10× per cycle,
walking the dashboard heap toward the 8 GB V8 limit until OOM. The
archive pass at line 610 already had this fix; extend it to the in-progress
and in-review recover passes that only read steps / paused / worktree /
mergeDetails / postReviewFixCount — all included in the slim projection.

Triage recovers are left non-slim because hasLatestSpecReviewApproval
scans task.log to find the most recent spec review; the triage column
is small so the memory cost is bounded.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 22:25:57 -07:00

36 lines
1.3 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { loadAllAppCssBaseOnly } from "../test/cssFixture";
const css = loadAllAppCssBaseOnly();
function getSelectorBlock(selector: string): string {
const escaped = selector.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const pattern = new RegExp(`${escaped}\\s*\\{([^}]*)\\}`, "m");
const match = css.match(pattern);
expect(match, `Expected ${selector} CSS block to exist`).not.toBeNull();
return match?.[1] ?? "";
}
function getSelectorZIndex(selector: string): number {
const block = getSelectorBlock(selector);
const match = block.match(/z-index:\s*(\d+)/);
expect(match, `Expected ${selector} to define a z-index`).not.toBeNull();
return Number(match?.[1]);
}
describe("onboarding overlay layering contract (FN-2397)", () => {
it("keeps modal overlays above sticky top banners", () => {
const modalOverlayZ = getSelectorZIndex(".modal-overlay");
const sessionBannerZ = getSelectorZIndex(".session-notification-banner");
expect(modalOverlayZ).toBeGreaterThan(sessionBannerZ);
});
it("keeps the onboarding resume banner in normal document flow", () => {
const onboardingResumeBlock = getSelectorBlock(".onboarding-resume-card");
expect(onboardingResumeBlock).not.toMatch(/position:\s*sticky/);
expect(onboardingResumeBlock).not.toMatch(/top:\s*0/);
});
});