From 19d87778a1647b209f887b4a111861299b9b67de Mon Sep 17 00:00:00 2001 From: _Kerman Date: Tue, 8 Sep 2026 17:55:48 +0800 Subject: [PATCH] test(web): hold workflow children through live navigation checks --- apps/web/tests/workflow-run.e2e.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/apps/web/tests/workflow-run.e2e.ts b/apps/web/tests/workflow-run.e2e.ts index 08f4c5e193..952c5a34d6 100644 --- a/apps/web/tests/workflow-run.e2e.ts +++ b/apps/web/tests/workflow-run.e2e.ts @@ -7,7 +7,7 @@ import { join } from 'node:path' import { fileURLToPath } from 'node:url' import type { Browser, Page } from 'playwright' import { chromium } from 'playwright' -import { afterAll, beforeAll, describe, expect, it, onTestFailed } from 'vitest' +import { afterAll, beforeAll, describe, expect, it, onTestFailed, onTestFinished } from 'vitest' import type { Session, SessionEvent, SessionId } from '@deepseek-ai/dsh-session' import { assertFixtureInventory, captureStableAria, compareOrRefreshGolden, @@ -32,6 +32,7 @@ describe.skipIf(MODE === 'record')('web e2e: durable workflow run in Chat', () = let page: Page let tripwire: ReturnType let prompt: string + const releaseChild = Promise.withResolvers() const waitForParentSettlement = (): Promise => new Promise((resolve, reject) => { let dispose = (): void => {} @@ -53,9 +54,14 @@ describe.skipIf(MODE === 'record')('web e2e: durable workflow run in Chat', () = scaffold = await launchWebScaffold({ replayFixture: PARENT_FIXTURE, replayChildFixtures: [CHILD_FIXTURE], - paceMs: 50, compareReplaySession: false, }) + // Keep the live child available throughout disclosure, layout, and navigation checks. + scaffold.ctx.on('llm/stream', async function* (options, next) { + const session = options.sessionId === undefined ? undefined : scaffold.ctx.sessions.get(options.sessionId) + if (session?.header.origin === 'subagent') await releaseChild.promise + yield* next() + }, { prepend: true }) browser = await chromium.launch() page = await newEnglishPage(browser) tripwire = watchConsole(page) @@ -65,6 +71,7 @@ describe.skipIf(MODE === 'record')('web e2e: durable workflow run in Chat', () = }, 120_000) afterAll(async () => { + releaseChild.resolve(undefined) await browser?.close() await scaffold?.close() }) @@ -72,6 +79,10 @@ describe.skipIf(MODE === 'record')('web e2e: durable workflow run in Chat', () = it('shows the live member, opens its local child, then retains the settled record beside the tool row', async () => { onTestFailed(() => saveFailureShot(page, 'web-e2e-workflow-run-live')) const settled = waitForParentSettlement() + onTestFinished(async () => { + releaseChild.resolve(undefined) + await settled + }) const input = page.locator('[data-composer-input]').first() await input.fill(prompt) await input.press('Enter') @@ -160,6 +171,7 @@ describe.skipIf(MODE === 'record')('web e2e: durable workflow run in Chat', () = const sessions = page.getByRole('tree', { name: 'Sessions' }) await sessions.getByRole('treeitem', { name: /Use the workflow tool exactly/ }).click() + releaseChild.resolve(undefined) await settled await expandTurnProcesses(page) await page.locator('[data-workflow-run][data-run-status="completed"]').waitFor()