From 15542e977ad8a768583631c2ef5e43b17355364d Mon Sep 17 00:00:00 2001 From: Codex Bot Date: Fri, 30 Oct 2026 18:30:20 +0800 Subject: [PATCH] Verify unsaved canvas edits survive arriving agent results --- .../tests/canvas-ui-integration.ts | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/apps/waterfall-wiki/tests/canvas-ui-integration.ts b/apps/waterfall-wiki/tests/canvas-ui-integration.ts index 209028a..a2d633d 100644 --- a/apps/waterfall-wiki/tests/canvas-ui-integration.ts +++ b/apps/waterfall-wiki/tests/canvas-ui-integration.ts @@ -39,11 +39,31 @@ export async function verifyCanvasAgentUI(base:string){ assert.equal((await patch({status:'running'})).status,200); await panel.getByText(/Agent 正在处理/).waitFor(); // This fixture verifies the external-client protocol and UI delivery, not model quality. - const generated='第一镜:晨光穿过窗边的植物。'; + let generated='第一镜:晨光穿过窗边的植物。'; assert.equal((await patch({status:'succeeded',result:{text:generated}})).status,200); await page.locator('[data-node-id="shot"] [data-node-content]').getByText(generated,{exact:true}).waitFor(); const updated=await fetch(base+root,{headers:ownerHeaders}).then(r=>r.json()); assert.equal(updated.document.cards.find((n:{id:string})=>n.id==='shot').instruction,'根据参考资料写六个分镜'); + await panel.getByRole('button',{name:'关闭 Agent 连接',exact:true}).click(); + await shot.click();await shot.click(); + await composer.getByRole('textbox',{name:'创作要求',exact:true}).fill('再写一个新镜头'); + const queued=page.waitForResponse(r=>r.request().method()==='POST'&&new URL(r.url()).pathname===root+'/tasks'); + await composer.getByRole('button',{name:'交给 Agent',exact:true}).click(); + const queuedResponse=await queued;assert.equal(queuedResponse.status(),201);const secondTask=await queuedResponse.json(); + await panel.getByRole('button',{name:'关闭 Agent 连接',exact:true}).click(); + const brief=page.locator('[data-node-id="brief"] [data-node-content]');await brief.click();await brief.click(); + const localText=page.getByRole('textbox',{name:'01 / 创意简报 内容',exact:true});await localText.fill('用户尚未同步的本机修改'); + const nextTask=root+'/tasks/'+secondTask.id; + const nextPatch=(body:unknown)=>fetch(base+nextTask,{method:'PATCH',headers:agentHeaders,body:JSON.stringify(body)}); + assert.equal((await nextPatch({status:'running'})).status,200); + generated='第二镜:城市在雨后醒来。'; + assert.equal((await nextPatch({status:'succeeded',result:{text:generated}})).status,200); + await page.getByRole('button',{name:'Agent · 在线画布',exact:true}).click(); + await panel.getByRole('button',{name:'载入在线版本',exact:true}).waitFor(); + assert.equal(await localText.inputValue(),'用户尚未同步的本机修改','Polling must not replace unsaved local work'); + await panel.getByRole('button',{name:'载入在线版本',exact:true}).click(); + await page.locator('[data-node-id="shot"] [data-node-content]').getByText(generated,{exact:true}).waitFor(); + assert.equal(await page.locator('[data-node-id="brief"] [data-node-content]').textContent(),state.document.cards.find((n:{id:string})=>n.id==='brief').text); await panel.getByRole('button',{name:'生成连接凭据',exact:true}).click(); await page.waitForFunction(old=>{const field=document.querySelector('textarea[aria-label="Agent 连接凭据"]');return !!field&&JSON.parse(field.value).authorization!==old},first.authorization); const second=JSON.parse(await credentials.inputValue());assert.equal((await fetch(base+root,{headers:agentHeaders})).status,404);