← back to Newmor Onboard
scripts/verify-discovery.cjs
62 lines
const fs=require('node:fs'),assert=require('node:assert/strict');
const {chromium,webkit}=require('/Users/macstudio3/.npm-global/lib/node_modules/playwright');
const root='/Users/macstudio3/Projects/newmor-onboard',origin='https://www.designerwallcoverings.com';
const journal=JSON.parse(fs.readFileSync(root+'/data/live-2026-09-09/product-launch-journal.json'));
const expected=journal.records.filter(r=>r.after?.status==='ACTIVE').map(r=>r.id.split('/').at(-1)).sort();
const results=[];
const finalMode=process.argv.includes('--final');
const {backgroundOwner,sanitize}=require('./browser-errors.cjs');
function baselineError(e){return !!backgroundOwner(e);}
(async()=>{for(const [engineName,engine] of [['chromium',chromium],['webkit',webkit]]){
const browser=await engine.launch();try{for(const mobile of [false,true]){
const name=engineName+(mobile?'-mobile':'-desktop');if(finalMode&&!['chromium-desktop','webkit-mobile'].includes(name))continue;const dir=root+'/verification/'+(finalMode?'final-discovery':'discovery')+'/'+name;fs.mkdirSync(dir,{recursive:true});
const context=await browser.newContext({viewport:mobile?{width:390,height:844}:{width:1440,height:1000},recordVideo:{dir}});try{
const page=await context.newPage();const errors=[],failedRequests=[];page.on('pageerror',e=>errors.push({message:sanitize(e.message),stack:sanitize(e.stack),url:page.url(),at:Date.now()}));page.on('requestfailed',r=>failedRequests.push({url:r.url().split('?')[0],failure:r.failure()?.errorText,at:Date.now()}));
for(const [route,path] of [['vendor','/collections/vendors?q=Newmor%20Wallcoverings'],['named','/collections/newmor-wallcoverings'],['legacy','/collections/newmor-wallcovering'],['code-search','/search?q=KOT-23&type=product'],['vendor-search','/search?q=Newmor&type=product']]){
if(finalMode&&!['named','vendor-search'].includes(route))continue;
const response=await page.goto(origin+path,{waitUntil:'domcontentloaded',timeout:60000});assert.equal(response.status(),200);await page.waitForTimeout(engineName==='webkit'?7000:3500);
const decline=page.getByRole('button',{name:'Decline',exact:true});if(await decline.isVisible().catch(()=>false))await decline.click({timeout:5000}).catch(()=>{});
assert(await page.evaluate(()=>window.__nwShowroomCards===true),'Newmor card guard missing');
const cards=page.locator('.nw-showroom-card');const ids=await cards.evaluateAll(ns=>ns.map(n=>n.dataset.nwId).sort());
assert.deepEqual(ids,route==='code-search'?['4351291785267']:expected,`${name} ${route} wrong products`);
assert.equal(await cards.locator('button').count(),0);assert(!/\$\s*\d/.test((await cards.allTextContents()).join(' ')));
assert(await cards.first().isVisible());
const layout=await page.locator('.nw-grid-controls label').evaluateAll(ns=>ns.map(n=>{const r=n.getBoundingClientRect();return{x:r.x,y:r.y,width:r.width,height:r.height}}));assert.equal(layout.length,2);assert(Math.abs(layout[0].y+layout[0].height/2-layout[1].y-layout[1].height/2)<10,'Controls not side-by-side');assert(layout[0].x+layout[0].width<=layout[1].x,'Controls overlap');
const images=await cards.locator('img').evaluateAll(ns=>ns.map(n=>({src:n.currentSrc||n.src,loaded:n.complete&&n.naturalWidth>0})));assert(images.every(i=>{const u=new URL(i.src);return u.hostname==='cdn.shopify.com'||u.hostname==='www.designerwallcoverings.com'&&u.pathname.startsWith('/cdn/shop/')}),JSON.stringify(images));assert(images[0].loaded,'First swatch not loaded');
await page.selectOption('#nw-sort','sku');const skus=await cards.evaluateAll(ns=>ns.map(n=>n.dataset.nwSku));assert.deepEqual(skus,[...skus].sort((a,b)=>a.localeCompare(b)));
await page.locator('#nw-density').evaluate(n=>{n.value='4';n.dispatchEvent(new Event('input',{bubbles:true}))});
const initial=await page.locator('.nw-showroom-grid').evaluate(n=>getComputedStyle(n).gridTemplateColumns);
await page.locator('#nw-density').evaluate(n=>{n.value='2';n.dispatchEvent(new Event('input',{bubbles:true}))});
const changed=await page.locator('.nw-showroom-grid').evaluate(n=>getComputedStyle(n).gridTemplateColumns);
assert.notEqual(initial,changed,'Density did not alter grid columns');
assert(await page.evaluate(()=>localStorage.getItem('nw-showroom-density')==='2'));
await page.selectOption('#nw-sort','title');await page.reload({waitUntil:'domcontentloaded'});await page.waitForTimeout(engineName==='webkit'?3500:1200);
assert.equal(await page.locator('#nw-sort').inputValue(),'title');assert.equal(await page.locator('#nw-density').inputValue(),'2');
for(const option of ['color','style','newest'])await page.selectOption('#nw-sort',option);
await page.locator('#nw-density').evaluate(n=>{n.value='4';n.dispatchEvent(new Event('input',{bubbles:true}))});
await page.locator('.nw-showroom').scrollIntoViewIfNeeded();await page.screenshot({path:dir+'/'+route+'.png',fullPage:expected.length<=2});
results.push({engine:name,route,http:200,ids,no_material_price:true,no_buy_control:true,sort_sku:true,sort_options:true,density_persistence:true,density_columns:{initial,changed},swatches:images.length});
if(route==='vendor'){const href=await cards.first().locator('a').getAttribute('href');await cards.first().locator('a').click();await page.waitForURL(u=>u.pathname===href);assert(await page.getByText('Newmor Showroom Line',{exact:true}).isVisible());assert.equal(await page.getByRole('link',{name:'Call the showroom',exact:true}).getAttribute('href'),'tel:+18883734564');results.push({engine:name,discovery_to_pdp:true,pathname:href,showroom_contact:true});await page.waitForTimeout(engineName==='webkit'?7000:3000);}
}
// Supplement remains absent for unrelated searches. Exercise the actual loaded guard with a cloned Boost card.
await page.goto(origin+'/search?q=Lintukoto&type=product',{waitUntil:'domcontentloaded',timeout:60000});await page.waitForTimeout(5000);
assert.equal(await page.locator('.nw-showroom-card').count(),0);
const guard=await page.evaluate(async()=>{
const original=document.querySelector('.boost-sd__product-item');if(!original)throw Error('No actual Boost card to clone');
const price=original.querySelector('.boost-sd__product-price');if(!price)throw Error('Control Boost price absent');
const control=original.innerText;const clone=original.cloneNode(true);clone.id='nw-guard-fixture';clone.dataset.productId='4351291785267';
const action=document.createElement('button');action.textContent='Quick buy';clone.appendChild(action);document.querySelector('main,.main-content').appendChild(clone);
const beforePaint=getComputedStyle(clone.querySelector('.boost-sd__product-price')).display;
await new Promise(r=>setTimeout(r,100));
const data={fixture_from_actual_boost_markup:true,css_before_paint:beforePaint,price_nodes:clone.querySelectorAll('.boost-sd__product-price,.boost-sd__format-currency').length,buttons:clone.querySelectorAll('button').length,inquiry:!!clone.querySelector('.nw-boost-inquiry'),control_unchanged:original.innerText===control,control_numeric_price:/\$\s*\d/.test(control)};clone.remove();return data;
});
assert.equal(guard.css_before_paint,'none');assert.equal(guard.price_nodes,0);assert.equal(guard.buttons,0);assert(guard.inquiry&&guard.control_unchanged&&guard.control_numeric_price);
const critical=errors.filter(e=>!baselineError(e));
results.push({engine:name,unrelated_search_unchanged:true,future_boost_guard_fixture:guard,page_errors:errors,nonblocking_external_errors:errors.filter(baselineError).map(e=>({owner:backgroundOwner(e),error:e})),failed_requests:failedRequests});assert.equal(critical.length,0,JSON.stringify(critical,null,2));
console.log(`PASS ${name}:${finalMode?2:5} live browse/search routes,controls,persistence,unrelatedvendor,Boostguard`);
}finally{await context.close();}
}}finally{await browser.close();}
}
fs.writeFileSync(root+'/verification/'+(finalMode?'final-discovery-proof.json':'discovery-proof.json'),JSON.stringify({timestamp:new Date().toISOString(),verdict:'PASS',expected_ids:expected,results,limitations:['Native collection/search paths verified independently of Boost indexing; no claim that Boost index has been repaired.','Future Boost card guard exercised with cloned actual app markup; this is not a claim of Newmor being indexed.','Known external analytics/optional app errors recorded with owner; native Newmor assertions remain strict.']},null,2)+'\n');
})().catch(e=>{fs.writeFileSync(root+'/verification/'+(finalMode?'final-discovery-proof.json':'discovery-proof.json'),JSON.stringify({timestamp:new Date().toISOString(),verdict:'FAIL',error:e.message,results},null,2)+'\n');console.error(e.stack);process.exit(1)});