tracker/e2e/module-groups-check.mjs
import {pathToFileURL} from 'node:url';
const [chrome,base,out,modulePath]=process.argv.slice(2);const {chromium}=await import(pathToFileURL(modulePath).href),browser=await chromium.launch({executablePath:chrome,headless:true,args:['--no-sandbox']});
const page=await browser.newPage({viewport:{width:1600,height:1100}}),errors=[];page.on('pageerror',e=>errors.push(e.message));await page.route('https://fonts.googleapis.com/**',r=>r.abort());await page.route('https://fonts.gstatic.com/**',r=>r.abort());let passed=0;const check=(ok,message)=>{if(!ok)throw Error(message);passed++;console.log('PASS '+message)};const go=path=>page.goto(base+path,{waitUntil:'domcontentloaded'});
try {
await go('/use-cases');check(await page.locator('select[name=module] option[value=ADM]').textContent().then(s=>s.startsWith('รับสมัครและคัดเลือก')&&!s.includes('ADM')),'Use-case module filter shows full names');check(await page.locator('[data-uc-module=ADM] .uc-module-header').textContent().then(s=>s.includes('รับสมัครและคัดเลือก')&&!/\bADM\b/.test(s)),'Use-case group header no longer prefixes the module abbreviation');
check(await page.locator('[data-uc-module=ADM] .uc-module-link').first().textContent().then(s=>s.trim()==='รับสมัครและคัดเลือก'),'Use-case row shows the full module label only');
await go('/use-cases/W-41');check(await page.locator('.uc-heading .uc-eyebrow').textContent().then(s=>s.includes('รับสมัครและคัดเลือก')&&!/\bADM\b/.test(s)),'Use-case detail heading uses full module name');
await go('/mockup/screens');check(await page.locator('select[name=module] option[value=ADM]').textContent()==='รับสมัครและคัดเลือก','Screen Listing filter uses full module names with stable internal values');check(await page.locator('.mock-screen-row').first().locator('td').nth(2).textContent().then(s=>s.includes('รับสมัครและคัดเลือก')&&!/\bADM\b/.test(s)),'Screen Listing module tags use full names');
await go('/mockup/screens/A01');check(await page.locator('.mock-detail-heading .uc-eyebrow').textContent().then(s=>s.includes('รับสมัครและคัดเลือก')&&!/\bADM\b/.test(s)),'screen detail heading uses full name');check(await page.locator('.mock-detail-info .mock-pill').textContent()==='รับสมัครและคัดเลือก','screen detail module badge uses full name');
const svg=await page.evaluate(async()=>{const text=await(await fetch(document.querySelector('#mock-detail-image').getAttribute('src'))).text();return new DOMParser().parseFromString(text,'image/svg+xml').documentElement.textContent});check(svg.includes('A01 · รับสมัครและคัดเลือก')&&!svg.includes('A01 · ADM'),'generated screen preview uses the full module label');
await go('/mockup/sitemap');await page.waitForFunction(()=>!document.querySelector('#mock-reload').disabled&&document.querySelectorAll('.mock-node').length>0);check(await page.locator('#mock-scope-module option[value=ADM]').textContent()==='รับสมัครและคัดเลือก','Sitemap scope dropdown shows full names');
const originalUseCaseState=await page.evaluate(()=>localStorage.getItem('tracker-usecase-collapsed-modules'));
await go('/mockup/page-flow');check(await page.locator('[data-flow-search]').count()===162&&await page.locator('[data-flow-module]').count()>1,'all page flows are grouped by module');const group=page.locator('[data-flow-module=ADM]'),button=group.locator('[data-flow-toggle]'),count=await group.locator('.mock-flow-row').count();
check(await button.textContent().then(s=>s.includes('รับสมัครและคัดเลือก')&&!/\bADM\b/.test(s)),'Page flow group header shows full name without abbreviation');check(await group.locator('.mock-flow-row td:nth-child(2)').first().textContent().then(s=>s.trim()==='รับสมัครและคัดเลือก'),'Page flow row module cells use full names');
await button.click();check(await button.getAttribute('aria-expanded')==='false'&&await group.locator('.mock-flow-row:visible').count()===0,'a module can collapse its page-flow rows');check(await page.locator('.mock-flow-row:visible').count()===162-count,'collapsing one module preserves the other groups');
await page.reload();check(await page.locator('[data-flow-toggle=ADM]').getAttribute('aria-expanded')==='false','collapsed Page flow modules survive reload');
await page.fill('#mock-flow-search','W-41');check(await page.locator('.mock-flow-row:visible').count()===1&&await page.locator('[data-flow-module]:visible').count()===1,'search opens the matching group even when normally collapsed');await page.fill('#mock-flow-search','');check(await page.locator('[data-flow-toggle=ADM]').getAttribute('aria-expanded')==='false','clearing search restores the saved collapse preference');
await page.click('[data-flow-collapse-all]');check(await page.locator('.mock-flow-row:visible').count()===0,'Collapse all hides every Page flow row');await page.fill('#mock-flow-search','รับสมัครและคัดเลือก');check(await page.locator('.mock-flow-row:visible').count()===count,'search accepts full module names');await page.fill('#mock-flow-search','');check(await page.locator('.mock-flow-row:visible').count()===0,'search does not overwrite collapsed-module preferences');await page.click('[data-flow-expand-all]');check(await page.locator('.mock-flow-row:visible').count()===162,'Expand all restores every Page flow');
await page.click('[data-flow-toggle=ADM]');await page.evaluate(()=>{const main=document.querySelector('#main');main.innerHTML=main.innerHTML;document.dispatchEvent(new CustomEvent('tracker:updated'))});check(await page.locator('[data-flow-toggle=ADM]').getAttribute('aria-expanded')==='false','group folding reapplies after live content replacement');check(await page.evaluate(()=>localStorage.getItem('tracker-usecase-collapsed-modules'))===originalUseCaseState,'Page flow folding does not change Use-case folding preferences');
await page.click('[data-flow-expand-all]');await page.click('[data-theme-choice=dark]');await page.screenshot({path:out+'/page-flow-module-groups-dark.png'});await page.setViewportSize({width:390,height:844});check(await page.evaluate(()=>document.documentElement.scrollWidth<=innerWidth+2),'full module names and grouping fit a mobile page');check(await page.locator('.mock-flow-name').first().evaluate(e=>getComputedStyle(e).textOverflow!=='ellipsis'&&getComputedStyle(e).whiteSpace!=='nowrap'),'module headings wrap instead of truncating full text');
check(errors.length===0,'no JavaScript errors in module filters or folding');console.log(passed+' module/group checks passed');
}finally{await browser.close()}