Cover progressive material outcomes in browser tests
Why: The r0.4 acceptance must show running findings, zero and partial failure, and a source-bound choice in the real UI. Evidence: Six task-owned HTTP/Playwright cases passed; npm test (265 tests) and npm run build passed. Impact: Browser test coverage only; no production UI change. Refs: U3 r0.4 Task 6
This commit is contained in:
@@ -7,22 +7,24 @@ test.skip(!manifestPath,'Run explicitly with a task-owned mechanism instance man
|
||||
const manifest=manifestPath?JSON.parse(readFileSync(manifestPath,'utf8')):null
|
||||
if(manifest&&(manifest.mode!=='mechanism'||!manifest.dataDir.includes('fast-slow-u2-u3-')||readlinkSync(`/proc/${manifest.pid}/exe`)!==manifest.binary||createHash('sha256').update(readFileSync(manifest.binary)).digest('hex')!==manifest.binarySHA256))throw new Error('Owned mechanism instance verification failed')
|
||||
|
||||
async function setup(request:any){
|
||||
type Scenario='normal'|'slow-stages'|'zero-failure'|'partial-failure'|'choice'
|
||||
async function setup(request:any,scenario:Scenario='normal',awaitTask=true){
|
||||
const project=await(await request.post(manifest.base+'/api/projects',{data:{name:'browser-'+Date.now()}})).json()
|
||||
const conv=await(await request.post(manifest.base+`/api/projects/${project.id}/conversations`,{data:{title:'材料整理',profileId:'checkpoint-eval'}})).json()
|
||||
const ids:string[]=[]
|
||||
for(let i=0;i<3;i++){
|
||||
const res=await request.post(manifest.base+`/api/projects/${project.id}/uploads`,{multipart:{file:{name:`来源${i+1}.txt`,mimeType:'text/plain',buffer:Buffer.from('上线六月。验收条件需要补齐,预算50万元尚未审批。交付包含12项需求,其中3项依赖外部接口。第一期先完成8项核心需求。\n\n'+('整理记录说明:保留日期、金额、限制和待确认事项。\n\n').repeat(100))}}})
|
||||
const marker=i===0&&scenario!=='normal'?`[fixture:${scenario}]\n`:''
|
||||
const res=await request.post(manifest.base+`/api/projects/${project.id}/uploads`,{multipart:{file:{name:`来源${i+1}.txt`,mimeType:'text/plain',buffer:Buffer.from(marker+'上线六月。验收条件需要补齐,预算50万元尚未审批。交付包含12项需求,其中3项依赖外部接口。第一期先完成8项核心需求。\n\n'+('整理记录说明:保留日期、金额、限制和待确认事项。\n\n').repeat(100))}}})
|
||||
expect(res.ok()).toBeTruthy();ids.push((await res.json()).artifactId)
|
||||
}
|
||||
const sent=await request.post(manifest.base+`/api/conversations/${conv.id}/messages`,{data:{text:'',attachmentIds:ids,requestId:'browser-'+Date.now()}})
|
||||
expect(sent.ok()).toBeTruthy()
|
||||
const sendBody=await sent.json()
|
||||
await expect.poll(async()=> (await(await request.get(manifest.base+`/api/runs/${sendBody.run.id}`)).json()).run.status).toBe('completed')
|
||||
await expect.poll(async()=>{
|
||||
if(awaitTask)await expect.poll(async()=>{
|
||||
const out=await(await request.get(manifest.base+`/api/conversations/${conv.id}/cards`)).json()
|
||||
return out.cards.find((c:any)=>c.task)?.task.executionState
|
||||
}).toBe('completed')
|
||||
}).toBe(scenario.endsWith('failure')?'failed':'completed')
|
||||
return {project,conv,ids}
|
||||
}
|
||||
async function open(page:any,seed:any){
|
||||
@@ -61,3 +63,34 @@ test('background replay does not steal the current file, focus or viewport',asyn
|
||||
await expect(composer).toBeFocused();await expect(composer).toHaveValue('正在记录自己的想法')
|
||||
expect(await page.locator('.tab-strip').textContent()).toBe(tabs)
|
||||
})
|
||||
test('two sourced stages appear while the material task is still running',async({page,request})=>{
|
||||
const seed=await setup(request,'slow-stages',false)
|
||||
await open(page,seed)
|
||||
const cards=async()=>(await(await request.get(manifest.base+`/api/conversations/${seed.conv.id}/cards`)).json()).cards
|
||||
await expect.poll(async()=>{const card=(await cards()).find((c:any)=>c.task);return card?.task.executionState}).toBe('running')
|
||||
await expect(page.locator('[data-conversation-work]')).toContainText('上线六月')
|
||||
await expect.poll(async()=>{const card=(await cards()).find((c:any)=>c.task);return card?.task.findings?.length}).toBeGreaterThan(1)
|
||||
await expect(page.locator('[data-conversation-work]')).toContainText('验收条件需要补齐')
|
||||
await expect.poll(async()=>{const card=(await cards()).find((c:any)=>c.task);return card?.task.executionState}).toBe('completed')
|
||||
})
|
||||
for(const scenario of ['zero-failure','partial-failure'] as const){
|
||||
test(`${scenario} shows the saved scope without a deliverable choice`,async({page,request})=>{
|
||||
const seed=await setup(request,scenario)
|
||||
await page.addInitScript(({id}:{id:string})=>{localStorage.setItem('as.conv',id);localStorage.setItem('as.ui',JSON.stringify({theme:'light',rightCollapsed:true,fontSize:14}))},{id:seed.conv.id})
|
||||
await page.goto('/')
|
||||
const work=page.locator('[data-conversation-work]')
|
||||
await expect(work).toContainText('执行失败')
|
||||
if(scenario==='zero-failure')await expect(work).toContainText('暂无阶段结论记录')
|
||||
else await expect(work).toContainText('上线六月')
|
||||
await expect(page.locator('.hitl-choice')).toHaveCount(0)
|
||||
})
|
||||
}
|
||||
test('completed sourced work offers only its grounded suggestions',async({page,request})=>{
|
||||
const seed=await setup(request,'choice')
|
||||
await open(page,seed)
|
||||
await expect(page.locator('.hitl-choice')).toHaveCount(3)
|
||||
for(const label of ['会议摘要','验收清单','联调计划'])await expect(page.locator('.hitl-choice').filter({hasText:label})).toHaveCount(1)
|
||||
await expect(page.locator('.hitl-card')).toContainText('基于整理结果,接下来生成什么?')
|
||||
await page.reload()
|
||||
await expect(page.locator('.hitl-choice')).toHaveCount(3)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user