|
| 1 | +// Test for issue #1998: "Expand to current page in toc tree". |
| 2 | +// |
| 3 | +// CmdExpandToCurrentPage expands the table-of-contents tree down to the entry |
| 4 | +// matching the current page and selects it (like Explorer's "Expand to current |
| 5 | +// folder"). Implemented in src/TableOfContents.cpp (ExpandTocToCurrentPage), |
| 6 | +// wired to the TOC context menu and the global command dispatcher. |
| 7 | +// |
| 8 | +// The test opens a PDF with a nested TOC, navigates to the last page, collapses |
| 9 | +// the whole tree, then invokes the command via WM_COMMAND and reads the tree |
| 10 | +// state with cross-process TreeView messages. After the command, the path to the |
| 11 | +// (deeply nested) last-page entry must be expanded -- so more tree rows are |
| 12 | +// visible than when fully collapsed -- and an item must be selected. Reverting |
| 13 | +// the fix leaves the tree collapsed with no expansion, so the test fails. |
| 14 | +// |
| 15 | +// Needs a PDF with a multi-level outline; uses one from the local bugs folder |
| 16 | +// and skips cleanly if it isn't present (so tests/all.ts keeps going). |
| 17 | + |
| 18 | +import { spawnSync } from "node:child_process"; |
| 19 | +import { copyFileSync, existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs"; |
| 20 | +import { join } from "node:path"; |
| 21 | +import { EXE, ROOT, tmpPath } from "./util"; |
| 22 | + |
| 23 | +// a PDF with a nested (multi-level) table of contents |
| 24 | +const TOC_PDF = "C:\\Users\\kjk\\OneDrive\\!sumatra\\bugs\\bug-1352-merged_manuals-1.4.2.pdf"; |
| 25 | + |
| 26 | +const SETTINGS = [ |
| 27 | + `ShowToc = true`, |
| 28 | + `ShowFavorites = false`, |
| 29 | + `DefaultDisplayMode = continuous`, |
| 30 | + `DefaultZoom = fit page`, |
| 31 | + `Scrollbars = windows`, |
| 32 | + `RestoreSession = false`, |
| 33 | + `ShowStartPage = false`, |
| 34 | + `CheckForUpdates = false`, |
| 35 | + ``, |
| 36 | +].join("\n"); |
| 37 | + |
| 38 | +export async function testit(): Promise<void> { |
| 39 | + if (!existsSync(TOC_PDF)) { |
| 40 | + console.log(` SKIP: TOC test PDF not found: ${TOC_PDF}`); |
| 41 | + return; |
| 42 | + } |
| 43 | + |
| 44 | + // copy the PDF out of OneDrive to a local path -- opening a cloud-backed file |
| 45 | + // can block/delay window creation (hydration), which breaks the automation |
| 46 | + const pdf = tmpPath("issue-1998.pdf"); |
| 47 | + copyFileSync(TOC_PDF, pdf); |
| 48 | + |
| 49 | + const appdata = tmpPath("issue-1998-appdata"); |
| 50 | + rmSync(appdata, { recursive: true, force: true }); |
| 51 | + mkdirSync(appdata, { recursive: true }); |
| 52 | + writeFileSync(join(appdata, "SumatraPDF-settings.txt"), SETTINGS); |
| 53 | + |
| 54 | + const ps1 = join(ROOT, "tests", "issue-1998.verify.ps1"); |
| 55 | + const r = spawnSync( |
| 56 | + "powershell.exe", |
| 57 | + ["-NoProfile", "-ExecutionPolicy", "Bypass", "-File", ps1, "-Exe", EXE, "-Pdf", pdf, "-AppData", appdata], |
| 58 | + { encoding: "utf8", timeout: 90_000 }, |
| 59 | + ); |
| 60 | + const out = (r.stdout || "") + (r.stderr || ""); |
| 61 | + const m = out.match(/RESULT collapsed=(\d+) after=(\d+) hasSelection=(\d+)/); |
| 62 | + if (!m) { |
| 63 | + throw new Error(`could not read TOC tree state; output:\n${out}`); |
| 64 | + } |
| 65 | + const collapsed = parseInt(m[1], 10); |
| 66 | + const after = parseInt(m[2], 10); |
| 67 | + const hasSelection = m[3] === "1"; |
| 68 | + console.log(` collapsed rows=${collapsed}, after-expand rows=${after}, hasSelection=${hasSelection}`); |
| 69 | + |
| 70 | + if (collapsed <= 0) { |
| 71 | + throw new Error(`baseline collapsed tree has no rows (${collapsed}) -- test setup wrong`); |
| 72 | + } |
| 73 | + if (!hasSelection) { |
| 74 | + throw new Error(`CmdExpandToCurrentPage did not select a TOC entry`); |
| 75 | + } |
| 76 | + if (after <= collapsed) { |
| 77 | + throw new Error( |
| 78 | + `CmdExpandToCurrentPage did not expand the tree to the current page ` + |
| 79 | + `(visible rows ${collapsed} -> ${after}; expected an increase)`, |
| 80 | + ); |
| 81 | + } |
| 82 | + console.log(` expanded TOC to current page: ${collapsed} -> ${after} visible rows ✓`); |
| 83 | +} |
| 84 | + |
| 85 | +if (import.meta.main) { |
| 86 | + const { runStandalone } = await import("./util"); |
| 87 | + await runStandalone(testit); |
| 88 | +} |
0 commit comments