← 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);}
})();