|
- import fs from 'node:fs';
- import assert from 'node:assert/strict';
- import {chromium,expect} from '@playwright/test';
- import {login,call} from './role-permissions-live.mjs';
- const dir='reports/bridge-tools-authoring-20260924';fs.mkdirSync(dir,{recursive:true});
- const fixture=JSON.parse(fs.readFileSync('reports/bridge-content-authoring-20260924/fixture.json','utf8'));
- 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:1000}});
- 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);
- page.on('pageerror',e=>errors.push(e.message));
- const api=async ep=>{const r=await call('tran/v1/'+ep,session.accessToken);assert.equal(r.status,200);return r.data;};
- const ready=()=>expect(page.getByRole('button',{name:'播放动作',exact:true})).toBeEnabled({timeout:120000});
- try{
- const before=new Map();for(const item of fixture.items)before.set(item.taskId,(await api('teaching/assignments/'+item.taskId)).definitionSnapshot);
- for(const item of fixture.items){
- if(process.env.PREVIEW_ONLY==='1'&&!['88','89'].includes(item.taskId))continue;
- await page.goto('http://127.0.0.1:6180/content/models/'+item.modelProjectId+'/production');await ready();
- const model=await api('content/projects/'+item.modelProjectId),actions=model.currentVersion.content.productionActions;
- const chosen=actions.findIndex(a=>/bolt-1$/.test(a.targetId));
- await page.locator('.production-action-item').nth(Math.max(0,chosen)).click();
- await expect(page.getByText('学员操作',{exact:true})).toBeVisible();
- if(chosen>=0){
- await expect(page.getByText('所需工具',{exact:true})).toBeVisible();
- await expect(page.getByText('工具作用部件',{exact:true})).toBeVisible();
- await page.getByRole('button',{name:'播放动作',exact:true}).click();await page.waitForTimeout(600);
- await page.screenshot({path:dir+'/'+item.taskCode+'-tool-preview.png'});await ready();
- }
- if(process.env.PREVIEW_ONLY==='1'){checks.push({task:item.taskCode,preview:true});continue;}
- // Publish only the authoring chain. The existing task points at its old fixed
- // snapshot; the assertion below protects all four active simulations.
- await page.getByRole('button',{name:'发布并进入场景',exact:true}).click();await expect(page).toHaveURL(new RegExp('/scenes/'+item.sceneProjectId+'/production'));await ready();
- await page.getByRole('button',{name:'发布并进入编排',exact:true}).click();await expect(page).toHaveURL(new RegExp('/training-projects/'+item.trainingProjectId+'/production'));await ready();
- await page.getByRole('button',{name:'发布训练内容',exact:true}).click();await expect(page.getByText('训练内容已发布;现有仿真仍保持固定版本')).toBeVisible();
- const training=await api('content/projects/'+item.trainingProjectId);
- const bindings=training.currentVersion.content.steps.flatMap(s=>s.modelActions||[]);
- assert.equal(bindings.length,item.actions);assert.ok(bindings.every(a=>a.toolAction&&a.toolAction.trigger));
- if(chosen>=0)assert.ok(bindings.some(a=>a.toolAction.trigger==='tool-drop'));
- await page.screenshot({path:dir+'/'+item.taskCode+'-training.png'});
- checks.push({task:item.taskCode,bindings:bindings.length,modelProject:item.modelProjectId,sceneProject:item.sceneProjectId,trainingProject:item.trainingProjectId,version:training.project.publishedVersionId});
- console.log(item.taskCode+' authoring tools published');
- }
- for(const item of fixture.items)assert.deepEqual((await api('teaching/assignments/'+item.taskId)).definitionSnapshot,before.get(item.taskId),'fixed simulation unchanged');
- assert.deepEqual(errors,[]);fs.writeFileSync(dir+(process.env.PREVIEW_ONLY==='1'?'/preview-result.json':'/result.json'),JSON.stringify({pass:true,checks,errors,existingTasksUnchanged:true},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},null,2));throw error;}finally{await browser.close();}
|