Files
Pier_v1/scripts/verify-ungok-ground.cjs
T

50 lines
5.9 KiB
JavaScript

// Run with Windows Node against isolated Chrome CDP 9444 and Vite 5173.
const fs=require('node:fs'),path=require('node:path'),assert=require('node:assert/strict');
const root=path.resolve(__dirname,'..'),out=path.join(root,'.verify/ungok-terrain-fixed-20261110/browser');
fs.mkdirSync(out,{recursive:true});
const report={checks:[],errors:[]};let ws;
const delay=ms=>new Promise(r=>setTimeout(r,ms));
(async()=>{
const tab=await(await fetch('http://127.0.0.1:9444/json/new?about:blank',{method:'PUT'})).json();
ws=new WebSocket(tab.webSocketDebuggerUrl);await new Promise((r,j)=>{ws.onopen=r;ws.onerror=j;});
let seq=0;const pending=new Map();
ws.onmessage=({data})=>{const m=JSON.parse(data),p=pending.get(m.id);if(p){clearTimeout(p.timer);pending.delete(m.id);m.error?p.reject(Error(JSON.stringify(m.error))):p.resolve(m.result);}if(m.method==='Runtime.exceptionThrown')report.errors.push(m.params.exceptionDetails.exception?.description||m.params.exceptionDetails.text);};
const send=(method,params={})=>new Promise((resolve,reject)=>{const id=++seq,timer=setTimeout(()=>reject(Error('Timeout '+method)),30000);pending.set(id,{resolve,reject,timer});ws.send(JSON.stringify({id,method,params}));});
const ev=async expression=>{const r=await send('Runtime.evaluate',{expression,awaitPromise:true,returnByValue:true});if(r.exceptionDetails)throw Error(r.exceptionDetails.exception?.description||r.exceptionDetails.text);return r.result.value;};
const until=async expression=>{for(let i=0;i<150;i++){if(await ev(expression))return;await delay(200);}throw Error('Wait '+expression);};
const check=(name,value)=>{assert.ok(value,name);report.checks.push(name);console.log('PASS',name);};
const click=expression=>ev(`(()=>{const e=${expression};if(!e||e.disabled)throw Error('Missing target '+${JSON.stringify(expression)});e.click();})()`);
const file=async(selector,name)=>{const d=await send('DOM.getDocument'),{nodeId}=await send('DOM.querySelector',{nodeId:d.root.nodeId,selector});await send('DOM.setFileInputFiles',{nodeId,files:[name]});};
const shot=async name=>{const s=await send('Page.captureScreenshot',{format:'png'});fs.writeFileSync(path.join(out,name+'.png'),Buffer.from(s.data,'base64'));};
await send('Page.enable');await send('Runtime.enable');await send('DOM.enable');
await send('Emulation.setDeviceMetricsOverride',{width:1600,height:1000,deviceScaleFactor:1,mobile:false});
await send('Page.navigate',{url:'http://127.0.0.1:5173/'});await until(`typeof window.openSampleProject==='function'`);
const settings=JSON.parse(fs.readFileSync(path.join(root,'pierzainer_ground/data/output/ungok_corrected_20261110/generation_settings.json')));
const workbook='\\\\wsl.localhost\\Ubuntu'+settings.piers.replaceAll('/','\\');
await ev('window.openSampleProject()');await file('#file',workbook);
await until(`document.getElementById('file-name').textContent.includes('piers.xlsx')`);
await ev(`(()=>{const e=document.getElementById('project-name');e.value='운곡교 지반 수정 검증';e.dispatchEvent(new Event('input'));document.getElementById('import-dialog').showModal();})()`);
await until(`!document.getElementById('dlg-apply').disabled`);
await click(`document.getElementById('dlg-apply')`);await click(`document.getElementById('nav-shape')`);await click(`document.getElementById('project-ground-open')`);
check('actual workbook lists all 16 structures',await ev(`document.querySelectorAll('[data-ground-pier]').length===16`));
await file('#ground-import',path.join(root,'pierzainer_ground/data/output/ungok_corrected_20261110/ground_model_3d_with_maps.json'));
await until(`document.getElementById('project-ground-status').textContent.includes('16/16')`);
check('all structures have applicable corrected ground',await ev(`[...document.querySelectorAll('[data-ground-pier]')].every(e=>!e.disabled)`));
await click(`document.getElementById('project-ground-select-all')`);
check('all 16 structures are selected for application',await ev(`document.querySelectorAll('[data-ground-pier]:checked').length===16`));
await click(`document.getElementById('project-ground-apply')`);
await click(`document.getElementById('project-ground-regenerate')`);
await until(`document.getElementById('project-ground-regenerate').disabled`);
check('all changes regenerate successfully',await ev(`document.getElementById('project-ground-regenerate').disabled`));
await shot('01-corrected-manager');await click(`document.querySelector('#project-ground-dialog .viewer-head button')`);
await delay(1000);await shot('02-corrected-terrain');
await send('Browser.setDownloadBehavior',{behavior:'deny'});
await ev(`(()=>{window.__ungokSaved=null;const original=URL.createObjectURL;URL.createObjectURL=function(blob){blob.text().then(t=>{try{window.__ungokSaved=JSON.parse(t);}catch{}});return original.call(this,blob);};})()`);
await click(`document.getElementById('save-project')`);await until(`document.getElementById('save-dialog').open`);await click(`document.getElementById('sv-save')`);await until(`!!window.__ungokSaved?.groundModel`);
const saved=await ev(`window.__ungokSaved`);fs.writeFileSync(path.join(out,'verified.pzr.json'),JSON.stringify(saved));
check('saved project retains 16 corrected ground records and two maps',saved.groundModel.piers.length===16&&saved.groundModel.mapLayers.length===2);
const expected=JSON.parse(fs.readFileSync(path.join(root,'pierzainer_ground/data/output/ungok_corrected_20261110/ground_model_3d_with_maps.json')));
check('saved terrain elevations equal generated JSON',JSON.stringify(saved.groundModel.terrainGrid.z)===JSON.stringify(expected.terrain_grid.z));
check('browser runtime has no exceptions',report.errors.length===0);report.result='PASS';
})().catch(e=>{report.result='FAIL';report.failure=e.stack;process.exitCode=1;}).finally(()=>{fs.writeFileSync(path.join(out,'report.json'),JSON.stringify(report,null,2));console.log(JSON.stringify(report));ws?.close();});