Преглед изворни кода

test(web): release timed-out barriers and await frame animations

Tianyi Cui пре 1 месец
родитељ
комит
d38391d629

+ 2 - 2
.agents/notes/implemented/testing/2026-09-08-ci-completion-observations.i18n.yaml

@@ -2,5 +2,5 @@
 # side as of the last confirmed-consistent state. Both languages carry equal authority;
 # after editing either side, bring the other along and re-record with:
 #   pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-09-08-ci-completion-observations.md
-2026-09-08-ci-completion-observations.md: 8ff56e680f5ec1d1e6bcb5e279d769d3ca6a780f
-2026-09-08-ci-completion-observations.zh.md: d1ee08f884d0653f37063fac3da5eeff410a073d
+2026-09-08-ci-completion-observations.md: c03f8ee40ad433c964d2c4f166dfb18e53b79bf3
+2026-09-08-ci-completion-observations.zh.md: 92ba2130e21459cbc6b5fbc5600db30fbd896d2f

+ 1 - 1
.agents/notes/implemented/testing/2026-09-08-ci-completion-observations.md

@@ -10,7 +10,7 @@ The [reference CI run](https://github.com/deepseek-harness/deepseek-harness/acti
 
 ## Decision
 
-The [GitHub review browser test](../../../../apps/web/tests/github-ready-review.e2e.ts) awaits the deterministic adapter’s first request before asserting exact Agent and request counts. A deferred Workspace-creation barrier proves that HTTP acceptance can precede both observations; the barrier delegates to the real method and is released and restored in `finally`. The original Workspace membership, prompt content, reply, and collapsed/expanded browser expectations remain authoritative.
+The [GitHub review browser test](../../../../apps/web/tests/github-ready-review.e2e.ts) awaits the deterministic adapter’s first request before asserting exact Agent and request counts. A deferred Workspace-creation barrier proves that HTTP acceptance can precede both observations; the barrier delegates to the real method and is released and restored in `finally`, with independent `onTestFinished` cleanup if the request itself stalls beyond the test timeout. The original Workspace membership, prompt content, reply, and collapsed/expanded browser expectations remain authoritative.
 
 The [PowerShell executor tests](../../../../packages/shell/pwsh-local/tests/executor.spec.ts) await `done` before reading complete stdin/environment output. Startup and consuming-read checks hold the command at a private file barrier, so the running state and unread later output do not depend on a sleep or elapsed-time threshold. Partial-output polling inherits the lane budget. Every created Context is registered for teardown before use; subprocess disposal precedes private-directory removal. A six-second delayed command reproduces the five-second failure and passes after the completion wait on native Windows.
 

+ 1 - 1
.agents/notes/implemented/testing/2026-09-08-ci-completion-observations.zh.md

@@ -10,7 +10,7 @@ Status: implemented
 
 ## Decision
 
-[GitHub 评审浏览器测试](../../../../apps/web/tests/github-ready-review.e2e.ts)先等待确定性适配器收到首个请求,再断言 Agent(智能体)和请求的精确数量。Workspace 创建的延迟屏障证明 HTTP 接纳可以早于这两项观察;屏障委托真实方法,并在 `finally` 中释放和恢复。原有的 Workspace 成员关系、提示词内容、回复以及折叠和展开浏览器预期仍然是判定依据。
+[GitHub 评审浏览器测试](../../../../apps/web/tests/github-ready-review.e2e.ts)先等待确定性适配器收到首个请求,再断言 Agent(智能体)和请求的精确数量。Workspace 创建的延迟屏障证明 HTTP 接纳可以早于这两项观察;屏障委托真实方法,并在 `finally` 中释放和恢复;如果请求本身挂起并超过测试超时,独立的 `onTestFinished` 清理仍会释放和恢复屏障。原有的 Workspace 成员关系、提示词内容、回复以及折叠和展开浏览器预期仍然是判定依据。
 
 [PowerShell 执行器测试](../../../../packages/shell/pwsh-local/tests/executor.spec.ts)先等待 `done`,再读取完整的 stdin 和环境变量输出。启动及消费式读取检查用私有文件屏障阻止命令结束,因此运行状态和未读的后续输出不依赖 sleep 或耗时阈值。部分输出轮询继承 lane 预算。每个创建的 Context 都在使用前登记清理;子进程释放先于私有目录删除。在原生 Windows 上,延迟六秒的命令复现五秒期限失败,而改用完成等待后通过。
 

+ 5 - 1
apps/web/tests/github-ready-review.e2e.ts

@@ -6,7 +6,7 @@ import type { AddressInfo } from 'node:net'
 import { fileURLToPath } from 'node:url'
 import type { Browser, Page } from 'playwright'
 import { chromium } from 'playwright'
-import { afterAll, beforeAll, describe, expect, it, onTestFailed, vi } from 'vitest'
+import { afterAll, beforeAll, describe, expect, it, onTestFailed, onTestFinished, vi } from 'vitest'
 import type { GenerateOptions, StreamChunk } from '@deepseek-ai/dsh-llm'
 import { LlmAdapter } from '@deepseek-ai/dsh-llm'
 import type {} from '@deepseek-ai/dsh-webhook'
@@ -157,6 +157,10 @@ describe.skipIf(MODE === 'record')('web e2e: GitHub ready-for-review', () => {
       await release.promise
       return await createWorkspace(...args)
     })
+    onTestFinished(() => {
+      release.resolve(undefined)
+      create.mockRestore()
+    })
     try {
       expect((await send(webhookOrigin, 'ready', payload)).status).toBe(202)
       await entered.promise

+ 4 - 3
apps/web/tests/queue-actions.e2e.ts

@@ -9,7 +9,7 @@ import { fileURLToPath } from 'node:url'
 import { join } from 'node:path'
 import type { Browser, Page } from 'playwright'
 import { chromium } from 'playwright'
-import { afterEach, describe, expect, it, onTestFailed, vi } from 'vitest'
+import { afterEach, describe, expect, it, onTestFailed } from 'vitest'
 import { deriveReplayScript, parseSessionLog, type ReplayEntry } from '@deepseek-ai/dsh-llm-replay'
 import type { SessionEvent } from '@deepseek-ai/dsh-session'
 import {
@@ -161,8 +161,9 @@ describe('web e2e: queue row actions', () => {
     await page.setViewportSize({ width: 640, height: 1000 })
     const narrowFrame = page.locator('[data-sidebar-collapsed="true"]')
     await narrowFrame.waitFor()
-    await expect.poll(() => narrowFrame.evaluate(element =>
-      element.getAnimations().filter(animation => animation.playState === 'running').length)).toBe(0)
+    await narrowFrame.evaluate(async (element) => {
+      await Promise.allSettled(element.getAnimations().map(animation => animation.finished))
+    })
     // The frame's resize observer can move both cards between browser round trips.
     const { queueBox, composerBox, dockInset } = await page.evaluate(() => {
       const queue = document.querySelector('[data-queue-dock]')