import fs from 'node:fs/promises'; import path from 'node:path'; import { launchChromium } from '../../scripts/orgchart-browser-runtime.mjs'; const output = path.resolve('test-results/org-chart-p9-3'); const origin = process.env.ORGCHART_STORY_ORIGIN ?? 'http://127.0.0.1:6064'; const browser = await launchChromium({headless:true}); const page = await browser.newPage({viewport:{width:1440,height:900}}); const results=[],errors=[]; page.on('pageerror',e=>errors.push(e.message)); page.on('console',m=>{if(m.type()==='error')errors.push(m.text());}); const check=(ok,name,detail)=>{results.push({name,status:ok?'PASS':'FAIL',detail});if(!ok)console.log('FAIL',name,detail);}; const ready=async()=>{await page.waitForFunction(()=>{const s=document.querySelector('.hm-orgchart-host')?.shadowRoot;return s&&!s.querySelector('[aria-busy="true"]')&&s.querySelector('.hm-orgchart-employee')&&[...s.querySelectorAll('link')].every(l=>l.sheet);});await page.evaluate(async()=>{await document.fonts.ready;for(let i=0;i<12;i++)await new Promise(requestAnimationFrame);});}; await page.goto(`${origin}/iframe.html?id=orgchart--full-composition&viewMode=story`);await ready(); await page.evaluate(async()=>{await Promise.all([...document.querySelector('.hm-orgchart-host').shadowRoot.querySelectorAll('img')].map(async i=>{i.loading='eager';await i.decode();}));}); // Reuse the exact original measurement function; do not rerun P9.2's suite. const priorSource=await fs.readFile('examples/org-chart/verify-p9-2-composition.mjs','utf8'); const from=priorSource.indexOf('async function snapshot()'),to=priorSource.indexOf('async function stability()',from); const state=await new Function('page',priorSource.slice(from,to)+'; return snapshot();')(page); const previous=JSON.parse(await fs.readFile('test-results/org-chart-p9-2/browser-composition.json','utf8')).snapshots['1440']; const same=(a,b)=>JSON.stringify(a)===JSON.stringify(b); const normalizedEqual=state.elements.every((e,i)=>{const old=previous.elements[i];return old?.key===e.key&&old.hash===e.hash&&same(old.style,e.style)&&Object.keys(e.box).every(k=>Math.abs(e.box[k]-old.box[k])<.15);}); check(previous.htmlHash===state.htmlHash&&same(previous.assets,state.assets)&&normalizedEqual,'Fixed P9.2 DOM, 139 image hashes, 152 element styles/geometry preserved',{before:previous.htmlHash,after:state.htmlHash,elements:state.elements.length,assets:state.assets.length}); check(Math.abs(state.centerDifference)<1&&state.collisions.length===0&&state.counts.cards===43&&state.counts.paths===5,'Fixed center/card/connector minimal regression',{centerDifference:state.centerDifference,counts:state.counts,collisions:state.collisions}); check(await page.evaluate(()=>!document.querySelector('.hm-orgchart-host').shadowRoot.querySelector('[data-edit-dragging],[data-drop-state],.hm-orgchart-move-feedback')),'Fixed has no editing UI'); await page.screenshot({path:path.join(output,'fixed-preserved-1440.png'),fullPage:true}); await page.goto(`${origin}/`); await page.waitForFunction(()=>Boolean(document.querySelector('a[href*="orgchart--expanded-org-chart"]'))); const menus=await page.locator('a[href*="orgchart--"]').allTextContents(); check(menus.includes('Overview')&&menus.includes('Department Colors')&&menus.includes('Full Composition')&&menus.includes('Expanded OrgChart'),'Four existing Storybook menu entries preserved',menus); for(const width of [390,768,1280,1440]){ await page.setViewportSize({width,height:1100}); await page.goto(`${origin}/iframe.html?id=orgchart--expanded-org-chart&viewMode=story`);await ready(); const metrics=await page.evaluate(()=>{const s=document.querySelector('.hm-orgchart-host').shadowRoot,v=s.querySelector('.hm-orgchart-viewport'),f=s.querySelector('.hm-orgchart-move-feedback'),c=getComputedStyle(f);return {width:innerWidth,scrollWidth:document.documentElement.scrollWidth,viewportWidth:v.clientWidth,rawInnerScrollWidth:v.scrollWidth,feedbackHeight:f.clientHeight,feedbackScrollHeight:f.scrollHeight,feedbackColor:c.color,feedbackFontWeight:c.fontWeight,unresolvedTokens:[...['--hm-orgchart-resolved-fg-secondary','--hm-orgchart-resolved-action-primary','--hm-orgchart-resolved-stroke-default','--hm-orgchart-resolved-stroke-input-focus']].filter(k=>!getComputedStyle(f).getPropertyValue(k).trim())};}); check(metrics.scrollWidth<=width+1&&metrics.viewportWidth>0&&metrics.feedbackScrollHeight<=metrics.feedbackHeight+1&&metrics.unresolvedTokens.length===0,`${width}: responsive move instructions, viewport and token declarations`,metrics); await page.screenshot({path:path.join(output,`expanded-${width}.png`),fullPage:true}); } check(errors.length===0,'No new console/page errors',errors); await fs.writeFile(path.join(output,'preservation.json'),JSON.stringify({origin,results,errors,fixedSnapshot:state},null,2)); await browser.close();console.log(JSON.stringify({pass:results.filter(x=>x.status==='PASS').length,fail:results.filter(x=>x.status==='FAIL').length})); if(results.some(x=>x.status==='FAIL'))process.exitCode=1;