plans/022-export-pipeline-tests.md
Executor instructions: Follow this plan step by step. Run every verification command and confirm the expected result. If anything in "STOP conditions" occurs, stop and report. When done, update the status row in
plans/README.md.Drift check (run first):
git diff --stat c63cb120..HEAD -- packages/slidev/node/commands/export.tsOn a mismatch with the excerpts below, treat it as a STOP condition.
c63cb120, 2026-07-10slidev export (PDF/PNG/PPTX) is a flagship feature (README) implemented in a
658-line file with zero tests. Regressions in page-range selection, TOC
outline building, or filename handling ship undetected; CI only runs slidev build in smoke, never export. Characterization tests over the pure helpers
give a fast safety net now (no Playwright needed) and are the prerequisite for
safely decomposing the module (plan 023).
packages/slidev/node/commands/export.ts pure/near-pure helpers worth pinning:
getExportOptions(args, options, outFilename?) (:574-624) — merges CLI args +
deck config into an ExportOptions; exported already.addToTree (:51-67) + makeOutline (:69-77) — TOC → PDF outline string
(module-internal; not currently exported). NB: plan 021 may move addToTree
into @slidev/parser as buildTocTree — if 021 has landed, test the shared
builder instead and only test makeOutline here.parseRangeString (from @slidev/parser) drives page selection at :189 — its
own tests are plan 009; here, assert getExportOptions/range interplay.gen* render functions need Playwright + a running preview → out of scope
for unit tests; covered by the optional smoke in Step 3.Test patterns available: colocated *.test.ts with Vitest (see
packages/slidev/node/syntax/*.test.ts) using describe/it/expect and
toMatchInlineSnapshot.
| Purpose | Command | Expected |
|---|---|---|
| Install | pnpm install | exit 0 |
| Build | pnpm build | exit 0 |
| Test | pnpm test -- export | new tests pass |
| Typecheck | pnpm typecheck | exit 0 |
In scope:
packages/slidev/node/commands/export.ts — export addToTree/makeOutline
(or import the shared builder from 021) so they're testable; no behavior changepackages/slidev/node/commands/export.test.ts (create) — unit testsOut of scope:
gen* closures (plan 023).test/export-pipeline.test(export): characterize export helpers.If addToTree/makeOutline are still local to export.ts, add export to them
(or, if plan 021 landed, import buildTocTree from @slidev/parser). Do not
change their logic.
Create packages/slidev/node/commands/export.test.ts covering:
getExportOptions: given representative args + a fake ResolvedSlidevOptions
(minimal data.config + data.slides), assert the resolved format, output
(default ${basename(entry,'.md')}-export), width/height from
canvasWidth/aspectRatio, withClicks default for pptx, range, and
scale defaults. Snapshot the returned object.makeOutline (and addToTree/buildTocTree): build a small tree from a
handful of titled slides at mixed levels and snapshot the outline string
(path|--|title lines), including a nested case.parseRangeString(total, range) (imported from
@slidev/parser) selects the expected pages for a couple of inputs the exporter
relies on (e.g. '2-3', undefined).Keep fixtures inline/synthetic — no real rendering, no fs writes.
Verify: pnpm build && pnpm test -- export → all new tests pass.
Only if the operator wants render coverage and playwright-chromium is available:
add a slow/opt-in test (or a cypress/script harness) that builds the demo,
serves it, runs exportSlides for a 2-slide deck to each format, and asserts the
output file exists with a plausible page count/size. Gate it so it does not run
in the default pnpm test (e.g. behind an env flag) unless CI is set up for
Playwright. STOP and ask before adding a browser dependency to the default CI.
export.test.ts pins getExportOptions, outline building, and range
selection — the regressions most likely to slip through today.packages/slidev/node/commands/export.test.ts exists and passesgetExportOptions, outline building, and range selection are coveredexport.ts beyond adding export keywordspnpm test does not require Playwright/a browserpnpm build && pnpm typecheck exit 0git status)plans/README.md status row updatedStop and report if:
export keyword) — that means the code has drifted; report.exportSlides.ResolvedSlidevOptions in tests stays minimal and
doesn't couple tests to unrelated config.