capture.js 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. const fs = require('fs');
  2. const URLS = [
  3. "http://localhost:5287",
  4. "http://localhost:5287/visualise/topology",
  5. "http://localhost:5287/visualise/logical",
  6. "http://localhost:5287/cli",
  7. "http://localhost:5287/yaml",
  8. "http://localhost:5287/hardware/tree",
  9. "http://localhost:5287/servers/list",
  10. "http://localhost:5287/resources/hardware/proxmox-node01",
  11. "http://localhost:5287/systems/list",
  12. "http://localhost:5287/services/list"
  13. ];
  14. function screenshotFilename(url) {
  15. const parsed = new URL(url);
  16. const path = parsed.pathname === "/"
  17. ? ""
  18. : parsed.pathname.replace(/^\/+|\/+$/g, "").replace(/\//g, "_");
  19. const port = parsed.port ? `_${parsed.port}` : "";
  20. const name = `${parsed.hostname}${port}${path ? `_${path}` : ""}`;
  21. return `${name.replace(/[^a-zA-Z0-9._-]/g, "_")}.png`;
  22. }
  23. async function capture() {
  24. const { chromium } = require('playwright');
  25. const browser = await chromium.launch();
  26. const page = await browser.newPage({
  27. viewport: { width: 1366, height: 768 }
  28. });
  29. if (!fs.existsSync("./webui_screenshots"))
  30. fs.mkdirSync("./webui_screenshots");
  31. for (const url of URLS) {
  32. const filename = screenshotFilename(url);
  33. console.log("Capturing", url);
  34. // Diagram routes are taller than the standard viewport; stretch it so
  35. // the GraphView's `h-full` container shows the whole diagram in-frame.
  36. const isVisualise = url.includes("/visualise/");
  37. if (isVisualise) {
  38. await page.setViewportSize({ width: 2400, height: 5000 });
  39. } else {
  40. await page.setViewportSize({ width: 1366, height: 768 });
  41. }
  42. await page.goto(url, {
  43. waitUntil: "networkidle",
  44. timeout: 30000
  45. });
  46. // extra settle time for SPA hydration; Mermaid renders async so the
  47. // visualise routes need a longer window before screenshotting.
  48. await page.waitForTimeout(isVisualise ? 5000 : 2000);
  49. // The visualise route wraps the diagram in an overflow:auto container
  50. // bounded to 75vh — fine for the live UI, but it clips taller diagrams
  51. // in screenshots. For the capture only, expand any ancestor of the SVG
  52. // to its natural height and disable overflow clipping.
  53. if (isVisualise) {
  54. await page.evaluate(() => {
  55. const svg = document.querySelector("[id^='visualise-graph-host'] svg, #visualise-graph-host svg");
  56. if (!svg) return;
  57. let el = svg.parentElement;
  58. while (el && el !== document.body) {
  59. el.style.height = "auto";
  60. el.style.maxHeight = "none";
  61. el.style.overflow = "visible";
  62. el = el.parentElement;
  63. }
  64. });
  65. await page.waitForTimeout(500);
  66. }
  67. await page.screenshot({
  68. path: `webui_screenshots/${filename}`,
  69. fullPage: isVisualise
  70. });
  71. }
  72. await browser.close();
  73. }
  74. if (require.main === module) {
  75. capture().catch(error => {
  76. console.error(error);
  77. process.exitCode = 1;
  78. });
  79. }
  80. module.exports = { capture, screenshotFilename };