68 lines
3.7 KiB
JavaScript
68 lines
3.7 KiB
JavaScript
// Read-only verification of YCode's actual IPC and renderer after an offline import.
|
|
import fs from 'node:fs/promises'
|
|
import assert from 'node:assert/strict'
|
|
|
|
const endpoint = process.argv[2] || 'http://127.0.0.1:9237'
|
|
const copy = JSON.parse(await fs.readFile('.tmp/workbuddy-copy-report.json', 'utf8'))
|
|
assert.equal(copy.applied, true)
|
|
const pause = ms => new Promise(resolve => setTimeout(resolve, ms))
|
|
let targets
|
|
for (let attempt = 0; attempt < 80; attempt++) {
|
|
try { targets = await (await fetch(`${endpoint}/json/list`)).json(); break } catch { await pause(200) }
|
|
}
|
|
const target = targets?.find(value => value.type === 'page' && (value.title === 'YCode' || value.url.includes('/out/renderer/')))
|
|
assert.ok(target, 'YCode renderer must be running')
|
|
const socket = new WebSocket(target.webSocketDebuggerUrl)
|
|
await new Promise((resolve, reject) => { socket.onopen = resolve; socket.onerror = reject })
|
|
let sequence = 0
|
|
const pending = new Map()
|
|
const exceptions = []
|
|
socket.onmessage = event => {
|
|
const message = JSON.parse(event.data)
|
|
if (message.method === 'Runtime.exceptionThrown') exceptions.push(message.params.exceptionDetails.text)
|
|
const request = pending.get(message.id)
|
|
if (request) { pending.delete(message.id); message.error ? request.reject(new Error(message.error.message)) : request.resolve(message.result) }
|
|
}
|
|
const send = (method, params = {}) => new Promise((resolve, reject) => {
|
|
const id = ++sequence
|
|
pending.set(id, { resolve, reject })
|
|
socket.send(JSON.stringify({ id, method, params }))
|
|
})
|
|
await send('Runtime.enable')
|
|
let result
|
|
try {
|
|
for (let attempt = 0; attempt < 80; attempt++) {
|
|
result = await send('Runtime.evaluate', { expression: `(async()=>{
|
|
if(!window.ycode?.session)return null;
|
|
const list=await window.ycode.session.list();
|
|
const session=list.find(item=>item.id===${JSON.stringify(copy.sessionId)});
|
|
if(!session)return null;
|
|
const messages=await window.ycode.session.messages(session.id);
|
|
return {session,sessionCount:list.length,messageCount:messages.length,
|
|
tools:messages.flatMap(message=>message.tools??[]).length,
|
|
images:messages.flatMap(message=>message.attachments??[]).filter(item=>item.previewUrl?.startsWith('data:image/')).length,
|
|
userXmlWrappers:messages.filter(message=>message.role==='user'&&/<user_query>|<system-reminder/.test(message.content)).length,
|
|
streaming:messages.filter(message=>message.status==='streaming').length,
|
|
renderedUserMessages:document.querySelectorAll('.msg--user').length,
|
|
renderedAssistantMessages:document.querySelectorAll('.msg--assistant').length,
|
|
titleVisible:[...document.querySelectorAll('.sidebar__item-title')].some(item=>item.textContent===session.title)}
|
|
})()`, awaitPromise: true, returnByValue: true })
|
|
if (result.result?.value?.titleVisible && result.result.value.renderedUserMessages > 0) break
|
|
if (result.exceptionDetails) throw new Error(result.exceptionDetails.text)
|
|
await pause(250)
|
|
}
|
|
const actual = result.result.value
|
|
assert.equal(actual.messageCount, copy.stats.importedMessages)
|
|
assert.equal(actual.tools, copy.stats.toolCalls)
|
|
assert.equal(actual.images, copy.stats.copiedImages)
|
|
assert.equal(actual.sessionCount, copy.existingSessionCount + 1)
|
|
assert.equal(actual.titleVisible, true)
|
|
assert.equal(actual.userXmlWrappers, 0)
|
|
assert.equal(actual.streaming, 0)
|
|
assert.deepEqual(exceptions, [])
|
|
const image = await send('Page.captureScreenshot', { format: 'png', fromSurface: true })
|
|
await fs.writeFile('.tmp/ycode-workbuddy-copy.png', Buffer.from(image.data, 'base64'))
|
|
await fs.writeFile('.tmp/ycode-workbuddy-copy-ui-report.json', JSON.stringify({ ...actual, exceptions }, null, 2))
|
|
console.log(JSON.stringify({ ...actual, exceptions }))
|
|
} finally { socket.close() }
|