Files
verstack/tests/ui-spectrogram-workers.mjs
Verstack Local f73167de85 Add downloadable VMs and improve catalog processing
Package Apple Silicon VM exports and cached runtime switching with local cabinet controls and conagent provisioning. Preserve experimental SPIKE 2 emulation.

Improve preparation concurrency, Ghidra checkpoints, signature importing, sound indexing and client-side spectrograms. Include regression tests and validation notes.
2026-09-14 20:03:59 -05:00

36 lines
3.1 KiB
JavaScript

import {createRequire} from 'node:module';
import {readFile} from 'node:fs/promises';
import assert from 'node:assert/strict';
const require=createRequire(import.meta.url),{chromium}=require('/tmp/verstack-browser-check/node_modules/playwright');
const browser=await chromium.launch({executablePath:'/home/jordan/.cache/ms-playwright/chromium-1243/chrome-linux64/chrome',headless:true,args:['--no-sandbox']});
const context=await browser.newContext(),page=await context.newPage();
const b=Buffer.alloc(44+8192);b.write('RIFF');b.writeUInt32LE(b.length-8,4);b.write('WAVEfmt ',8);b.writeUInt32LE(16,16);b.writeUInt16LE(1,20);b.writeUInt16LE(1,22);b.writeUInt32LE(8192,24);b.writeUInt32LE(16384,28);b.writeUInt16LE(2,32);b.writeUInt16LE(16,34);b.write('data',36);b.writeUInt32LE(8192,40);for(let i=0;i<4096;i++)b.writeInt16LE(Math.round(16000*Math.sin(2*Math.PI*i/8)),44+i*2);
let release;const gate=new Promise(resolve=>release=resolve),requests=[];
await context.route('http://spectrum.test/**',async route=>{
const url=route.request().url();if(url.endsWith('/'))return route.fulfill({contentType:'text/html',body:'<p>Worker test</p>'});
requests.push(url);if(url.includes('slow'))await gate;
await route.fulfill({contentType:'audio/wav',body:b}).catch(()=>{});
});
try{
await page.goto('http://spectrum.test/');
const spectrum=await readFile('workbench/stern-catalog/lib/browser/sound-spectrum.js','utf8'),loader=await readFile('workbench/stern-catalog/lib/browser/spectrogram-loader.js','utf8');
await page.evaluate(({spectrum,loader})=>{
const decoded={};new Function('exports',spectrum)(decoded);const loaded={};new Function('require','exports',loader)(()=>decoded,loaded);window.loadSpectrum=loaded.loadSpectrum;
window.outcomes={};window.controls=[];window.ticks=0;setInterval(()=>window.ticks++,10);
const start=(url,key)=>{const c=new AbortController();window.controls.push(c);window.loadSpectrum(url,c.signal).then(r=>window.outcomes[key]={duration:r.duration,nonblack:r.pixels.some((v,i)=>i%4!==3&&v>0)},e=>window.outcomes[key]={error:e.name});};
window.start=start;window.limit=Math.min(4,Math.max(2,navigator.hardwareConcurrency||2));
for(let i=0;i<window.limit;i++)start('/slow-'+i+'.wav','slow'+i);
start('/fast.wav','fast');start('/never.wav','never');window.controls[window.limit+1].abort();
},{spectrum,loader});
await page.waitForFunction(()=>window.outcomes.never?.error==='AbortError');
const limit=await page.evaluate(()=>window.limit);
for(let i=0;i<100&&requests.length<limit;i++)await page.waitForTimeout(20);
assert.equal(requests.length,limit);assert(requests.every(u=>u.includes('slow')));
await page.evaluate(()=>window.controls[0].abort());
await page.waitForFunction(()=>window.outcomes.fast?.duration===.5,{},{timeout:10000});
assert(await page.evaluate(()=>window.outcomes.fast.nonblack));assert(await page.evaluate(()=>window.ticks>2));
assert(!requests.some(u=>u.includes('never')));
await page.evaluate(()=>window.controls.forEach(c=>c.abort()));
console.log('PASS bounded concurrent worker downloads, no head-of-line blocking after cancellation, queued cancellation, real FFT pixels, main-thread responsiveness');
}finally{release();await browser.close();}