74 lines
5.3 KiB
JavaScript
74 lines
5.3 KiB
JavaScript
const {chromium}=require('playwright-core'),assert=require('node:assert/strict'),fs=require('node:fs');
|
|
const root='D:/web/dj/integration-work/',base='http://127.0.0.1:18885';
|
|
const fixture=JSON.parse(fs.readFileSync(root+'hd-test-panels/shot-ui-fixture.json'));
|
|
(async()=>{
|
|
const browser=await chromium.launch({channel:'chrome',headless:true});
|
|
try{
|
|
const page=await browser.newPage({viewport:{width:1700,height:1150}}),errors=[];
|
|
page.on('pageerror',e=>errors.push(e.message));
|
|
let submitted=null,replacement=null;
|
|
await page.route('**/api/v1/tasks**',async route=>{
|
|
const req=route.request(),u=new URL(req.url());
|
|
if(req.method()==='POST'&&u.pathname==='/api/v1/tasks'){
|
|
submitted=req.postDataJSON();
|
|
replacement={id:fixture.ids[1]+100,type:'video',storyboard_id:1,drama_id:1,provider:'minimax',model:submitted.model,config_id:submitted.config_id,
|
|
task_id:'ui-new-job',status:'processing',stage:'polling',created_at:new Date().toISOString(),params:JSON.stringify({gpu:submitted.gpu}),routing:{gpu:'gpu1',port:8189,legacy:false}};
|
|
return route.fulfill({status:201,contentType:'application/json',body:JSON.stringify({data:replacement})});
|
|
}
|
|
if(req.method()==='GET'&&replacement){
|
|
if(u.pathname==='/api/v1/tasks/'+replacement.id)return route.fulfill({json:{data:replacement}});
|
|
if(u.pathname==='/api/v1/tasks'){
|
|
const response=await route.fetch(),json=await response.json();
|
|
json.data=json.data.map(t=>t.id===fixture.ids[0]?{...t,status:'failed',error_code:'user_cancelled'}:t);
|
|
if(!u.searchParams.has('type')||u.searchParams.get('type')==='video')json.data.push(replacement);
|
|
return route.fulfill({response,json});
|
|
}
|
|
}
|
|
return route.continue();
|
|
});
|
|
await page.route('**/api/v1/episodes/1/generation-tasks',async route=>{
|
|
const response=await route.fetch(),json=await response.json();
|
|
if(replacement){json.data.tasks=json.data.tasks.map(t=>t.id===fixture.ids[0]?{...t,status:'failed',error_code:'user_cancelled'}:t);json.data.tasks.push(replacement)}
|
|
return route.fulfill({response,json});
|
|
});
|
|
await page.goto(base+'/drama/1/episode/1',{waitUntil:'networkidle'});
|
|
await page.getByRole('navigation').getByRole('button',{name:/^视频制作/}).click();
|
|
const rows=page.locator('.video-task-row'),gpu=page.getByLabel('本次生成显卡',{exact:true});
|
|
const actual=page.getByTestId('shot-actual-routing');
|
|
await actual.filter({hasText:'GPU2 · ComfyUI 8188'}).waitFor();
|
|
const top=page.locator('.studio-topbar .model-select').filter({has:page.locator('.model-select-label',{hasText:'视频默认'})});
|
|
const beforeDefault=await top.innerText();
|
|
const shotModel=page.locator('.video-inspector-settings .model-select');
|
|
await shotModel.locator('button').click();
|
|
await page.getByText('GPU1 · ComfyUI 8189 · MiniMax-H3',{exact:true}).last().click();
|
|
await gpu.selectOption('gpu1');
|
|
assert.equal(await top.innerText(),beforeDefault);
|
|
await rows.nth(1).click();
|
|
assert.equal(await gpu.inputValue(),'gpu3');
|
|
assert.match(await actual.innerText(),/GPU3 · ComfyUI 8191/);
|
|
await rows.first().click();assert.equal(await gpu.inputValue(),'gpu1');
|
|
// Before submission, the current-job badge still reports the old confirmed worker.
|
|
assert.match(await actual.innerText(),/GPU2 · ComfyUI 8188/);
|
|
await page.getByRole('button',{name:'取消并换卡重新生成',exact:true}).click();
|
|
await actual.filter({hasText:'GPU1 · ComfyUI 8189'}).waitFor();
|
|
assert.equal(submitted.storyboard_id,1);assert.equal(submitted.replace_task_id,fixture.ids[0]);assert.equal(submitted.gpu,'gpu1');assert.equal(submitted.config_id,11);
|
|
assert.match(await rows.nth(1).locator('.video-task-routing').innerText(),/GPU3 :8191/);
|
|
assert.match(await rows.first().locator('.video-task-state').innerText(),/生成中/);
|
|
await page.screenshot({path:root+'shot-specific-routing-ui.png'});
|
|
await page.reload({waitUntil:'networkidle'});
|
|
await page.getByRole('navigation').getByRole('button',{name:/^视频制作/}).click();
|
|
await actual.filter({hasText:'GPU1 · ComfyUI 8189'}).waitFor();
|
|
await page.getByRole('navigation').getByRole('button',{name:/^高清制作/}).click();
|
|
const hdGpu=page.getByLabel('高清生成显卡',{exact:true});await hdGpu.waitFor();
|
|
await hdGpu.selectOption('gpu1');await page.getByLabel('目标分辨率').selectOption('4K');
|
|
const shots=page.locator('.hd-shots button');await shots.nth(1).click();
|
|
assert.notEqual(await hdGpu.inputValue(),'gpu1');assert.equal(await page.getByLabel('目标分辨率').inputValue(),'2K');
|
|
await hdGpu.selectOption('gpu3');await shots.first().click();
|
|
assert.equal(await hdGpu.inputValue(),'gpu1');assert.equal(await page.getByLabel('目标分辨率').inputValue(),'4K');
|
|
await page.locator('.hd-studio').getByRole('button',{name:'刷新',exact:true}).click();assert.equal(await hdGpu.inputValue(),'gpu1');
|
|
assert.deepEqual(errors,[]);
|
|
fs.writeFileSync(root+'shot-routing-ui-result.json',JSON.stringify({passed:true,checks:['per-shot model and GPU choices','batch default unchanged','exact selected task replacement','confirmed routing appears only after submission','other shot unchanged','routing survives reload','HD settings scoped per shot'],errors},null,2));
|
|
console.log('PASS: individual shot model/GPU selection and actual worker badges, persistent task routing, independent HD choices');
|
|
}finally{await browser.close()}
|
|
})().catch(e=>{console.error(e.stack);process.exit(1)});
|