/** Offline VM contracts only: no Electron, browser, layout or native input is executed. */ import assert from 'node:assert/strict' import fs from 'node:fs' import path from 'node:path' import vm from 'node:vm' import test from 'node:test' const source = fs.readFileSync(new URL('./verify-b04-image-native.cjs', import.meta.url), 'utf8') const flush = async () => { for (let i = 0; i < 12; i++) await Promise.resolve() } const deferred = () => { let resolve, reject; const promise = new Promise((a, b) => { resolve = a; reject = b }); return { promise, resolve, reject } } const validReport = () => ({ samples: [{ height: 232, textLength: 35, imageHeight: 180 }], errors: [] }) function harness({ report = validReport(), holdReady = false, holdLoad = false, holdFrames = false, frameError } = {}) { const ready = deferred(), load = deferred(), frames = deferred() const state = { writes: [], exits: [], events: {}, timers: new Map(), windows: [], logs: [] } let id = 0 const app = { setPath: (key, value) => { state.profile = { key, value } }, whenReady: () => ready.promise, exit: code => state.exits.push(code) } class BrowserWindow { constructor(options) { state.windows.push(options); state.window = this; this.destroyed = false this.webContents = { on: (name, callback) => { state.events[name] = callback }, executeJavaScript: async code => { state.rendererCode = code if (frameError) throw Error(frameError) if (holdFrames) return frames.promise return report } } } loadFile(file) { state.loaded = file; return holdLoad ? load.promise : Promise.resolve() } isDestroyed() { return this.destroyed } destroy() { this.destroyed = true } } const modules = { electron: { app, BrowserWindow, session: { defaultSession: { webRequest: { onBeforeRequest: callback => { state.network = callback } } } } }, 'node:path': path, 'node:os': { tmpdir: () => '/mock-temp' }, 'node:fs': { existsSync: () => true, mkdtempSync: prefix => prefix + 'isolated', writeFileSync: (file, body) => state.writes.push({ file, report: JSON.parse(body) }) } } vm.runInNewContext(source, { require: name => { assert.ok(name in modules); return modules[name] }, process: { argv: ['electron', 'probe.cjs', '/mock-fixture'] }, console: { log: value => state.logs.push(value) }, setTimeout: (callback, delay) => { state.timers.set(++id, { callback, delay }); return id }, clearTimeout: key => state.timers.delete(key) }) if (!holdReady) ready.resolve() return { state, ready, load, frames, expire: () => { const timer = [...state.timers.values()][0]; assert.equal(timer.delay, 20000); timer.callback() } } } function result(h, status, pattern) { assert.equal(h.state.writes.length, 1) const report = h.state.writes[0].report assert.equal(report.result, status) assert.deepEqual(h.state.exits, [status === 'PASS' ? 0 : 1]) if (pattern) assert.match(report.error, pattern) assert.match(report.limits, /not the installed application/) assert.equal(h.state.timers.size, 0) return report } test('B04 mock host preserves security, frame scheduling, deadline and report', async () => { const h = harness(); await flush() const report = result(h, 'PASS') assert.equal(report.phase, 'checking-native-report') const options = h.state.windows[0] assert.equal(options.show, true) assert.equal(options.webPreferences.backgroundThrottling, false) assert.equal(options.webPreferences.sandbox, true) assert.equal(options.webPreferences.contextIsolation, true) assert.equal(options.webPreferences.nodeIntegration, false) assert.equal(h.state.profile.key, 'userData') assert.match(h.state.profile.value, /ycode-b04-native-/) assert.equal(h.state.window.destroyed, true) for (const [url, cancel] of [['https://example.invalid/image', true], ['file:///fixture.js', false], ['data:image/png;base64,AA', false], ['blob:local', false]]) { let actual; h.state.network({ url }, value => { actual = value.cancel }); assert.equal(actual, cancel) } assert.match(h.state.rendererCode, /window\.__b04Error/) assert.match(h.state.rendererCode, /window\.__b04Report/) }) for (const [label, report, message] of [ ['zero layout', { samples: [{ height: 0, textLength: 0 }] }, /No nonzero/], ['large text', { samples: [{ height: 232, textLength: 1001 }] }, /text\/height spike/], ['large layout', { samples: [{ height: 2001, textLength: 35 }] }, /text\/height spike/], ['missing samples', {}, /some|samples/] ]) test(`B04 mock rejects ${label}`, async () => { const h = harness({ report }); await flush(); result(h, 'FAIL', message) }) test('B04 mock propagates fixture rejection', async () => { const h = harness({ frameError: 'synthetic no URI text assertion' }); await flush(); result(h, 'FAIL', /no URI text assertion/) }) for (const [option, phase] of [['holdReady', 'waiting-for-app'], ['holdLoad', 'loading-fixture'], ['holdFrames', 'waiting-for-native-frames']]) { test(`B04 mock deadline covers ${phase}`, async () => { const h = harness({ [option]: true }); await flush(); h.expire() const report = result(h, 'FAIL', /timed out after 20s/); assert.equal(report.phase, phase) if (option === 'holdReady') h.ready.resolve() if (option === 'holdLoad') h.load.resolve() if (option === 'holdFrames') h.frames.resolve(validReport()) await flush(); assert.equal(h.state.writes.length, 1) if (option === 'holdReady') assert.equal(h.state.windows.length, 0) }) } for (const [event, args, message] of [ ['render-process-gone', [{}, { reason: 'crashed' }], /Renderer gone: crashed/], ['did-fail-load', [{}, -6, 'FILE_NOT_FOUND'], /Page load failed: -6 FILE_NOT_FOUND/] ]) test(`B04 mock records ${event} once`, async () => { const h = harness({ holdLoad: true }); await flush(); h.state.events[event](...args); h.load.reject(Error('later rejection')); await flush(); result(h, 'FAIL', message) }) test('B04 mock fails renderer console errors', async () => { const h = harness({ holdFrames: true }); await flush() h.state.events['console-message']({ level: 'error', message: 'synthetic renderer error' }) h.frames.resolve(validReport()); await flush(); result(h, 'FAIL', /synthetic renderer error/) }) test('B04 fixture retains real rAF sampling and decode assertions (source contract only)', () => { const fixture = fs.readFileSync(new URL('./b04-image-lifecycle-fixture.tsx', import.meta.url), 'utf8') assert.match(fixture, /requestAnimationFrame\(\(\) => \{sample\(/) assert.match(fixture, /await folds\(true\)/) assert.match(fixture, /naturalWidth === 320/) assert.match(fixture, /imageHeight > 0/) assert.match(fixture, /no URI text/) }) for (const scenario of ['success', 'fixture-error', 'pending']) test(`B04 renderer polling contract: ${scenario} (mock window)`, async () => { const h = harness(); await flush() const report = validReport(), window = {}, timers = [] if (scenario === 'success') window.__b04Report = report if (scenario === 'fixture-error') { window.__b04Error = 'synthetic fixture assertion'; window.__b04Report = report } const promise = vm.runInNewContext(h.state.rendererCode, { window, setTimeout: (callback, delay) => timers.push({ callback, delay }) }) if (scenario === 'fixture-error') await assert.rejects(promise, /synthetic fixture assertion/) else { if (scenario === 'pending') { assert.equal(timers.length, 1); assert.equal(timers[0].delay, 25) window.__b04Report = report; timers[0].callback() } assert.equal(await promise, report) } })