|
|
@@ -11,7 +11,8 @@ import {
|
|
|
import type {} from '@deepseek-ai/dsh-agent'
|
|
|
import { snapshotSubagentDescriptor } from '@deepseek-ai/dsh-subagent'
|
|
|
import {
|
|
|
- captureStableAria, compareOrRefreshGolden, launchWebScaffold, watchConsole,
|
|
|
+ acknowledgeReloadConnectionLoss, captureStableAria, compareOrRefreshGolden,
|
|
|
+ launchWebScaffold, watchConsole,
|
|
|
webSnapshotMode, type WebScaffold,
|
|
|
} from './scaffold.ts'
|
|
|
import { connectFreshWorkspace, saveFailureShot } from './support.ts'
|
|
|
@@ -73,6 +74,7 @@ describe('web e2e: persisted subagent conversation and human continuation', () =
|
|
|
scaffold = await launchWebScaffold({
|
|
|
replayFixture: BASE_FIXTURE,
|
|
|
replayChildFixtures: [childFixturePath],
|
|
|
+ paceMs: 25,
|
|
|
})
|
|
|
browser = await chromium.launch()
|
|
|
page = await browser.newPage({ viewport: { width: 1680, height: 1000 } })
|
|
|
@@ -209,7 +211,20 @@ describe('web e2e: persisted subagent conversation and human continuation', () =
|
|
|
label: NESTED_LABEL, activity: 'inactive', hasChildren: false,
|
|
|
},
|
|
|
])
|
|
|
- await page.getByRole('button', { name: '2 个子代理' }).waitFor({ timeout: 15_000 })
|
|
|
+ // These two cold fixtures were authored after the page's initial
|
|
|
+ // session.list and intentionally emitted no session-added frame. Reload
|
|
|
+ // to exercise the restart baseline that discovers their full lineage.
|
|
|
+ const warningStart = tripwire.warnings.length
|
|
|
+ await page.reload({ waitUntil: 'load' })
|
|
|
+ await page.waitForSelector('[class*="frame"]', { timeout: 30_000 })
|
|
|
+ const catalogButton = page.getByRole('button', { name: /个子代理/ })
|
|
|
+ await catalogButton.waitFor({ timeout: 15_000 })
|
|
|
+ await catalogButton.click()
|
|
|
+ const catalogTree = page.getByRole('tree', { name: '子代理会话' })
|
|
|
+ await catalogTree.getByRole('treeitem').nth(1).waitFor({ timeout: 15_000 })
|
|
|
+ await catalogTree.press('Escape')
|
|
|
+ await page.getByRole('button', { name: '3 个子代理' }).waitFor({ timeout: 15_000 })
|
|
|
+ acknowledgeReloadConnectionLoss(tripwire, warningStart)
|
|
|
}, 120_000)
|
|
|
|
|
|
afterAll(async () => {
|
|
|
@@ -226,7 +241,7 @@ describe('web e2e: persisted subagent conversation and human continuation', () =
|
|
|
|
|
|
it('expands a persisted grandchild progressively without activating either level', async () => {
|
|
|
onTestFailed(() => saveFailureShot(page, 'web-e2e-subagent-tree'))
|
|
|
- await page.getByRole('button', { name: '2 个子代理' }).click()
|
|
|
+ await page.getByRole('button', { name: '3 个子代理' }).click()
|
|
|
expect(await page.getByRole('button', {
|
|
|
name: `展开 ${ONE_SHOT_LABEL} 的下级子代理`,
|
|
|
}).count()).toBe(0)
|
|
|
@@ -245,7 +260,7 @@ describe('web e2e: persisted subagent conversation and human continuation', () =
|
|
|
|
|
|
it('opens the completed child from persistence without activating it', async () => {
|
|
|
onTestFailed(() => saveFailureShot(page, 'web-e2e-subagent-open'))
|
|
|
- await page.getByRole('button', { name: '2 个子代理' }).click()
|
|
|
+ await page.getByRole('button', { name: '3 个子代理' }).click()
|
|
|
await page.getByRole('treeitem', { name: new RegExp(LABEL) }).click()
|
|
|
await expect.poll(
|
|
|
() => page.getByText(INITIAL_PROMPT, { exact: true }).count(),
|
|
|
@@ -281,7 +296,26 @@ describe('web e2e: persisted subagent conversation and human continuation', () =
|
|
|
const input = page.getByRole('textbox', { name: 'Message the agent' })
|
|
|
await input.fill(FOLLOWUP)
|
|
|
await input.press('Enter')
|
|
|
+ await expect.poll(
|
|
|
+ () => scaffold.ctx.agents.get(childId)?.status,
|
|
|
+ { timeout: 10_000 },
|
|
|
+ ).toBe('running')
|
|
|
+ const hierarchy = page.getByRole('navigation', { name: 'Session hierarchy' })
|
|
|
+ await hierarchy.getByRole('button').first().click()
|
|
|
+ const runningTrigger = page.getByRole('button', { name: '3 个子代理,正在运行' })
|
|
|
+ await runningTrigger.waitFor({ timeout: 10_000 })
|
|
|
+ expect(await runningTrigger.locator('[data-state="ongoing"]').count()).toBe(1)
|
|
|
+ await runningTrigger.click()
|
|
|
+ await page.getByRole('treeitem', {
|
|
|
+ name: new RegExp(`${LABEL}.*正在运行`),
|
|
|
+ }).waitFor({ timeout: 10_000 })
|
|
|
await ended
|
|
|
+ await page.getByRole('treeitem', {
|
|
|
+ name: new RegExp(`${LABEL}.*当前未运行`),
|
|
|
+ }).waitFor({ timeout: 10_000 })
|
|
|
+ expect(await page.getByRole('button', { name: '3 个子代理' })
|
|
|
+ .locator('[data-state="ongoing"]').count()).toBe(0)
|
|
|
+ await page.getByRole('treeitem', { name: new RegExp(LABEL) }).click()
|
|
|
await expect.poll(() => page.getByText(FOLLOWUP, { exact: true }).count(), { timeout: 10_000 }).toBe(1)
|
|
|
await expect.poll(() => scaffold.ctx.agents.get(childId), { timeout: 10_000 }).toBeUndefined()
|
|
|
expect(await page.getByRole('button', { name: 'Stop generating' }).count()).toBe(0)
|
|
|
@@ -318,7 +352,7 @@ describe('web e2e: persisted subagent conversation and human continuation', () =
|
|
|
.getByRole('treeitem')
|
|
|
.last()
|
|
|
await parentSession.click()
|
|
|
- await page.getByRole('button', { name: '2 个子代理' }).click()
|
|
|
+ await page.getByRole('button', { name: '3 个子代理' }).click()
|
|
|
await page.getByRole('treeitem', { name: new RegExp(ONE_SHOT_LABEL) }).click()
|
|
|
await page.getByText('一次性任务不支持后续消息,可在这里查看完整执行记录。').waitFor()
|
|
|
expect(scaffold.ctx.agents.get(oneShotId)).toBeUndefined()
|
|
|
@@ -329,7 +363,7 @@ describe('web e2e: persisted subagent conversation and human continuation', () =
|
|
|
await page.getByRole('tree', { name: 'Sessions' })
|
|
|
.getByRole('treeitem', { name: /Ask a research subagent to/ })
|
|
|
.click()
|
|
|
- await page.getByRole('button', { name: '2 个子代理' }).click()
|
|
|
+ await page.getByRole('button', { name: '3 个子代理' }).click()
|
|
|
await page.getByRole('treeitem', { name: new RegExp(LABEL) }).click()
|
|
|
await page.getByRole('textbox', { name: 'Message the agent' }).waitFor()
|
|
|
const forkResponse = page.waitForResponse(response =>
|
|
|
@@ -355,7 +389,7 @@ describe('web e2e: persisted subagent conversation and human continuation', () =
|
|
|
onTestFailed(() => saveFailureShot(page, 'web-e2e-subagent-post-fork-followup'))
|
|
|
const sessions = page.getByRole('tree', { name: 'Sessions' })
|
|
|
await sessions.getByRole('treeitem', { name: /Ask a research subagent to/ }).click()
|
|
|
- await page.getByRole('button', { name: '2 个子代理' }).click()
|
|
|
+ await page.getByRole('button', { name: '3 个子代理' }).click()
|
|
|
await page.getByRole('treeitem', { name: new RegExp(LABEL) }).click()
|
|
|
await page.locator('textarea:enabled').first().waitFor()
|
|
|
expect(scaffold.ctx.agents.get(childId)).toBeUndefined()
|
|
|
@@ -372,7 +406,7 @@ describe('web e2e: persisted subagent conversation and human continuation', () =
|
|
|
await expect.poll(() => scaffold.ctx.agents.get(forkId)).not.toBeUndefined()
|
|
|
|
|
|
await sessions.getByRole('treeitem', { name: /Ask a research subagent to/ }).click()
|
|
|
- await page.getByRole('button', { name: '2 个子代理' }).click()
|
|
|
+ await page.getByRole('button', { name: '3 个子代理' }).click()
|
|
|
await page.getByRole('treeitem', { name: new RegExp(LABEL) }).click()
|
|
|
const input = page.locator('textarea:enabled').first()
|
|
|
await input.waitFor()
|