← back to Quadrille Showroom

proto/shot-focus.cjs

47 lines

#!/usr/bin/env node
/* Verify the click-to-focus mechanic: drive focus() on a swatch programmatically,
   confirm the detail card shows the pattern name + 27" spec, capture a focus shot. */
const { spawn } = require("child_process");
const path = require("path");
const http = require("http");
const PROTO_DIR = __dirname, PORT = 7712;
const URL = `http://127.0.0.1:${PORT}/v6-colorriver.html`;
function waitForServer(port,tries=40){return new Promise((res,rej)=>{const p=(n)=>{const r=http.get({host:"127.0.0.1",port,path:"/v6-colorriver.html"},x=>{x.destroy();res();});r.on("error",()=>{if(n<=0)return rej(new Error("no server"));setTimeout(()=>p(n-1),150);});};p(tries);});}
(async()=>{
  const pw=require("playwright");
  const srv=spawn("node",[path.join(PROTO_DIR,"proxy-server.cjs")],{env:{...process.env,PROTO_PORT:String(PORT)},stdio:"inherit"});
  let code=1;
  try{
    await waitForServer(PORT);
    const b=await pw.chromium.launch({headless:true});
    const pg=await b.newPage({viewport:{width:1440,height:900},deviceScaleFactor:2});
    const errs=[]; pg.on("console",m=>{if(m.type()==="error")errs.push(m.text());}); pg.on("pageerror",e=>errs.push(e.message));
    await pg.goto(URL,{waitUntil:"domcontentloaded"});
    await pg.waitForFunction(()=>window.__RIVER__&&window.__RIVER__.done(),{timeout:35000}).catch(()=>{});
    await pg.waitForTimeout(1500);
    // pick a saturated swatch and focus it via the page's own click path
    const info = await pg.evaluate(()=>{
      // find a colorful swatch by raycasting against the most saturated one
      const probe = window.__FOCUS_PROBE__;
      return probe ? probe() : null;
    });
    // no probe export — instead simulate a center click on a visible swatch
    await pg.mouse.click(720, 380);
    await pg.waitForTimeout(1400);
    const cardShown = await pg.evaluate(()=>document.getElementById("detail").classList.contains("show"));
    const name = await pg.evaluate(()=>document.getElementById("d_name").textContent);
    const dim = await pg.evaluate(()=>document.getElementById("d_dim").textContent);
    await pg.screenshot({path:path.join(PROTO_DIR,"shots","v6-colorriver-focus.png")});
    console.log("\n=== FOCUS VERIFY ===");
    console.log("detail card shown :", cardShown);
    console.log("pattern name      :", JSON.stringify(name));
    console.log("dimensions spec   :", JSON.stringify(dim));
    console.log("console errors    :", errs.length);
    console.log("====================");
    await b.close();
    code = (cardShown && name && name!=="—" && /27/.test(dim) && errs.length===0) ? 0 : 1;
    console.log(code===0?"FOCUS: PASS":"FOCUS: (card may need a swatch under the click point)");
  }catch(e){console.error(e);code=3;}
  finally{srv.kill("SIGTERM");setTimeout(()=>process.exit(code),300);}
})();