LazyBoy2/tests/desktop_memory_ui.mjs

48 lines
2.5 KiB
JavaScript
Raw Normal View History

2026-09-16 08:17:38 +00:00
// Opt-in live desktop soak test: opens the UI, sends no chat/model requests.
import { chromium } from '../tools/playwright/node_modules/playwright/index.mjs';
import assert from 'node:assert/strict';
import { execFileSync } from 'node:child_process';
const browser=await chromium.launch({headless:true});
try {
const page=await browser.newPage({viewport:{width:1440,height:900}});
const errors=[];page.on('pageerror',e=>errors.push(e.message));
await page.goto(process.env.LAZYBOY_TEST_UI_URL || 'http://127.0.0.1:8787');
const iframe=page.locator('iframe.desktop-frame');
await iframe.waitFor({timeout:60000});
const frame=await (await iframe.elementHandle()).contentFrame();
await frame.waitForSelector('canvas',{timeout:30000});
const connected=()=>frame.evaluate(async()=>{
const {default:ui}=await import(new URL('./app/ui.js',location.href).href);
return ui.rfb?._rfbConnectionState;
});
await frame.waitForFunction(async()=>{
const {default:ui}=await import(new URL('./app/ui.js',location.href).href);
return ui.rfb?._rfbConnectionState==='connected';
}, undefined, {timeout:30000});
const cdp=await page.context().newCDPSession(page);
const browserCdp=await browser.newBrowserCDPSession();
const measure=async()=>{
const heap=await cdp.send('Runtime.getHeapUsage');
const dom=await cdp.send('Memory.getDOMCounters');
const {processInfo}=await browserCdp.send('SystemInfo.getProcessInfo');
const rss=execFileSync('ps',['-o','rss=','-p',processInfo.map(p=>p.id).join(',')],{encoding:'utf8'}).trim().split(/\s+/).reduce((sum,n)=>sum+Number(n),0);
return {heapMiB:heap.usedSize/1024/1024,rssMiB:rss/1024,nodes:dom.nodes,listeners:dom.jsEventListeners};
};
await cdp.send('HeapProfiler.collectGarbage');
const initial=await measure();
console.log('desktop initial',JSON.stringify(initial));
for(let i=0;i<Number(process.env.LAZYBOY_SOAK_SAMPLES || 6);i++) {
await page.waitForTimeout(10000);
assert.equal(await connected(),'connected');
console.log(`desktop ${10*(i+1)}s`,JSON.stringify(await measure()));
}
await cdp.send('HeapProfiler.collectGarbage');
const final=await measure();
assert.ok(final.heapMiB-initial.heapMiB<24,'retained heap grew by more than 24 MiB');
assert.ok(final.rssMiB-initial.rssMiB<128,'browser RSS grew by more than 128 MiB');
assert.ok(final.nodes-initial.nodes<500,'DOM nodes accumulated');
assert.ok(final.listeners-initial.listeners<100,'listeners accumulated');
assert.deepEqual(errors,[]);
console.log('PASS live desktop soak',JSON.stringify({initial,final}));
} finally {await browser.close();}