← back to Commercialrealestate
5x night item 2: crcp.html strong gate (crcp-assert.js — tiles/segments/expand/modal/sort/empty all PASS); six-way 6/6 with correct visible selector. No crcp defect — M3 FAIL was collapse-default vs visibility-selector mismatch, not a bug
928c43fab2b328d05f36832225919fffbf697021 · 2026-06-28 23:33:32 -0700 · Steve
Files touched
A 5x/crcp-assert.jsA 5x/crcp-sweep-1.rawA 5x/crcp-sweep-2.raw
Diff
commit 928c43fab2b328d05f36832225919fffbf697021
Author: Steve <steve@designerwallcoverings.com>
Date: Sun Jun 28 23:33:32 2026 -0700
5x night item 2: crcp.html strong gate (crcp-assert.js — tiles/segments/expand/modal/sort/empty all PASS); six-way 6/6 with correct visible selector. No crcp defect — M3 FAIL was collapse-default vs visibility-selector mismatch, not a bug
---
5x/crcp-assert.js | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++
5x/crcp-sweep-1.raw | 19 ++++++++++++++++++
5x/crcp-sweep-2.raw | 15 ++++++++++++++
3 files changed, 91 insertions(+)
diff --git a/5x/crcp-assert.js b/5x/crcp-assert.js
new file mode 100644
index 0000000..596f2df
--- /dev/null
+++ b/5x/crcp-assert.js
@@ -0,0 +1,57 @@
+// Strong crcp.html gate: tiles render with data (no NaN), 8 segment rows ATTACHED+correct, collapsed panel
+// expands to visible, segment modal opens with a call-list, broker sort reorders, empty-data degrades clean.
+const pw=require('/Users/stevestudio2/.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:1320,height:1000}});
+ 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/segments',r=>r.fulfill({status:200,contentType:'application/json',body:'{"segments":[]}'}));
+ await pg.route('**/api/crcp/stats',r=>r.fulfill({status:200,contentType:'application/json',body:'{}'}));
+ }
+ await pg.goto('http://127.0.0.1:9911/crcp.html',{waitUntil:'networkidle'}); await pg.waitForTimeout(1500);
+ const base=await pg.evaluate(()=>{
+ const tiles=[...document.querySelectorAll('#tiles .tile .v')].map(v=>v.textContent);
+ const srows=[...document.querySelectorAll('.srow')];
+ const cellText=srows.map(r=>r.textContent).join(' ');
+ return { tiles, segRowsAttached:srows.length, anyNaN:/NaN|undefined/.test(cellText+' '+tiles.join(' ')),
+ segVisibleBefore: srows.length?srows[0].offsetParent!==null:false };
+ });
+ let expanded=false, modal={}, sortOk=null;
+ if(!mockEmpty){
+ // expand the Call Segments panel (the .panel that holds #segTbl)
+ expanded=await pg.evaluate(()=>{ const t=document.querySelector('#segTbl'); const p=t&&t.closest('.panel');
+ if(!p) return false; const h=p.querySelector('h3'); if(p.classList.contains('collapsed')) h.click();
+ return !p.classList.contains('collapsed'); });
+ await pg.waitForTimeout(250);
+ const visAfter=await pg.evaluate(()=>{ const r=document.querySelector('.srow'); return r? r.offsetParent!==null:false; });
+ // click first clickable segment row → modal with call list
+ await pg.evaluate(()=>{ const r=[...document.querySelectorAll('.srow')].find(x=>x.style.cursor==='pointer'); if(r)r.click(); });
+ await pg.waitForTimeout(900);
+ modal=await pg.evaluate(()=>({ open:document.querySelector('#ov')?.classList.contains('on'),
+ items:document.querySelectorAll('#mbody .brow3').length, hasHeading:!!document.querySelector('#mbody h2') }));
+ await pg.evaluate(()=>{ const ov=document.querySelector('#ov'); if(ov)ov.classList.remove('on'); });
+ modal.visAfterExpand=visAfter;
+ // broker table sort: expand its panel, capture order, click a header, compare
+ sortOk=await pg.evaluate(async()=>{ const t=document.querySelector('#brTbl'); const p=t&&t.closest('.panel');
+ if(p&&p.classList.contains('collapsed')) p.querySelector('h3').click();
+ await new Promise(r=>setTimeout(r,150));
+ const before=[...document.querySelectorAll('#brTbl tbody tr')].map(r=>r.textContent).slice(0,5).join('|');
+ const th=document.querySelector('#brTbl th.srt[data-col=name]'); if(!th) return null; th.click();
+ await new Promise(r=>setTimeout(r,200));
+ const after=[...document.querySelectorAll('#brTbl tbody tr')].map(r=>r.textContent).slice(0,5).join('|');
+ return { changed: before!==after, rows: document.querySelectorAll('#brTbl tbody tr').length }; });
+ }
+ await b.close();
+ return { mockEmpty, ...base, expanded, modal, sortOk, jsErrors:errors };
+}
+(async()=>{
+ const normal=await run(false); const empty=await run(true);
+ const passNormal = normal.segRowsAttached>=7 && !normal.anyNaN && normal.expanded && normal.modal.visAfterExpand
+ && normal.modal.open && normal.modal.hasHeading && (normal.modal.items>0) && normal.sortOk && normal.sortOk.changed && 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);});
diff --git a/5x/crcp-sweep-1.raw b/5x/crcp-sweep-1.raw
new file mode 100644
index 0000000..1c0b6d2
--- /dev/null
+++ b/5x/crcp-sweep-1.raw
@@ -0,0 +1,19 @@
+
+/3x — verifying http://127.0.0.1:9911/crcp.html
+
+Phase A — 3 unique methods:
+ [PASS] M1 HTTP contract request layer — HTTP 200 text/html
+ [PASS] M2 headless render render layer — screenshot 84KB → /var/folders/2n/jmw9_4v56_x4m3539tr4v0lr0000gn/T/3x-TKmVpN/render.png
+ [FAIL] M3 automation E2E interaction layer — page.waitForSelector: Timeout 8000ms exceeded.
+Call log:
+[2m - waiting for locator('#segTbl tbody tr') to be visible[22m
+[2m 21 × locator resolved to 8 elements. Proceeding with the first one: <tr class="srow" data-key="mixed-use">…</tr>[22m
+
+
+Phase B — 3 browsers (cross-browser):
+ [SKIP] B4 Google Chrome cross-browser — engine not installed, --no-open set
+ [SKIP] B5 Safari cross-browser — engine not installed, --no-open set
+ [SKIP] B6 Firefox cross-browser — engine not installed, --no-open set
+
+ RESULT → 2/3 passed, 1 FAILED, 3 skipped
+ artifacts: /var/folders/2n/jmw9_4v56_x4m3539tr4v0lr0000gn/T/3x-TKmVpN
diff --git a/5x/crcp-sweep-2.raw b/5x/crcp-sweep-2.raw
new file mode 100644
index 0000000..cccf2b8
--- /dev/null
+++ b/5x/crcp-sweep-2.raw
@@ -0,0 +1,15 @@
+
+/3x — verifying http://127.0.0.1:9911/crcp.html
+
+Phase A — 3 unique methods:
+ [PASS] M1 HTTP contract request layer — HTTP 200 text/html
+ [PASS] M2 headless render render layer — screenshot 84KB → /var/folders/2n/jmw9_4v56_x4m3539tr4v0lr0000gn/T/3x-cCYJrI/render.png
+ [PASS] M3 automation E2E interaction layer — 7×"#tiles .tile", 0 JS errors
+
+Phase B — 3 browsers (cross-browser):
+ [PASS] B4 Google Chrome cross-browser — automated render OK
+ [PASS] B5 Safari cross-browser — automated render OK
+ [PASS] B6 Firefox cross-browser — automated render OK
+
+ RESULT → 6/6 passed
+ artifacts: /var/folders/2n/jmw9_4v56_x4m3539tr4v0lr0000gn/T/3x-cCYJrI
← cdaa2b4 5x night-log: items 1+3 done; queue + method note for next w
·
back to Commercialrealestate
·
5x night item 5: harden geocoder — strip unit designators (# ad89b92 →