← back to Dw Signup Fulfillment
verification/tk11283/journey.cjs
112 lines
'use strict';
const fs=require('node:fs');
const path=require('node:path');
const http=require('node:http');
const assert=require('node:assert/strict');
const {Liquid}=require('/private/tmp/dw-signin-review/node_modules/liquidjs');
const {chromium}=require('/Users/macstudio3/Projects/Designer-Wallcoverings/node_modules/playwright');
const {webkit}=require('/Users/macstudio3/.npm-global/lib/node_modules/playwright');
const engine=new Liquid();
const proposal=path.resolve(__dirname,'../../theme-proposals/designer-signin-tk11283/snippets');
const checks=[];
function pass(name,detail){checks.push({name,verdict:'PASS',detail});console.log('PASS '+name);}
const routes={account_url:'/account',account_login_url:'/customer_authentication/redirect?locale=en',all_products_collection_url:'/collections/all'};
async function render(persona){
const customer=persona==='signedin'?{email:'audit@example.invalid',tags:[]}:persona==='approved'?{email:'audit@example.invalid',tags:['trade_approved']}:null;
const data={customer,routes,request:{path:'/pages/trade-only-benefits'}};
const trade=await engine.parseAndRender(fs.readFileSync(path.join(proposal,'dw-trade-apply.liquid'),'utf8'),data);
const modal=await engine.parseAndRender(fs.readFileSync(path.join(proposal,'dw-signin-modal.liquid'),'utf8'),data);
return '<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><style>body{margin:0}button,input,select,textarea{font-family:inherit}a{color:inherit}</style></head><body><button data-dw-signin>Account</button>'+trade+modal+'</body></html>';
}
async function fill(page,email='audit@example.invalid'){
await page.locator('[name=contact_name]').fill('DW Audit');
await page.locator('#dwTaEmail').fill(email);
await page.locator('#dwTaPhone').fill('202-555-0100');
await page.locator('#dwTaBusiness').fill('Intercepted Test Studio');
await page.locator('#dwTaRole').selectOption({label:'Interior designer'});
await page.locator('#dwTaWebsite').fill('https://example.invalid');
await page.locator('#dwTaLocation').fill('Los Angeles, CA');
await page.locator('[name=terms_acknowledged]').check();
}
async function main(){
const pages={};for(const persona of ['anon','signedin','approved'])pages[persona]=await render(persona);
const server=http.createServer((req,res)=>{res.setHeader('content-type','text/html');res.end(pages[new URL(req.url,'http://localhost').searchParams.get('persona')||'anon']);});
await new Promise(resolve=>server.listen(0,'127.0.0.1',resolve));
const origin='http://127.0.0.1:'+server.address().port;
try{
for(const [name,driver] of [['chrome',chromium],['safari',webkit]]){
const browser=await driver.launch({headless:true});
const ctx=await browser.newContext({viewport:{width:1280,height:900},recordVideo:{dir:path.join(__dirname,'recordings',name)}});
let mode='linked',calls=[];
await ctx.route('**/*',async route=>{
const req=route.request();
if(req.url().includes('signup.designerwallcoverings.com/trade/apply')){
calls.push(JSON.parse(req.postData()));
if(mode==='network')return route.abort('failed');
const status=mode==='rate'?429:mode==='server'?500:200;
const body=mode==='invalid'?{}:status!==200?{ok:false,error:'rate_limited'}:{ok:true,id:'TRADE-AUDIT-INTERCEPTED',status:'pending',linked:mode!=='unlinked'};
return route.fulfill({status,contentType:'application/json',body:JSON.stringify(body)});
}
if(!['GET','HEAD'].includes(req.method()))throw new Error('Blocked unexpected mutation '+req.method());
if(new URL(req.url()).origin!==origin)return route.abort();
return route.continue();
});
const page=await ctx.newPage();const errors=[];page.on('pageerror',e=>errors.push(e.message));
const go=async(persona='anon')=>{await page.goto(origin+'/pages/trade-only-benefits?persona='+persona);};
const shot=async(file)=>{await page.screenshot({path:path.join(__dirname,name+'-'+file+'.png'),fullPage:false});};
try{
await go();
await page.locator('[data-dw-signin]').click();
assert(await page.locator('#dw-signin').evaluate(x=>x.classList.contains('dwsm-open')));
assert.equal(await page.locator('#dw-signin form').count(),0);
assert.equal(await page.locator('[data-dwsm-designer]').getAttribute('href'),'/pages/trade-only-benefits#dwTradeApplication');
assert.equal(await page.locator('[data-dwsm-login]').count(),2);
await page.keyboard.press('Shift+Tab');
assert(await page.locator('[data-dwsm-login]').last().evaluate(x=>x===document.activeElement));
await page.keyboard.press('Tab');
assert(await page.locator('[data-dwsm-close]').evaluate(x=>x===document.activeElement));
await shot('account-modal');
await page.keyboard.press('Escape');
assert(await page.locator('[data-dw-signin]').evaluate(x=>x===document.activeElement));
pass(name+' modal','Full-form designer entry; retail/existing sign-in; focus trap and focus restoration.');
await page.locator('[data-dw-signin]').click();await page.locator('[data-dwsm-designer]').click();
assert(!await page.locator('#dw-signin').evaluate(x=>x.classList.contains('dwsm-open')));
const submit=()=>page.locator('#dwTradeForm button[type=submit]').click();
await submit();assert.equal(calls.length,0);assert.match(await page.locator('#dwTradeStatus').innerText(),/required/);
await fill(page);assert.equal(await page.locator('#dwTaSmsConsent').isChecked(),false);
pass(name+' required fields','Empty form blocked; full professional fields required; optional SMS remains unchecked.');
for(const failure of ['rate','server','invalid','network']){
mode=failure;await submit();await page.waitForFunction(()=>document.getElementById('dwTradeStatus').dataset.state==='error');
assert.equal(await page.locator('#dwTaEmail').inputValue(),'audit@example.invalid');
assert(await page.locator('#dwTradeNext').isHidden());
assert(await page.locator('#dwTradeForm button').isEnabled());
pass(name+' '+failure,'No false success; form values retained and error displayed.');
}
mode='linked';await submit();await page.locator('#dwTradeNext').waitFor({state:'visible'});
assert.match(await page.locator('#dwTradeNextTitle').innerText(),/account is ready/);
const link=new URL(await page.locator('#dwTradeLogin').getAttribute('href'));
assert.equal(link.pathname,'/customer_authentication/login');assert.equal(link.searchParams.get('login_hint'),'audit@example.invalid');assert.equal(link.searchParams.get('return_to'),'/collections/all');
assert.match(await page.locator('#dwTradeNext').innerText(),/approval is still pending/);
const n=calls.length;await page.locator('#dwTradeForm').evaluate(f=>f.dispatchEvent(new Event('submit',{cancelable:true})));assert.equal(calls.length,n);
assert.equal(calls.at(-1).sms_marketing_consent,false);
await shot('account-ready');pass(name+' account and login','Confirmed pending/linked result gives encoded same-email sign-in; repeat submit suppressed.');
await go();await fill(page);mode='unlinked';await submit();await page.locator('#dwTradeNext').waitFor({state:'visible'});
assert.match(await page.locator('#dwTradeNextTitle').innerText(),/needs one more step/);assert.match(await page.locator('#dwTradeAccountMessage').innerText(),/could not confirm/);
pass(name+' unlinked','Saved application does not falsely claim the account is connected.');
await go('signedin');await fill(page);mode='linked';await submit();await page.locator('#dwTradeNext').waitFor({state:'visible'});
assert.equal(await page.locator('#dwTradeLogin').getAttribute('href'),'/collections/all');pass(name+' signed in','Same-email existing account continues browsing without redundant login.');
await go('signedin');await fill(page,'another@example.invalid');await submit();await page.locator('#dwTradeNext').waitFor({state:'visible'});
assert.match(await page.locator('#dwTradeLogin').getAttribute('href'),/another%40example.invalid/);pass(name+' different email','Does not assume another email belongs to the currently signed-in account.');
await go('approved');assert.equal(await page.locator('#dwTradeForm').count(),0);await page.locator('[data-dw-signin]').click();assert.equal(await page.locator('[data-dwsm-designer]').count(),0);pass(name+' approved','Approved designers see active benefits and sourcing, with no repeat application.');
await page.setViewportSize({width:390,height:844});await go();await page.locator('[data-dw-signin]').click();await shot('mobile-modal');
assert(await page.locator('.dwsm-card').evaluate(x=>x.getBoundingClientRect().width<=window.innerWidth));
await page.keyboard.press('Escape');await fill(page);await submit();await page.locator('#dwTradeNext').waitFor({state:'visible'});await shot('mobile-ready');
assert(await page.evaluate(()=>document.documentElement.scrollWidth<=window.innerWidth+1));pass(name+' mobile','390px layout has no horizontal overflow; primary sign-in CTA visible.');
assert.deepEqual(errors,[]);pass(name+' scripts','No page JavaScript errors.');
}finally{await ctx.close();await browser.close();}
}
}finally{await new Promise(resolve=>server.close(resolve));}
fs.writeFileSync(path.join(__dirname,'journey.json'),JSON.stringify({timestamp:new Date().toISOString(),environment:'Local Liquid-rendered proposal; all signup submissions intercepted',checks,externalWrites:0,verdict:'PASS',limitations:['Shopify OTP completion and live account creation are not performed by this fixture test.','Cloud browser not run; zero-cost policy.']},null,2)+'\n');
}
main().catch(e=>{console.error(e.stack);process.exitCode=1;});