import { describe, it, expect, beforeAll } from "vitest"; import { execSync } from "node:child_process"; import { readFileSync } from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); const appCssPath = path.join(root, "musehub/templates/musehub/static/app.css"); function compiledCss(): string { return readFileSync(appCssPath, "utf8"); } describe("layout sidebar compiled CSS (musehub#84)", () => { beforeAll(() => { execSync("npm run build:css", { cwd: root, stdio: "pipe" }); }); it("SIDEBAR_06: app.css contains no 100vh", () => { expect(compiledCss()).not.toMatch(/100vh/); }); it("SIDEBAR_06: app.css uses 100dvh for viewport-bound panels", () => { expect(compiledCss()).toMatch(/100dvh/); }); it("SIDEBAR_01: layout-two-col utility includes min-height:0", () => { expect(compiledCss()).toMatch(/\.layout-two-col\{[^}]*min-height:0/); }); it("SIDEBAR_02: layout-sidebar utility scrolls independently of its own bounded height", () => { const css = compiledCss(); expect(css).toMatch(/\.layout-sidebar\{[^}]*min-height:0/); expect(css).toMatch(/\.layout-sidebar\{[^}]*overflow-y:auto/); }); it("SIDEBAR_03: layout-two-col resets to auto height below 900px", () => { expect(compiledCss()).toMatch( /@media\s*\(max-width:\s*900px\)\s*\{[^}]*\.layout-two-col\{[^}]*height:auto/, ); }); it("SIDEBAR_05: bounded-height columns use --sticky-offset with header fallback", () => { const css = compiledCss(); expect(css).toMatch(/100dvh - var\(--sticky-offset,\s*var\(--header-height\)\)/); }); });