test(desktop): fence active turn state in streaming-remount e2e - #3178
Conversation
…he#3177) Generated-by: gemini-3.6-flash [PARS-IDEMPOTENCY:branch:198847bf4d9c77543a610819e8ead7911d3c7671ca5c945a797217c9bf737434]
📝 WalkthroughSummary
Validation
Review-relevant risksNo protected-area effect was identified in the current diff. The person performing the merge reviews the final diff, and a maintainer makes the final determination. WalkthroughThe interrupted-conversation end-to-end test now checks send-button readiness before submission and confirms that the original session has an active running turn afterward. ChangesStreaming remount test
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: 🔵 Low · up to The change only affects end-to-end synchronization, but the new check may proceed before a genuinely active turn is established, reducing the test’s ability to catch remount timing regressions. The PR is mergeable with owner awareness or a follow-up to align the predicate with the renderer’s active-turn condition. Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
PR Summary by QodoFence active-turn state in streaming-remount E2E
AI Description
Diagram
High-Level Assessment
Files changed (1)
|
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 403ccef5-6b66-451c-8860-da2ae2653cf3
📒 Files selected for processing (1)
apps/desktop/e2e/streaming-remount.spec.ts
Included review availability: Your plan includes up to 3 reviews per rolling hour; 2 remain after this review.
| await expect.poll( | ||
| () => page.evaluate(async (sessionId) => ( | ||
| (await window.maka.sessions.list()).find((session) => session.id === sessionId) | ||
| ?.runningTurnIds?.length ?? 0 | ||
| ), originalSessionId!), | ||
| { timeout: 20_000 }, | ||
| ).toBeGreaterThan(0); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Align the poll with the active-turn predicate.
The runningTurnIds.length > 0 check can pass when the only ID is armedTurnId. The renderer treats that state as inactive when turnPhase is undefined. Assert a running turn different from armedTurnId, or require a new running-turn ID compared with the pre-submit state.
As per path instructions, this check targets a concrete synchronization-contract failure.
Source: Path instructions
Code Review by Qodo🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)
Great, no issues found!Qodo reviewed your code and found no material issues that require reviewTip of the day💡 Did you know, you can keep summaries lean with Finding overflow, which tucks the rest behind 'View more' |
|
Thanks for the attempt — but this change makes the test deterministically fail, the opposite of the flake fix you're going for. Please hold on merge until verified. Conclusion: FAIL — P1 + P2, both need resolution before merge. P1 — the reordering inverts the assertion: the send button is disabled on an empty draft, so P2 — the new durable-poll fence likely won't fix #3177's failing case and is unverified as a fence. The poll is honest (it reads the kernel's live P3 (optional): the new poll is a structural twin of the existing AI-assisted review disclosure: this review was produced with AI assistance (pi review subagent on 中文摘要(AI 辅助审查)结论:FAIL(P1 + P2,合并前需解决)。P1:重排让断言反转——发送按钮在空草稿时恒为 disabled,现在 expect(发送).toBeEnabled() 在 composer.fill() 之前断言,必然每次运行 20s 超时(从偶发 flake 变成确定性红)。原因:sendCurrent 提交成功后无条件清空输入(composer.tsx:1078-1080),测试里第一轮 hold-open turn 已提交、draft 无回填机制;发送按钮 enabled 依赖草稿非空(composer.tsx:1220-1224),中断轮结束后 streaming=false 且 text 为空,渲染为 disabled 的发送按钮。原顺序(fill 后再查 enabled)才是对的——fence 必须在文本存在之后求值。验证方式:单跑该 spec 应确定性超时。P2:新增的 durable 轮询大概率治不了 #3177 的失败类别——用户消息可见意味着 host 已接受 turn、runningTurnIds 早已 >0,轮询立即通过,随后 停止 断言照样 20s 超时;轮询只证明 host 侧状态,不能证明 renderer 订阅/投影通道健康(#3177 疑点所在)。且 PR 无实际测试运行记录(gh pr checks 只有 CodeRabbit),不能声称 fixes #3177。要求:回退/修正重排(P1)、本地连续多轮运行该 spec 证明 flake 真的消失、说明 fence 证明的是 host 侧启动而非 renderer 侧投影。P3:新轮询与文件内既有轮询是结构孪生,可抽 runningTurnIdsOf(id) 助手去重。 |
|
Thanks for taking the time to investigate #3177 and propose a synchronization fence. We ultimately traced the intermittent failure to a production renderer race rather than a missing readiness check in the test: session settlement could combine an older catalog result with a newer live-Turn projection and incorrectly clear the Stop witness. #3189 has now been merged with the root-cause fix. It binds settlement to the accepted authoritative list read, uses a per-projection compare-and-swap, projects observer-owned running Turn identities, and adds deterministic regression coverage. This supersedes the test-only approach here, so we can close #3178 without asking you to make further changes. The current ordering would also check whether Send is enabled before filling the empty composer, as noted above, but there is no need to spend time revising it now unless an independent test improvement remains. Thanks again for helping investigate the failure. |
What changed
getByRole('button', { name: '发送' }).toBeEnabled()) to precedecomposer.fill(...)inapps/desktop/e2e/streaming-remount.spec.tsso React state transitions after an interrupted turn settle before filling text.expect.pollfence verifyingrunningTurnIds.length > 0on the session before expecting the Stop button to be rendered, ensuring active Turn state is fenced in durable session state.Addresses #3177
Generated from a bounded immutable repository snapshot by PARS-Agent using Gemini 3.6 Flash. Tests listed above are recommendations unless GitHub checks report otherwise.