|
- import fs from 'node:fs';
- import assert from 'node:assert/strict';
- import {chromium,expect} from '@playwright/test';
- import {login} from './role-permissions-live.mjs';
-
- const dir='reports/bridge-workbench-inspection-20260924';fs.mkdirSync(dir,{recursive:true});
- const session=await login('root'),checks=[],errors=[];
- const browser=await chromium.launch({channel:'msedge',headless:true,args:['--enable-unsafe-swiftshader']});
- const page=await browser.newPage({viewport:{width:1440,height:900}});
- await page.addInitScript(s=>{sessionStorage.setItem('unreal-tran:web:access-token:v1',s.accessToken);sessionStorage.setItem('unreal-tran:web:refresh-token:v1',s.refreshToken);localStorage.setItem('unreal-tran:web:preferences:v1',JSON.stringify({themeMode:'light'}));},session);
- 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.__workbenchState=()=>{const e=activeTraining;if(!e?.sceneReady)return null;const b=e.bridgePartsWorkbench;return {hide:e.viewerHideOthers,step:e.session.stepIndex,completed:[...e.session.completed],focus:e.inspection.focused?.name,tween:!!e.viewerCameraTween,stored:[...(b?.items.values()||[])].filter(i=>i.stored).map(i=>{const materials=[];i.part.traverse(o=>{if(o.isMesh&&!o.userData.trainingPickProxy)for(const m of Array.isArray(o.material)?o.material:[o.material])materials.push({actual:m.opacity,baseline:e.viewerMaterialBaseline.get(m)?.opacity,visible:o.visible});});return {id:i.id,materials};})};};`});
- });
- page.on('pageerror',error=>errors.push(error.message));
- const state=()=>page.evaluate(()=>globalThis.__workbenchState?.());
- const settle=async()=>{await page.waitForTimeout(1100);await expect.poll(async()=>{const s=await state();return s&&!s.tween;}).toBeTruthy();};
- try{
- for(const id of [88,89,86,87]){
- await page.goto('http://127.0.0.1:6180/teaching/virtual-training/preview/'+id);
- await expect(page.locator('[data-role="loading"]')).toHaveClass(/is-hidden/,{timeout:120000});
- await page.locator('[data-intro-command="skip"]').click();await settle();
- if(await page.locator('[data-toolbox-toggle]').count())await page.locator('[data-toolbox-toggle]').click();
- if(id===86||id===87){await expect(page.locator('.training-parts-tray')).toBeHidden();checks.push({id,check:'no storage workflow: no empty workbench UI'});continue;}
- const hide=page.locator('[data-action="toggle-hide-others"]');if(!await hide.isVisible())await page.locator('[data-viewer-action="tools"]').click();
- await hide.click();assert.equal((await state()).hide,true);
- await page.locator('.training-parts-tray summary').click();await page.locator('[data-tray-focus=""]').click();await settle();
- const s=await state();assert.equal(s.hide,false);assert.equal(s.step,0);assert.deepEqual(s.completed,[]);assert.equal(s.focus,'零件暂存工作台');
- await expect(hide).toHaveAttribute('aria-pressed','false');
- for(const item of s.stored)for(const mat of item.materials){assert.equal(mat.actual,mat.baseline);assert.equal(mat.visible,true);}
- await page.screenshot({path:dir+'/task-'+id+'-workbench-light.png'});
- await page.locator('[data-tray-return]').click();await settle();assert.notEqual((await state()).focus,'零件暂存工作台');
- checks.push({id,check:'workbench focus exits isolation; stored parts visible and opaque; return does not advance',stored:s.stored.map(i=>i.id)});
- }
- assert.deepEqual(errors,[]);fs.writeFileSync(dir+'/result.json',JSON.stringify({pass:true,checks,errors},null,2));
- }catch(error){await page.screenshot({path:dir+'/failure.png'}).catch(()=>{});fs.writeFileSync(dir+'/result.json',JSON.stringify({pass:false,error:error.message,checks,errors,state:await state()},null,2));throw error;}
- finally{await browser.close();}
|