File size: 1,866 Bytes
a0ebf39
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import { chromium, type Browser, type Page } from '@playwright/test';
import type { PPTElement } from '@/lib/types/slides';
import { mkdirSync } from 'fs';
import { join } from 'path';

const VIEWPORT = { width: 1000, height: 563 };

let browser: Browser | null = null;
let page: Page | null = null;

/**
 * Initialize Playwright browser (reused across captures).
 */
export async function initCapture(baseUrl: string): Promise<void> {
  browser = await chromium.launch({ headless: true });
  const context = await browser.newContext({ viewport: VIEWPORT });
  page = await context.newPage();

  await page.goto(`${baseUrl}/eval/whiteboard`);
  // Wait for the page to signal readiness
  await page.waitForFunction(
    () => (window as unknown as Record<string, unknown>).__evalReady === true,
  );
}

/**
 * Capture a screenshot of the whiteboard with the given elements.
 * Returns the path to the saved screenshot.
 */
export async function captureWhiteboard(
  elements: PPTElement[],
  outputDir: string,
  filename: string,
): Promise<string> {
  if (!page) throw new Error('Capture not initialized. Call initCapture() first.');

  // Inject elements into the page
  await page.evaluate(
    (els: unknown[]) => {
      const setter = (window as unknown as Record<string, (els: unknown[]) => void>).__setElements;
      setter(els);
    },
    elements as unknown as unknown[],
  );

  // Wait for rendering to stabilize (fonts, KaTeX, images)
  await page.waitForTimeout(1500);

  mkdirSync(outputDir, { recursive: true });
  const filepath = join(outputDir, filename);

  await page.screenshot({ path: filepath, clip: { x: 0, y: 0, width: 1000, height: 563 } });

  return filepath;
}

/**
 * Close the browser.
 */
export async function closeCapture(): Promise<void> {
  if (browser) {
    await browser.close();
    browser = null;
    page = null;
  }
}