tricu

An interpreted language for exploring Tree Calculus
Log | Files | Refs | README | LICENSE

backend-webkit.mjs (3367B)


      1 // Exercise the built site with Linux WebKit.
      2 import assert from 'node:assert/strict';
      3 import {writeFile,mkdtemp,rm} from 'node:fs/promises';
      4 import {tmpdir} from 'node:os';
      5 import {join} from 'node:path';
      6 import {startSiteServer} from './backend-server.mjs';
      7 const {webkit}=await import(process.env.PLAYWRIGHT_MODULE);
      8 const {server,url,completion}=await startSiteServer(process.argv[2]||'unused',true);
      9 const profile=await mkdtemp(join(tmpdir(),'tricu-webkit-'));
     10 let browser,timer;
     11 try {
     12  // Match the other browser harnesses: a fresh disk-backed profile per run.
     13  browser=await webkit.launchPersistentContext(profile,{headless:true,viewport:{width:1280,height:900}});
     14  const page=await browser.newPage(),errors=[];
     15  page.on('pageerror',e=>errors.push(String(e)));
     16  await page.goto(url);
     17  const report=await Promise.race([completion,new Promise((_,reject)=>{timer=setTimeout(()=>reject(Error('WebKit probe timeout')),240000);})]);
     18  assert.deepEqual(errors,[]);
     19  if(process.env.TEST_IMPORT_PICKER){
     20   await page.click('#add-import');
     21   await page.waitForFunction(()=>document.querySelector('#import-results button'));
     22   for(let i=0;i<8;i++){await page.keyboard.press('Tab');assert(await page.evaluate(()=>document.querySelector('#import-dialog').contains(document.activeElement)),'Dialog contains keyboard focus');}
     23   await page.keyboard.press('Escape');
     24   assert(await page.evaluate(()=>!document.querySelector('#import-dialog').open&&document.activeElement.id==='add-import'),'Escape restores focus');
     25   await page.click('#add-import');
     26   await page.getByRole('button',{name:/^native-math ยท/}).click();
     27  }
     28  for(const width of [320,390,1280]){
     29   await page.setViewportSize({width,height:844});
     30   // Let ResizeObserver update the textarea's decorative mirror geometry.
     31   await page.evaluate(()=>new Promise(resolve=>requestAnimationFrame(()=>requestAnimationFrame(resolve))));
     32   if(process.env.TEST_IMPORT_PICKER)assert(await page.evaluate(()=>{
     33    const content=document.querySelector('#import-content').getBoundingClientRect();
     34    return ['import-cancel','insert-import','import-alias','import-preview'].every(id=>{
     35     const r=document.getElementById(id).getBoundingClientRect();
     36     return r.top>=0&&r.bottom<=innerHeight&&(id==='import-cancel'||id==='insert-import'||r.top>=content.top&&r.bottom<=content.bottom);
     37    });
     38   }),'Import controls and preview visible at '+width);
     39   const overflow=await page.evaluate(()=>document.documentElement.scrollWidth>innerWidth ? [...document.querySelectorAll('body *')].filter(e=>{const r=e.getBoundingClientRect();return r.width&&r.right>innerWidth+1;}).map(e=>({tag:e.tagName,id:e.id,class:e.className,width:e.getBoundingClientRect().width,text:e.textContent.slice(0,100)})) : []);
     40   assert.deepEqual(overflow,[],'Viewport overflow at '+width);
     41   if(process.env.SCREENSHOT){await page.evaluate(()=>scrollTo({top:0,behavior:'instant'}));await page.screenshot({path:process.env.SCREENSHOT.replace(/\.png$/, '-'+width+'.png')});}
     42  }
     43  report.engine='Linux WebKit';
     44  if(process.env.BENCHMARK_REPORT)await writeFile(process.env.BENCHMARK_REPORT,JSON.stringify(report,null,2)+'\n');
     45 
     46  console.log('PASS '+report.engine+': '+report.checks.join(' / '));
     47 } finally {
     48  clearTimeout(timer);await browser?.close();server.closeAllConnections();await new Promise(r=>server.close(r));
     49  await rm(profile,{recursive:true,force:true});
     50 }