import fs from 'node:fs/promises'; import {chromium,expect} from '@playwright/test'; import {login} from './role-permissions-live.mjs'; const browser=await chromium.launch({channel:'msedge',headless:true,args:['--enable-unsafe-swiftshader']}); const page=await browser.newPage(); await page.addInitScript(s=>{sessionStorage.setItem('unreal-tran:web:access-token:v1',s.accessToken);sessionStorage.setItem('unreal-tran:web:refresh-token:v1',s.refreshToken);},await login('root')); await page.route(/\/src\/features\/virtual-training-legacy\/upstream\/views\/training\.js(?:\?|$)/,async route=>{ const response=await route.fetch();await route.fulfill({response,body:await response.text()+` globalThis.__accessSurvey=()=>{ const e=activeTraining,result=[]; for(const id of ['front-pump-hydraulic-pump','front-pump-pto-switch','front-pump-ball-valve-switch','front-pump-aux-control-box-cover']){ const o=e.parts.get(id),box=physicalBounds(o),center=box.getCenter(new THREE.Vector3()),size=box.getSize(new THREE.Vector3()),views=[]; const meshes=[];e.publishedContentRoot.traverse(n=>{if(n.isMesh&&!n.userData.trainingPickProxy&&effectivelyVisible(n))meshes.push(n);}); for(const elevation of [0,.2,.5])for(let angle=0;angle<360;angle+=45){ const a=angle*Math.PI/180,direction=new THREE.Vector3(Math.sin(a),elevation,Math.cos(a)).normalize(),camera=center.clone().addScaledVector(direction,2.5322),ray=new THREE.Raycaster(),blockers=[];let hits=0; for(const offset of [[0,0,0],[.3,0,0],[-.3,0,0],[0,.3,0],[0,-.3,0]]){ const target=center.clone().add(new THREE.Vector3(...offset).multiply(size));ray.set(camera,target.sub(camera).normalize()); const hit=ray.intersectObjects(meshes,false)[0];if(hit&&e.isObjectInsideTarget(hit.object,o))hits++;else if(hit)blockers.push(hit.object.name); } views.push({angle,elevation,direction:direction.toArray(),hits,blockers:[...new Set(blockers)]}); }result.push({id,views});}return result; };`}); }); try{ await page.goto('http://127.0.0.1:6180/teaching/virtual-training/preview/86');await expect(page.locator('[data-role="loading"]')).toHaveClass(/is-hidden/,{timeout:120000}); const result=await page.evaluate(()=>__accessSurvey());await fs.writeFile('reports/bridge-solid-view-20260915/access-survey.json',JSON.stringify(result,null,2)); for(const item of result)console.log(JSON.stringify({id:item.id,best:item.views.sort((a,b)=>b.hits-a.hits).slice(0,5)})); }finally{await browser.close();}