Files
dj/integration-work/browser-test/verify_video_action_ui.cjs

46 lines
3.3 KiB
JavaScript

// Exercise visibility/hit testing at short window heights without submitting jobs.
const {chromium}=require('playwright-core'),assert=require('node:assert/strict'),fs=require('node:fs');
(async()=>{
const root='D:/web/dj',base=process.env.VERIFY_INSTALLED ? JSON.parse(fs.readFileSync(root+'/huobao-data/last-launch.json')).api.replace('/api/v1','') : 'http://127.0.0.1:18938';
const browser=await chromium.launch({channel:'chrome',headless:true});
try {
const page=await browser.newPage(),errors=[];let pending=false;
page.on('pageerror',e=>errors.push(e.message));
await page.addInitScript(()=>localStorage.setItem('huobao:tours',JSON.stringify(['episode'])));
await page.route('**/api/**',async route=>{
if(!['GET','HEAD'].includes(route.request().method()))return route.abort();
if(pending&&route.request().url().includes('/generation-tasks')){
const response=await route.fetch(),body=await response.json(),task=body.data.tasks.find(t=>t.id===237);
assert.ok(task);task.status='processing';task.stage='running';task.result_url=null;
task.params=JSON.stringify({...JSON.parse(task.params||'{}'),progress:{phase:'sampling',step:9,totalSteps:20,observedAt:Date.now(),stepUpdatedAt:Date.now(),samplingMinSeconds:600,samplingMaxSeconds:900,historySamples:3,historyMinSeconds:1200,historyMaxSeconds:1800}});
return route.fulfill({response,json:body});
}
return route.continue();
});
async function open(){
await page.goto(base+'/drama/6/episode/1',{waitUntil:'networkidle'});
await page.getByText('视频制作',{exact:true}).first().click();
await page.locator('.video-inspector-action').waitFor();
}
async function reachable(){
const result=await page.locator('.video-inspector-action').evaluate(el=>{
const r=el.getBoundingClientRect(),p=el.closest('.video-task-inspector').getBoundingClientRect();
return {visible:r.top>=Math.max(0,p.top)&&r.bottom<=Math.min(innerHeight,p.bottom)+1,hit:el.contains(document.elementFromPoint(r.x+r.width/2,r.y+r.height/2))};
});assert.deepEqual(result,{visible:true,hit:true});
}
for(const viewport of [{width:1600,height:1100},{width:1257,height:827},{width:1280,height:720},{width:1280,height:600}]){
await page.setViewportSize(viewport);await open();
assert.match(await page.locator('.video-inspector-action').innerText(),/重新生成当前分镜视频/);
assert.equal(await page.getByRole('button',{name:'重新拆分',exact:true}).count(),1);
await reachable();
await page.getByLabel('本次生成显卡',{exact:true}).scrollIntoViewIfNeeded();await reachable();
await page.locator('.video-inspector-scroll').evaluate(el=>el.scrollTop=0);await reachable();
if(viewport.height===827)await page.screenshot({path:root+'/integration-work/video-action-visible.png'});
}
pending=true;await open();await page.locator('.video-task-inspector .task-progress').waitFor();
assert.match(await page.locator('.video-inspector-action').innerText(),/取消并换卡重新生成/);
await reachable();await page.locator('.video-inspector-scroll').evaluate(el=>el.scrollTop=el.scrollHeight);await reachable();
assert.deepEqual(errors,[]);console.log('PASS: regeneration/replacement action visible and hit-testable at 4 window sizes, scroll top/bottom and active progress; no writes');
}finally{await browser.close()}
})().catch(e=>{console.error(e.stack);process.exit(1)});