← back to CelebritySignatures

scripts/screenrecord-tk10191.mjs

65 lines

import pkg from '/Users/macstudio3/Projects/homesonspec/node_modules/.pnpm/playwright-core@1.61.1/node_modules/playwright-core/index.js'; const { chromium } = pkg;
import fs from 'fs';
const URL='http://localhost:9956/';
const BASE='/Users/macstudio3/Projects/CelebritySignatures/screenrecord';
const LOG=BASE+'/debug-log.jsonl';
const prior = fs.existsSync(LOG)? fs.readFileSync(LOG,'utf8').trim().split('\n').filter(Boolean).map(l=>{try{return JSON.parse(l)}catch{ return {}}}):[];
const priorБad=new Set(prior.filter(r=>r.errors&&r.errors.length).map(r=>r.selector));
const append=o=>fs.appendFileSync(LOG, JSON.stringify(o)+'\n');
const orderFor=(run,els)=>{
  if(run===0)return els;
  if(run===1)return [...els].reverse();
  if(run===2)return [...els].sort((a,b)=>(b.type==='range')-(a.type==='range'));
  if(run===3){const s=[...els];for(let i=s.length-1;i>0;i--){const j=(i*7+run*13)%(i+1);[s[i],s[j]]=[s[j],s[i]];}return s;}
  return [...els].sort((a,b)=>(priorБad.has(b.sel))-(priorБad.has(a.sel)));
};
const allRunErrors=[];
for(let run=0;run<5;run++){
  const browser=await chromium.launch({channel:'chrome',headless:true});
  const ctx=await browser.newContext({viewport:{width:1440,height:900},recordVideo:{dir:`${BASE}/rec/run${run}`}});
  const page=await ctx.newPage();
  let errs=[]; page.on('console',m=>m.type()==='error'&&errs.push(m.text().slice(0,300))); page.on('pageerror',e=>errs.push('PAGEERROR: '+(''+e).slice(0,300)));
  await page.goto(URL,{waitUntil:'domcontentloaded',timeout:20000});
  await page.waitForTimeout(1500);
  const loadErrs=errs.splice(0); if(loadErrs.length) append({run,ts:Date.now(),selector:'(pageload)',label:'initial load',action:'goto',ok:false,errors:loadErrs});
  // discover
  const els=await page.evaluate(()=>{
    const out=[]; const seen=new Set();
    const sel=el=>{ if(el.id)return '#'+CSS.escape(el.id); const t=el.tagName.toLowerCase(); const c=(el.className&&el.className.toString().trim().split(/\s+/)[0])||''; const txt=(el.textContent||'').trim().slice(0,20); return t+(c?'.'+CSS.escape(c):'')+(txt?`:has("${txt}")`:''); };
    document.querySelectorAll('button, a[href], [role=button], [onclick], input[type=range], input[type=checkbox], [data-action], nav a, .tab, .chip, select').forEach(el=>{
      const s=sel(el); const label=(el.getAttribute('aria-label')||el.textContent||el.value||el.getAttribute('href')||'').trim().slice(0,40);
      const key=s+'|'+label; if(seen.has(key))return; seen.add(key);
      out.push({sel:s, label, type:(el.type||el.tagName.toLowerCase()), href:el.getAttribute&&el.getAttribute('href')||null});
    });
    return out;
  });
  append({run,ts:Date.now(),selector:'(discover)',label:`${els.length} interactive els`,action:'enumerate',ok:true,errors:[]});
  const ordered=orderFor(run,els);
  let acted=0;
  for(const e of ordered){
    if(acted>=60){ append({run,ts:Date.now(),selector:'(cap)',label:'capped at 60 actions',action:'skip',ok:true,errors:[]}); break; }
    try{
      // for links that leave the page, record + skip actual nav to keep front-page focus (log href)
      const isNav = e.type==='a' && e.href && !e.href.startsWith('#') && !/javascript:/i.test(e.href);
      const loc=page.locator(e.sel).first();
      if(await loc.count()===0){ continue; }
      await loc.scrollIntoViewIfNeeded({timeout:2000}).catch(()=>{});
      if(isNav){ append({run,ts:Date.now(),selector:e.sel,label:e.label,action:'nav-link(logged, not followed)',ok:true,effect:'href='+e.href,errors:errs.splice(0)}); acted++; continue; }
      const before=await page.evaluate(()=>document.body.innerText.length).catch(()=>0);
      if(e.type==='range'){ await loc.fill(String(Math.floor(Math.random()*100))).catch(async()=>{await loc.click({timeout:2000}).catch(()=>{});}); }
      else { await loc.click({timeout:2500,force:false}).catch(async()=>{await loc.click({timeout:1500,force:true}).catch(()=>{});}); }
      await page.waitForTimeout(350);
      const after=await page.evaluate(()=>document.body.innerText.length).catch(()=>0);
      append({run,ts:Date.now(),selector:e.sel,label:e.label,action:'click',ok:errs.length===0,effect:`text ${before}->${after}`,errors:errs.splice(0)});
      acted++;
      // dismiss any modal/overlay + ensure still on base
      await page.keyboard.press('Escape').catch(()=>{});
      if(!page.url().startsWith(URL)){ await page.goto(URL,{waitUntil:'domcontentloaded'}).catch(()=>{}); }
    }catch(err){ append({run,ts:Date.now(),selector:e.sel,label:e.label,action:'click',ok:false,errors:[...errs.splice(0),'THROW: '+(''+err).slice(0,150)]}); }
  }
  const runErrCount=prior.length; // n/a
  await ctx.close(); await browser.close();
  console.log(`run ${run}: ${ordered.length} els, ${acted} acted`);
}
console.log('DONE 5 runs');