← back to Quadrille Showroom
auto-save: 2026-07-01T11:11:52 (2 files) — public/js/showroom.js scripts/_reverify.mjs
df1dc51421d13799c03375b96fd32179684f5014 · 2026-07-01 11:12:04 -0700 · Steve Abrams
Files touched
M public/js/showroom.jsA scripts/_reverify.mjs
Diff
commit df1dc51421d13799c03375b96fd32179684f5014
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed Jul 1 11:12:04 2026 -0700
auto-save: 2026-07-01T11:11:52 (2 files) — public/js/showroom.js scripts/_reverify.mjs
---
public/js/showroom.js | 2 +-
scripts/_reverify.mjs | 26 ++++++++++++++++++++++++++
2 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/public/js/showroom.js b/public/js/showroom.js
index 6e72310..1adb111 100644
--- a/public/js/showroom.js
+++ b/public/js/showroom.js
@@ -3909,7 +3909,7 @@ function initHUD() {
const ageInput = document.getElementById('tray-age-input');
if (ageInput) {
const saved = localStorage.getItem('qh_visitor_age');
- if (saved !== null && saved !== '') { ageInput.value = saved; visitorAge = parseInt(saved) || null; }
+ if (saved !== null && saved !== '') { const n = parseInt(saved, 10); ageInput.value = saved; visitorAge = Number.isFinite(n) ? n : null; }
ageInput.addEventListener('input', () => {
const v = ageInput.value.trim();
const n = v === '' ? null : Math.max(0, Math.min(120, parseInt(v, 10) || 0));
diff --git a/scripts/_reverify.mjs b/scripts/_reverify.mjs
new file mode 100644
index 0000000..4ab5005
--- /dev/null
+++ b/scripts/_reverify.mjs
@@ -0,0 +1,26 @@
+import pw from '/Users/stevestudio2/.npm-global/lib/node_modules/playwright/index.js';
+const b=await pw.chromium.launch();
+const ctx=await b.newContext({httpCredentials:{username:'admin',password:'DWSecure2024!'}});
+const p=await ctx.newPage();
+const errs=[]; p.on('console',m=>{if(m.type()==='error')errs.push(m.text().slice(0,120));});
+p.on('pageerror',e=>errs.push('PE '+String(e).slice(0,120)));
+const setAge=(v)=>p.evaluate(x=>{const el=document.getElementById('tray-age-input');el.value=x;el.dispatchEvent(new Event('input',{bubbles:true}));},v);
+await p.goto('http://127.0.0.1:7690/',{waitUntil:'domcontentloaded',timeout:30000});
+await p.waitForFunction(()=>window._qh&&window._wingBoards&&window._wingBoards.length>0,{timeout:60000});
+await setAge('67'); await p.waitForTimeout(80);
+const t1=await p.evaluate(()=>({qh:window._qh.visitorAge,ls:localStorage.getItem('qh_visitor_age')}));
+await p.reload({waitUntil:'domcontentloaded'});
+await p.waitForFunction(()=>window._qh&&window._wingBoards&&window._wingBoards.length>0,{timeout:60000});
+const r1=await p.evaluate(()=>({input:document.getElementById('tray-age-input').value,qh:window._qh.visitorAge}));
+// the fixed 0-case: store 0, reload, must restore 0 (not null)
+await setAge('0'); await p.waitForTimeout(80);
+await p.reload({waitUntil:'domcontentloaded'});
+await p.waitForFunction(()=>window._qh&&window._wingBoards&&window._wingBoards.length>0,{timeout:60000});
+const r0=await p.evaluate(()=>({input:document.getElementById('tray-age-input').value,qh:window._qh.visitorAge}));
+console.log('after type 67 :',JSON.stringify(t1));
+console.log('after reload :',JSON.stringify(r1));
+console.log('0-case reload :',JSON.stringify(r0),'(qh must be 0, not null)');
+console.log('errors('+errs.length+')');
+const ok=t1.qh===67&&r1.input==='67'&&r1.qh===67&&r0.qh===0&&r0.input==='0'&&errs.length===0;
+console.log(ok?'✅ RE-VERIFY PASS (incl. 0-case fix)':'❌ RE-VERIFY FAIL');
+await b.close(); process.exit(ok?0:1);
← 59eede3 Capture visitor age as a plain data point on the Sample Tray
·
back to Quadrille Showroom
·
chore: refactor + v1.2.2 (session close) d6a840c →