import assert from 'node:assert/strict' import fs from 'node:fs/promises' import path from 'node:path' import { tmpdir } from 'node:os' import { pathToFileURL } from 'node:url' const runtime = path.resolve('.tmp/rea-css-runtime/dist') const { inspectCdpElectronPage } = await import(pathToFileURL(path.join(runtime, 'browser/CdpElectronInspection.js'))) const { inspectElectronPageInputSchema, electronPageInspectionSchema } = await import(pathToFileURL(path.join(runtime, 'domain/javascript/electronObservation.js'))) const { createElectronEvidence } = await import(pathToFileURL(path.join(runtime, 'application/javascript/ElectronEvidence.js'))) const fixture = await fs.mkdtemp(path.join(tmpdir(), 'rea-visual-fixture-')) try { const html = path.join(fixture, 'index.html') await fs.writeFile(html, '
Own fixture
') const frame = { id: 'own-frame', url: pathToFileURL(html).href } const png = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+jKXcAAAAASUVORK5CYII=' let listener, mode = 'normal' const calls = [] const connection = { onEvent(fn) { listener = fn; return () => { listener = undefined } }, async send(method, params, sessionId) { calls.push(method) if (method === 'SystemInfo.getInfo') { assert.equal(sessionId, undefined, 'SystemInfo must use the browser connection') return { commandLine: 'private-command', gpu: { devices: [{ vendorId: 1, deviceId: 2, deviceString: 'Fixture GPU', active: true }], auxAttributes: { inProcessGpu: false, glImplementationParts: '(gl=egl-angle,angle=swiftshader)', privateValue: 'private-gpu-value' }, featureStatus: { gpu_compositing: 'disabled_software' } } } } if (method === 'Page.getFrameTree') return { frameTree: { frame: mode === 'foreign' ? { ...frame, url: 'https://example.com' } : frame } } if (method === 'Page.getResourceTree') return { frameTree: { frame, resources: [] } } if (method === 'Target.getTargets') return { targetInfos: [] } if (method === 'Page.getLayoutMetrics') return { cssLayoutViewport: { clientWidth: 100, clientHeight: 80, pageX: 0, pageY: 0 } } if (method === 'DOMSnapshot.captureSnapshot') return { strings: [frame.url, frame.id, 'DIV', 'class', 'fixture', 'value', 'sensitive-input', 'foreign-frame', '15px', 'svg', 'path', 'd', 'M0 0L1 1', 'onclick', 'bad-action', 'href', 'https://example.invalid'], documents: [ { documentURL: 0, frameId: 1, nodes: { nodeName: [2,9,10], parentIndex: [-1,0,1], attributes: [[3,4,5,6],[13,14,15,16],[11,12,5,6]] }, layout: { nodeIndex: [0], bounds: [[10,20,30,40]], styles: [params.computedStyles.map(() => 8)] } }, { documentURL: 0, frameId: 7, nodes: {}, layout: {} } ] } if (method === 'Page.captureScreenshot') { if (mode === 'navigation') listener({ sessionId, method: 'Page.frameNavigated', params: { frame } }) return { data: mode === 'bad-png' ? 'AAAA' : png } } return {} } } const input = inspectElectronPageInputSchema.parse({ cdp_endpoint: 'http://127.0.0.1:9223', target_id: 'fixture', observation_ms: 0, include_visuals: true }) const context = { connection, sessionId: 'fixture-session', input, target: { id: 'fixture', type: 'page', title: 'Fixture', attached: false }, discovery: { version: { product: 'Fixture/1', protocol_version: '1.3', revision: 'fixture', user_agent: 'fixture', js_version: 'fixture' } } } const result = electronPageInspectionSchema.parse(await inspectCdpElectronPage(context)) assert.deepEqual(result.visuals.viewport, { width: 1, height: 1 }) assert.equal(result.visuals.css_viewport.width, 100) assert.equal(result.visuals.layout.documents.length, 1) assert.deepEqual(result.visuals.layout.documents[0].nodes[0].attributes, { class: 'fixture' }) assert.equal(result.visuals.layout.documents[0].nodes[0].styles['font-size'], '15px') assert.ok(!JSON.stringify(result.visuals).includes('sensitive-input')) assert.equal(result.visuals.layout.documents[0].svg_nodes.length, 2) assert.deepEqual(result.visuals.layout.documents[0].svg_nodes[1].attributes, { d: 'M0 0L1 1' }) assert.ok(!JSON.stringify(result.visuals).includes('bad-action')) assert.ok(!JSON.stringify(result.visuals).includes('example.invalid')) const evidence = createElectronEvidence('inspect_electron_page', input, result, { id: 'rea-cdp-electron', name: 'Local fixture', version: '1+visual-local.1' }) assert.equal(evidence.parameters.include_visuals, true) assert.equal(evidence.normalized_result.visuals.artifact.data_base64, png) const fontInput = inspectElectronPageInputSchema.parse({ ...input, visual_probe: { include_fonts: true, actions: [] } }) const withGpu = electronPageInspectionSchema.parse(await inspectCdpElectronPage({ ...context, input: fontInput })) assert.equal(withGpu.visuals.environment_gpu.status, 'observed') assert.equal(withGpu.visuals.environment_gpu.devices[0].device_string, 'Fixture GPU') assert.equal(withGpu.visuals.environment_gpu.feature_status.gpu_compositing, 'disabled_software') assert.ok(!JSON.stringify(withGpu).includes('private-command')) assert.ok(!JSON.stringify(withGpu).includes('private-gpu-value')) calls.length = 0 await inspectCdpElectronPage({ ...context, input: { ...input, include_visuals: false } }) assert.ok(!calls.includes('Page.captureScreenshot')) assert.ok(!calls.includes('Page.getLayoutMetrics')) assert.ok(!calls.includes('SystemInfo.getInfo')) mode = 'bad-png' await assert.rejects(inspectCdpElectronPage(context)) mode = 'navigation' await assert.rejects(inspectCdpElectronPage(context), error => error.reason === 'target_changed') mode = 'foreign'; calls.length = 0 await assert.rejects(inspectCdpElectronPage(context)) assert.ok(!calls.includes('Page.captureScreenshot')) assert.ok(!calls.includes('Runtime.evaluate')) assert.equal(listener, undefined) console.log('REA visual capture passed: PNG/schema/Evidence/layout, attribute filtering, frame scope, opt-out, malformed PNG, navigation rejection, cleanup') } finally { await fs.rm(fixture, { recursive: true, force: true }) }