@@ -88,6 +88,62 @@ testQuartoCmd(
8888- Use absolute paths with ` join() ` for file verification
8989- Clean up output directories in teardown
9090
91+ ### Pre/Post Render Script Tests
92+
93+ For testing pre-render or post-render scripts that run during project rendering:
94+
95+ ``` typescript
96+ import { docs } from " ../../utils.ts" ;
97+ import { join } from " ../../../src/deno_ral/path.ts" ;
98+ import { existsSync } from " ../../../src/deno_ral/fs.ts" ;
99+ import { testQuartoCmd } from " ../../test.ts" ;
100+ import { noErrors , validJsonWithFields } from " ../../verify.ts" ;
101+ import { safeRemoveIfExists } from " ../../../src/core/path.ts" ;
102+
103+ const projectDir = docs (" project/prepost/my-test" );
104+ const projectDirAbs = join (Deno .cwd (), projectDir );
105+ const dumpPath = join (projectDirAbs , " output.json" );
106+ const outDir = join (projectDirAbs , " _site" );
107+
108+ testQuartoCmd (
109+ " render" ,
110+ [projectDir ],
111+ [
112+ noErrors ,
113+ validJsonWithFields (dumpPath , {
114+ expected: " value" ,
115+ }),
116+ ],
117+ {
118+ teardown : async () => {
119+ safeRemoveIfExists (dumpPath );
120+ if (existsSync (outDir )) {
121+ await Deno .remove (outDir , { recursive: true });
122+ }
123+ },
124+ },
125+ );
126+ ```
127+
128+ ** Fixture structure:**
129+
130+ ```
131+ tests/docs/project/prepost/my-test/
132+ ├── _quarto.yml # project config with pre-render/post-render scripts
133+ ├── index.qmd # minimal page (website needs at least one)
134+ ├── check-env.ts # pre/post-render script (Deno TypeScript)
135+ └── .gitignore # exclude .quarto/ and *.quarto_ipynb
136+ ```
137+
138+ ** Key points:**
139+ - Pre/post-render scripts run as subprocesses with ` cwd ` set to the project directory
140+ - Scripts access environment variables via ` Deno.env.get() ` and can write files for verification
141+ - Use ` validJsonWithFields ` for JSON file verification (parses and compares field values exactly)
142+ - Use ` ensureFileRegexMatches ` for non-JSON files or when regex matching is needed
143+ - The file dump pattern (script writes JSON, test reads it) is useful for verifying env vars and other runtime state
144+ - Clean up both the dump file and the output directory in teardown
145+ - Existing fixtures: ` tests/docs/project/prepost/ ` (mutate-render-list, invalid-mutate, extension, issue-10828, script-env-vars)
146+
91147### Extension Template Tests
92148
93149For testing ` quarto use template ` :
@@ -164,6 +220,43 @@ folderExists(path: string)
164220directoryEmptyButFor (dir : string , allowedFiles : string [])
165221```
166222
223+ ### Content Verifiers
224+
225+ ``` typescript
226+ // Regex match on file contents (matches required, noMatches must be absent)
227+ ensureFileRegexMatches (file : string , matches : (string | RegExp )[], noMatches ?: (string | RegExp )[])
228+
229+ // Regex match on CSS files linked from HTML
230+ ensureCssRegexMatches (file : string , matches : (string | RegExp )[], noMatches ?: (string | RegExp )[])
231+
232+ // Check HTML elements exist or don't exist (CSS selectors)
233+ ensureHtmlElements (file : string , noElements : string [], elements : string [])
234+
235+ // Verify JSON structure has expected fields
236+ validJsonWithFields (file : string , fields : string [])
237+
238+ // Check output message at specific log level
239+ printsMessage (options : { level: string , regex: RegExp })
240+ ```
241+
242+ ### Assertion Helpers
243+
244+ ``` typescript
245+ // Assert path exists (throws if missing)
246+ verifyPath (path : string )
247+
248+ // Assert path does NOT exist (throws if present)
249+ verifyNoPath (path : string )
250+ ```
251+
252+ ### Cleanup Helpers
253+
254+ ``` typescript
255+ // Safe file removal (no error if missing) - from src/core/path.ts
256+ import { safeRemoveIfExists } from " ../../../src/core/path.ts" ;
257+ safeRemoveIfExists (path : string )
258+ ```
259+
167260### Path Helpers
168261
169262``` typescript
0 commit comments