Files
documentation/scripts/browser/skills-exports.cjs
T
jarvis-at-skic abe00994a1
Build and publish Eldorado documentation / build (pull_request) Successful in 46s
docs: [verified] separate Measurement registry and workflow Baseline
2026-10-07 13:33:07 +00:00

46 lines
3.2 KiB
JavaScript

const {chromium}=require('playwright');
const fs=require('node:fs');
const path=require('node:path');
const assert=require('node:assert/strict');
(async()=>{
const dir=process.argv[2]||'.cache/skills-candidate';
const browser=await chromium.launch({executablePath:process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE,args:['--no-sandbox']});
const results=[];
try {
for(const topic of ['measurement','baseline','governance','quality','adoption','maintenance']) for(const width of [1440,1024,390,320]){
const spec=JSON.parse(fs.readFileSync(`diagrams/strategy-${topic}${width<=1100?'-mobile':''}.architecture.json`));
const page=await browser.newPage({viewport:{width:1200,height:1000}});
await page.goto('file://'+path.resolve(`${dir}/${topic}-${width}.svg`));
const measured=await page.locator('svg').evaluate(svg=>{
const v=svg.viewBox.baseVal;const issues=[];
for(const el of svg.querySelectorAll('[data-node-id],path[data-edge-id],g[data-edge-id]')){
const b=el.getBBox();if(b.x<v.x-1||b.y<v.y-1||b.x+b.width>v.x+v.width+1||b.y+b.height>v.y+v.height+1)issues.push(el.getAttribute('data-node-id')||el.getAttribute('data-edge-id'));
}
// Measure the whole rendered label group, including its opaque mask:
// text presence alone cannot detect one label hiding another.
const labels=[...svg.querySelectorAll('g[data-edge-id]')].filter(el=>el.querySelector('text')).map(el=>({id:el.dataset.edgeId,box:el.getBoundingClientRect()}));
const labelOverlaps=[];
for(let i=0;i<labels.length;i++)for(let j=i+1;j<labels.length;j++){
const a=labels[i],b=labels[j];
if(Math.min(a.box.right,b.box.right)>Math.max(a.box.left,b.box.left)&&Math.min(a.box.bottom,b.box.bottom)>Math.max(a.box.top,b.box.top))labelOverlaps.push([a.id,b.id]);
}
return {labelOverlaps,viewBox:[v.width,v.height],nodes:[...svg.querySelectorAll('[data-node-id]')].map(n=>n.dataset.nodeId),edges:[...svg.querySelectorAll('path[data-edge-id]')].map(n=>n.dataset.edgeId),text:svg.textContent,issues};
});
assert.deepEqual(measured.viewBox,spec.meta.viewBox);
assert.deepEqual(measured.nodes.sort(),spec.components.map(n=>n.id).sort());
assert.deepEqual(measured.edges.sort(),spec.connections.map(e=>e.id).sort());
assert.deepEqual(measured.issues,[]);
assert.deepEqual(measured.labelOverlaps,[],`${topic}-${width}: rendered edge labels overlap`);
for(const n of spec.components){assert(measured.text.includes(n.label));assert(measured.text.includes(n.tag));for(const line of n.sublabel.split('\n'))assert(measured.text.includes(line));}
for(const e of spec.connections)if(e.label)assert(measured.text.includes(e.label));
if(width===1440){
await page.setViewportSize({width:spec.meta.viewBox[0],height:spec.meta.viewBox[1]});
await page.screenshot({path:`${dir}/${topic}-standalone-export.png`});
}
results.push({topic,width,nodes:measured.nodes.length,edges:measured.edges.length,complete:true});await page.close();
}
fs.writeFileSync(`${dir}/export-results.json`,JSON.stringify(results,null,2));
console.log(`PASS ${results.length} standalone SVGs: exact graph, text, full-canvas containment and non-overlapping edge labels`);
}finally{await browser.close();}
})().catch(e=>{console.error(e);process.exitCode=1});