← back to Commercialrealestate
5x/sales-assert.js
38 lines
// Strong sales.html gate: table rows render with data (no NaN), both charts drew, a filter narrows rows,
// depth note present; empty-data degrades with no NaN/error.
const pw=require('/Users/macstudio3/.claude/skills/browserbase/node_modules/playwright-core');
const EXEC='/Applications/Google Chrome.app/Contents/MacOS/Google Chrome';
async function run(mockEmpty){
const errors=[]; const b=await pw.chromium.launch({executablePath:EXEC,headless:true});
const pg=await b.newPage({viewport:{width:1280,height:900}});
pg.on('pageerror',e=>errors.push('PAGEERR: '+e.message));
pg.on('console',m=>{if(m.type()==='error'&&!/Failed to load resource/.test(m.text()))errors.push('CONSOLE: '+m.text());});
if(mockEmpty) await pg.route('**/api/closed-sales**',r=>r.fulfill({status:200,contentType:'application/json',body:'{"sales":[],"rows":[]}'}));
await pg.goto('http://127.0.0.1:9911/sales.html',{waitUntil:'networkidle'}); await pg.waitForTimeout(1800);
const base=await pg.evaluate(()=>{
const rows=[...document.querySelectorAll('#tbl tbody tr')];
const cellTxt=rows.slice(0,40).map(r=>r.textContent).join(' ');
return { rows:rows.length, anyNaN:/NaN|undefined/.test(cellTxt),
cityChart:!!(window.Chart&&Chart.getChart('cityChart')), yearChart:!!(window.Chart&&Chart.getChart('yearChart')),
depthNote:(document.querySelector('#depthNote')?.textContent||'').length>0 };
});
let filterOk=null;
if(!mockEmpty){
filterOk=await pg.evaluate(async()=>{ const sel=document.querySelector('#city'); if(!sel||sel.tagName!=='SELECT'||(sel.options||[]).length<2) return null;
const before=document.querySelectorAll('#tbl tbody tr').length;
sel.selectedIndex=1; sel.dispatchEvent(new Event('change'));
await new Promise(r=>setTimeout(r,400));
const after=document.querySelectorAll('#tbl tbody tr').length;
return { before, after, narrowed: after<=before && after>0 }; });
}
await b.close();
return { mockEmpty, ...base, filterOk, jsErrors:errors };
}
(async()=>{
const normal=await run(false); const empty=await run(true);
const passNormal = normal.rows>0 && !normal.anyNaN && normal.cityChart && normal.yearChart && (!normal.filterOk||normal.filterOk.narrowed) && normal.jsErrors.length===0;
const passEmpty = !empty.anyNaN && empty.jsErrors.length===0;
console.log(JSON.stringify({normal,empty,passNormal,passEmpty,VERDICT:(passNormal&&passEmpty)?'PASS':'FAIL'},null,2));
process.exit((passNormal&&passEmpty)?0:1);
})().catch(e=>{console.error('FAIL',e.message);process.exit(1);});