const { chromium } = require('playwright-core'); const assert = require('node:assert/strict'); const path = require('node:path'); (async () => { const browser = await chromium.launch({channel:'chrome',headless:true}); const errors=[]; try { const page = await browser.newPage({viewport:{width:1600,height:1120}}); page.setDefaultTimeout(10000); await page.addInitScript(()=>localStorage.setItem('huobao:tours',JSON.stringify(['episode']))); page.on('pageerror',error=>{errors.push(error.message);console.log('UI ERROR',error.message)}); await page.route('**/api/v1/tasks',route=>route.request().method()==='POST'?route.abort():route.continue()); await page.goto('http://127.0.0.1:18930/drama/1/episode/2',{waitUntil:'networkidle'}); const tourClose=page.locator('.driver-popover-close-btn'); if(await tourClose.isVisible()) await tourClose.click(); await page.getByText('视频制作',{exact:true}).first().click(); const panel=page.locator('.continuity-panel'); await panel.waitFor(); assert.match(await panel.innerText(),/接第 1 集 · 分镜 2/); await panel.getByLabel('本镜头开始状态').fill('右手持剑,位于画面左侧,向右继续行走'); await panel.getByRole('button',{name:'保存衔接',exact:true}).click(); await page.waitForFunction(()=>document.querySelector('.continuity-actions')?.textContent.includes('衔接设置已保存')); await panel.getByRole('button',{name:'预览前镜头尾帧',exact:true}).click(); await page.waitForFunction(()=>{const img=document.querySelector('.continuity-panel img');return img&&img.complete&&img.naturalWidth>0}); const data=await page.evaluate(async()=> (await (await fetch('/api/v1/storyboards/3/continuity')).json()).data); assert.match(data.startState,/右手持剑/); await panel.scrollIntoViewIfNeeded(); await page.screenshot({path:path.join(process.env.CONTINUITY_FIXTURE,'continuity-ui.png')}); await page.setViewportSize({width:1280,height:850}); assert.equal(await panel.evaluate(e=>e.scrollWidth<=e.clientWidth+2),true); assert.deepEqual(errors,[]); console.log('PASS: cross-episode source label, state save, decoded tail-frame preview, narrow layout, no runtime errors; no video generation'); } finally { await browser.close(); } })().catch(error=>{console.error(error.stack);process.exit(1)});