1import { describe, expect, it } from 'vitest'2import { browserHarness, createPageExecutor } from '../src/executor'34describe('browser page executor', () => {5 it('posts the renderer protocol message and accepts the matching result', async () => {6 const listeners = new Set<(event: MessageEvent) => void>()7 const fakeWindow = {8 addEventListener: (_type: string, listener: (event: MessageEvent) => void) => listeners.add(listener),9 removeEventListener: (_type: string, listener: (event: MessageEvent) => void) => listeners.delete(listener),10 postMessage: (data: unknown) => queueMicrotask(() => listeners.forEach(listener => listener({ source: globalThis, data: { channel: 'diagram.zip:renderer:v1', type: 'result', requestId: (data as any).requestId, ok: true, svg: '<svg/>', version: 'v', build: 'b', pipeline: ['mermaid'] } } as unknown as MessageEvent))),11 }12 const oldMethods = { addEventListener: (globalThis as any).addEventListener, removeEventListener: (globalThis as any).removeEventListener, postMessage: (globalThis as any).postMessage }13 Object.assign(globalThis, fakeWindow)14 await expect(browserHarness({ engine: 'mermaid', requestId: 'r', source: 'graph TD' })).resolves.toMatchObject({ ok: true, svg: '<svg/>' })15 Object.assign(globalThis, oldMethods)16 })1718 it('navigates only to the pinned frame and returns the protocol result', async () => {19 const navigated: string[] = []20 const page = {21 async goto(url: string) { navigated.push(url) },22 async evaluate<T>(_fn: unknown, payload: any): Promise<T> {23 return { ok: true, svg: '<svg />', version: 'test', build: 'test', pipeline: [payload.engine] } as T24 },25 }26 const result = await createPageExecutor(page).render({ engine: 'mermaid', requestId: 'r', source: 'graph TD' })27 expect(result.ok).toBe(true)28 expect(navigated).toEqual(['https://mermaid.render.diagram.zip/index.html?v=2'])29 })3031 it('rejects output above the hard limit', async () => {32 const page = {33 async goto() {},34 async evaluate<T>(): Promise<T> { return { ok: true, svg: 'x'.repeat(4_194_305), version: 'v', build: 'b', pipeline: [] } as T },35 }36 await expect(createPageExecutor(page).render({ engine: 'mermaid', requestId: 'r', source: '' })).rejects.toThrow(/output is too large/)37 })38})