Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 

51 linhas
3.8 KiB

  1. import {chromium,expect} from '@playwright/test';
  2. import assert from 'node:assert/strict';
  3. import fs from 'node:fs';
  4. import {login,call} from './role-permissions-live.mjs';
  5. const dir='reports/bridge-model-match-20260914',session=await login('root');
  6. const fixture=fs.readdirSync(dir).filter(f=>f.startsWith('fixtures-')).flatMap(f=>JSON.parse(fs.readFileSync(dir+'/'+f))).find(f=>f.code==='TASK-VIRTUAL-007');
  7. const result=await call('tran/v1/teaching/assignments/'+fixture.taskId,session.accessToken);assert.equal(result.status,200);
  8. const browser=await chromium.launch({channel:'msedge',headless:true,args:['--enable-unsafe-swiftshader']});
  9. const page=await browser.newPage({viewport:{width:1600,height:1000}}),checks=[],errors=[];
  10. await page.addInitScript(s=>sessionStorage.setItem('unreal-tran:web:access-token:v1',s.accessToken),session);
  11. page.on('pageerror',e=>errors.push(e.message));
  12. const diag=()=>page.evaluate(()=>globalThis.__trainingSceneDiagnostics());
  13. try{
  14. // LAN entry exercises the same Gateway-backed preview as localhost.
  15. await page.goto(`http://192.168.31.168:6180/teaching/virtual-training/preview/${fixture.taskId}`);
  16. await expect(page.locator('[data-role="loading"]')).toHaveClass(/is-hidden/,{timeout:120000});await page.waitForTimeout(1500);
  17. const teacher=page.locator('[aria-label="关闭数字教员"]');if(await teacher.isVisible())await teacher.click();
  18. const initial=await diag();
  19. const old=initial.bridgeWorkshop.targets.find(t=>t.id==='bridge-old-pump');
  20. for(const key of ['min','max'])assert.ok(old.worldBounds[key].every((v,i)=>Math.abs(v-initial.bridgeWorkshop.modelBinding.sourceBounds[key][i])<1e-6));
  21. for(let i=0;i<4;i++){
  22. const ops=result.data.definitionSnapshot.steps[i].action.mechanism.steps;
  23. for(let j=0;j<ops.length;j++){
  24. await page.waitForTimeout(550);
  25. const response=j===ops.length-1?page.waitForResponse(r=>r.url().includes('/preview/validate')):null;
  26. if(i===3){
  27. const d=await diag(),t=d.framing.targetOnScreen;
  28. assert.ok(t.insideCanvas);assert.deepEqual(t.coveredBy,[]);
  29. const rect=await page.locator('[data-role="canvas"]').boundingBox();
  30. await page.mouse.click(rect.x+t.localX,rect.y+t.localY);
  31. checks.push(`Canvas picking ${ops[j].targetId}`);
  32. }else await page.locator('[data-role="part-label"]').click();
  33. if(response)assert.equal((await response).status(),200);
  34. else await expect.poll(async()=>(await diag()).bridgeWorkshop.operationIndex).toBe(j+1);
  35. }
  36. await expect(page.locator('[data-action="next"]')).toBeEnabled();
  37. if(i<3)await page.locator('[data-action="next"]').click();
  38. }
  39. const positions=()=>diag().then(d=>d.bridgeWorkshop.targets.map(t=>[t.id,t.position,t.visible]));
  40. const before=await positions();
  41. await page.locator('[data-action="viewer-reset-view"]').click();await page.waitForTimeout(800);
  42. assert.deepEqual(await positions(),before,'camera reset must preserve dismantled state');
  43. await page.screenshot({path:`${dir}/TASK-VIRTUAL-007-context.png`});
  44. checks.push('camera reset preserves actual pump/bolt state');
  45. await page.reload();await expect(page.locator('[data-role="loading"]')).toHaveClass(/is-hidden/,{timeout:120000});await page.waitForTimeout(1000);
  46. const reloaded=await diag();assert.deepEqual(reloaded.bridgeWorkshop.modelBinding.sourceBounds,initial.bridgeWorkshop.modelBinding.sourceBounds);
  47. checks.push('reload preserves source placement');assert.deepEqual(errors,[]);
  48. fs.writeFileSync(`${dir}/picking.json`,JSON.stringify({pass:true,checks,errors},null,2));
  49. }catch(e){await page.screenshot({path:`${dir}/picking-failure.png`});fs.writeFileSync(`${dir}/picking-diagnostic.json`,JSON.stringify(await diag(),null,2));fs.writeFileSync(`${dir}/picking.json`,JSON.stringify({pass:false,error:e.message,checks,errors,feedback:await page.locator('.el-message').allTextContents()},null,2));throw e;}
  50. finally{await browser.close();}