// @vitest-environment node import { describe, expect, it } from 'vitest'; import { buildSrcdoc } from '../../src/runtime/srcdoc'; // Regression coverage for the "deck-stage shows a sliver of content in the // top-left with the rest of the preview black" symptom. Root cause: the // srcdoc deck bridge injected `place-content: center !important` on // `.stage, .deck-stage, .deck-shell` for ALL deck-mode artifacts, even // framework decks (DECK_SKELETON_HTML in apps/daemon/src/prompts/ // deck-framework.ts) whose `fit()` already centers a `transform-origin: // top left` stage with an explicit `translate(tx, ty)` that assumes the // stage's natural layout position is (0, 0). Forcing place-content on // the shell re-centered the implicit grid track, doubled the offset, and // pushed the scaled stage off-screen. // // The fix: detect the framework deck via its `id="deck-stage"` marker and // skip the `data-od-deck-fix` styleFix for it. Legacy / non-framework // decks that authored their own `.stage` grid still get the override. function frameworkDeckHtml(): string { return [ '', '
', '
', '
slide 1
', '
slide 2
', '
', '
', '', '', ].join('\n'); } function legacyDeckHtml(): string { return [ '', '
', '
', '
slide 1
', '
slide 2
', '
', '
', '', ].join('\n'); } describe('injectDeckBridge — framework-deck detection (#deck-stage)', () => { it('skips the place-content fix when the deck carries the framework #deck-stage marker', () => { const out = buildSrcdoc(frameworkDeckHtml(), { deck: true }); expect(out).not.toMatch(/]*data-od-deck-fix/); expect(out).not.toContain('place-content: center !important'); // The bridge script itself must still ship — the framework's own // fit() handles centering, but the host-side counter / keyboard // bridge still needs the slide-state postMessage channel. expect(out).toMatch(/]*data-od-deck-bridge/); }); it('keeps injecting the place-content fix for legacy / non-framework decks', () => { const out = buildSrcdoc(legacyDeckHtml(), { deck: true }); expect(out).toMatch(/]*data-od-deck-fix/); expect(out).toContain('.stage, .deck-stage, .deck-shell { place-content: center !important; }'); expect(out).toMatch(/]*data-od-deck-bridge/); }); it('skips the fix when #deck-stage uses single quotes, extra whitespace, or uppercase ID syntax', () => { // The detector should match the framework's emit shape but also // tolerate the minor formatting variations that DOMParser / // serializeHtmlDocument introduce in the middle of the pipeline. const variants = [ `
`, `
`, `
`, ]; for (const variant of variants) { const out = buildSrcdoc(`${variant}`, { deck: true }); expect(out, `variant ${JSON.stringify(variant)}`).not.toContain('data-od-deck-fix'); } }); });