gui/tmp_verify_chat_stream.cjs
Rama master · réplica de lectura del repositorio original.
const path = require('path');
const { app, BrowserWindow, ipcMain } = require('electron');
const guiDir = process.cwd();
app.setAppPath(guiDir);
require(path.join(guiDir, 'dist-electron', 'main', 'index.js'));
const streamTokens = ['Alpha', ' Beta', ' Gamma'];
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
function registerDeterministicAppHandlers() {
ipcMain.removeHandler('rex:getSetupStatus');
ipcMain.handle('rex:getSetupStatus', async () => ({ ok: true, needs_setup: false }));
ipcMain.removeHandler('rex:getStatus');
ipcMain.handle('rex:getStatus', async () => ({ ok: true, status: 'ready' }));
ipcMain.removeHandler('rex:startChatStream');
ipcMain.handle('rex:startChatStream', async (event, { message, streamId }) => {
process.stdout.write(JSON.stringify({ handler: 'rex:startChatStream', message }) + '\n');
for (const token of streamTokens) {
await sleep(240);
event.sender.send('rex:chatToken', { streamId, token });
}
event.sender.send('rex:chatDone', { streamId });
return { ok: true };
});
}
async function waitForWindow() {
for (let attempt = 0; attempt < 100; attempt += 1) {
const win = BrowserWindow.getAllWindows()[0];
if (win && !win.isDestroyed()) {
return win;
}
await sleep(200);
}
throw new Error('Timed out waiting for Electron window');
}
app.whenReady().then(async () => {
let ok = false;
try {
const win = await waitForWindow();
registerDeterministicAppHandlers();
await win.reload();
await sleep(1500);
const result = await win.webContents.executeJavaScript(`
(async () => {
const prompt = 'Smoke test message';
const tokens = ${JSON.stringify(streamTokens)};
const finalReply = tokens.join('');
window.location.hash = '#/chat';
await new Promise((resolve) => setTimeout(resolve, 700));
window.__chatVerify = {
partialSnapshots: [],
finalReply,
preloadStreamApiAvailable: typeof window.rex.sendChatStream === 'function'
};
if (!window.__chatVerify.preloadStreamApiAvailable) {
throw new Error('Preload sendChatStream API is unavailable');
}
const textarea = document.querySelector('textarea[aria-label="Chat message input"]');
if (!textarea) {
throw new Error('Could not find chat textarea');
}
const nativeSetter = Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, 'value')?.set;
if (!nativeSetter) {
throw new Error('Could not resolve textarea value setter');
}
nativeSetter.call(textarea, prompt);
textarea.dispatchEvent(new Event('input', { bubbles: true }));
const sendButton = document.querySelector('button[aria-label="Send message"]');
if (!sendButton) {
throw new Error('Could not find send button');
}
for (let attempt = 0; attempt < 20 && sendButton.disabled; attempt += 1) {
await new Promise((resolve) => setTimeout(resolve, 50));
}
if (sendButton.disabled) {
throw new Error('Send button did not enable after entering a message');
}
sendButton.click();
let sawUserMessage = false;
let sawFinal = false;
let lastText = '';
for (let attempt = 0; attempt < 60; attempt += 1) {
await new Promise((resolve) => setTimeout(resolve, 120));
lastText = document.body.innerText;
window.__chatVerify.partialSnapshots.push(lastText);
if (lastText.includes(prompt)) sawUserMessage = true;
if (lastText.includes(finalReply)) {
sawFinal = true;
break;
}
}
const partialSnapshots = window.__chatVerify?.partialSnapshots || [];
const sawFirstPartial = partialSnapshots.some((text) => text.includes('Alpha') && !text.includes(finalReply));
const sawSecondPartial = partialSnapshots.some((text) => text.includes('Alpha Beta') && !text.includes(finalReply));
if (!sawUserMessage) {
throw new Error('User message was not rendered in chat UI');
}
if (!sawFirstPartial || !sawSecondPartial) {
throw new Error(
'Streaming partial reply was not rendered token-by-token: ' + JSON.stringify({
partialSnapshots,
lastText
})
);
}
if (!sawFinal) {
throw new Error('Final streamed reply was not rendered');
}
return {
prompt,
finalReply,
sawUserMessage,
sawFirstPartial,
sawSecondPartial,
sawFinal,
excerpt: lastText.slice(0, 800)
};
})();
`, true);
process.stdout.write(JSON.stringify({ ok: true, result }) + '\n');
ok = true;
} catch (error) {
process.stdout.write(JSON.stringify({ ok: false, error: String(error) }) + '\n');
} finally {
setTimeout(() => app.quit(), 500);
if (!ok) {
process.exitCode = 1;
}
}
});