backend-firefox.mjs (2364B)
1 import {writeFile} from 'node:fs/promises'; 2 import {sampleBrowser} from './browser-memory.mjs'; 3 import {spawn} from 'node:child_process'; 4 import {mkdtemp,rm} from 'node:fs/promises'; 5 import {tmpdir} from 'node:os'; 6 import {resolve} from 'node:path'; 7 import {startSiteServer} from './backend-server.mjs'; 8 const {server,url,completion,marks}=await startSiteServer(process.argv[2],true); 9 const profile=await mkdtemp(resolve(tmpdir(),'tricu-site-firefox-')); 10 let browser,timer,stopMemory; 11 try { 12 // --profile does not isolate Firefox's global Crash Reports directory. 13 // Keep all test state under the temporary root and disable external crash 14 // reporting, not browser failure detection (exit/stderr/probe timeout below). 15 const env={...process.env,HOME:profile,XDG_CONFIG_HOME:resolve(profile,'config'), 16 XDG_CACHE_HOME:resolve(profile,'cache'),XDG_DATA_HOME:resolve(profile,'data'),MOZ_CRASHREPORTER_DISABLE:'1',GSETTINGS_BACKEND:'memory'}; 17 browser=spawn(process.argv[3]||'firefox',['--headless','--no-remote','--new-instance','--profile',profile,url],{stdio:['ignore','ignore','pipe'],detached:true,env}); 18 if(process.env.TEST_BENCHMARK)stopMemory=sampleBrowser(browser.pid,marks); 19 let log='';browser.stderr.on('data',b=>{log=(log+b).slice(-16000);process.stderr.write(b);}); 20 const failure=new Promise((_,reject)=>{ 21 browser.on('error',reject);browser.on('exit',code=>reject(Error('Firefox exited '+code+'\n'+log))); 22 timer=setTimeout(()=>reject(Error('Site backend test timed out\n'+log)),180000); 23 }); 24 const report=await Promise.race([completion,failure]); 25 if(stopMemory){report.browserMemory=await stopMemory(marks);stopMemory=undefined;} 26 if(process.env.BENCHMARK_REPORT)await writeFile(process.env.BENCHMARK_REPORT,JSON.stringify(report,null,2)+'\n'); 27 if(report.parity)console.log(JSON.stringify(report.parity)); 28 console.log('PASS actual site '+report.userAgent+': '+report.checks.join(' / ')); 29 } finally { 30 if(stopMemory)await stopMemory(marks); 31 clearTimeout(timer); 32 if(browser?.pid){const exited=browser.exitCode===null?new Promise(r=>browser.once('exit',r)):Promise.resolve();try{process.kill(-browser.pid,'SIGKILL');}catch(e){if(e.code!=='ESRCH')throw e;}await exited;} 33 server.closeAllConnections();await new Promise(r=>server.close(r)); 34 await rm(profile,{recursive:true,force:true,maxRetries:5,retryDelay:100}); 35 }