From 08a49aa50f64fadee938b2bd7352c2f4059e1623 Mon Sep 17 00:00:00 2001 From: Jesse_Chen Date: Thu, 23 Jul 2026 13:32:14 +0800 Subject: [PATCH] test: align rectification checks with agent replies --- docs/BUG_HISTORY.md | 16 ++++++++++++ ...ersational-rectification-component.test.ts | 26 ++++++++++--------- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/docs/BUG_HISTORY.md b/docs/BUG_HISTORY.md index 0761e186..74d00f25 100644 --- a/docs/BUG_HISTORY.md +++ b/docs/BUG_HISTORY.md @@ -601,3 +601,19 @@ - 相关记录:BUG-018、BUG-032 - 复发自:无 - 修复版本:待提交(本地可测) + +## BUG-036 | Agent 化生时校正上线前被旧模板组件断言阻断 + +- 状态:resolved +- 首次发现:2026-07-23 +- 最近更新:2026-07-23 +- 影响面:生产发布门禁、生时校正前端组件测试 +- 用户现象:最新 `main` 已保留 Agent 自然语言回复与历史气泡,但生产测试门禁失败,无法进入部署。 +- 触发条件:运行生产 `Jyotish Skill Tests` 的完整前端测试套件。 +- 根因:组件测试仍断言旧版确定性模板会覆盖 Agent 叙事、经历摘要带固定“已记录”前缀,并直接调用无撤回窗口的提交表达式;真实 Chromium 等待条件也仍匹配旧文案。 +- 修复:更新 5 条过期断言,使其验证 Agent 原始叙事、折叠进度中的经历摘要、2.5 秒撤回后提交路径和当前移动端文案;不回退现有业务实现。 +- 验证:生时校正组件测试、完整前端测试、生产质量门禁与生产部署工作流;以对应提交 SHA 的线上健康检查为最终验收。 +- 防复发:对话呈现测试应验证用户可见契约,不再把旧模板句式或内部调用参数写成不必要的固定实现约束。 +- 相关记录:BUG-034、BUG-035 +- 复发自:无 +- 修复版本:待提交 diff --git a/frontend/tests/conversational-rectification-component.test.ts b/frontend/tests/conversational-rectification-component.test.ts index 0766644a..ab7105d3 100644 --- a/frontend/tests/conversational-rectification-component.test.ts +++ b/frontend/tests/conversational-rectification-component.test.ts @@ -91,10 +91,11 @@ test("rectification is a language-first exchange with one free-text answer path" { controller: controller() }, )); - assert.match(markup, /已记录:2021 年 7 月 · 开始第一份长期工作/); - assert.match(markup, /目前已经形成一个待确认候选/); - assert.ok(markup.indexOf("待确认候选") < markup.indexOf("当前候选 05:18")); - assert.doesNotMatch(markup, /D9 与 D10|当前判断/); + assert.match(markup, /当前判断/); + assert.match(markup, /D9 与 D10/); + assert.match(markup, /2021 年 7 月 · 开始第一份长期工作/); + assert.ok(markup.indexOf("当前判断") < markup.indexOf("当前候选 05:18")); + assert.doesNotMatch(markup, /目前已经形成一个待确认候选/); assert.match(markup, /]+id="conversational-rectification-answer"/); assert.match(markup, /像聊天一样回答即可/); assert.match(markup, /2018 年 6 月去了上海工作/); @@ -103,7 +104,7 @@ test("rectification is a language-first exchange with one free-text answer path" assert.doesNotMatch(markup, /2006[^<]*2011|BirthTimeChoiceQuestion|birth-time-choice-question/); }); -test("a resumed legacy turn replaces repeated technical prose with actionable guidance", () => { +test("a resumed legacy turn preserves its Agent narrative and keeps evidence in progress details", () => { const legacyTurn = { ...turn, status: "active", @@ -116,10 +117,10 @@ test("a resumed legacy turn replaces repeated technical prose with actionable gu { controller: controller({ turn: legacyTurn }) }, )); - assert.match(markup, /已记录:2021 年 7 月 · 开始第一份长期工作/); - assert.match(markup, /范围暂未变化不代表提交失败/); - assert.match(markup, /接下来请说一件重要关系或搬迁与居住地方面已经发生的事/); - assert.doesNotMatch(markup, /D1 保持稳定/); + assert.match(markup, /05:30 是范围内的待验证候选/); + assert.match(markup, /D1 保持稳定/); + assert.match(markup, /2021 年 7 月 · 开始第一份长期工作/); + assert.doesNotMatch(markup, /范围暂未变化不代表提交失败/); }); test("an incomplete concrete event gets a targeted clarification instead of the generic question", () => { @@ -133,6 +134,7 @@ test("an incomplete concrete event gets a targeted clarification instead of the dateLabel: "日期待补充", domain: "relocation", }], + narrative: "你提到离开家去北京开始工作,这件事很有区分度。大致是什么年月?", actions: ["answer", "pause", "abandon"], } satisfies ConversationalRectificationTurn; const markup = renderToStaticMarkup(React.createElement( @@ -140,7 +142,7 @@ test("an incomplete concrete event gets a targeted clarification instead of the { controller: controller({ turn: incompleteTurn }) }, )); - assert.match(markup, /你提到“离开家去北京开始工作”/); + assert.match(markup, /你提到离开家去北京开始工作/); assert.match(markup, /大致是什么年月/); assert.doesNotMatch(markup, /接下来请说一件/); }); @@ -261,7 +263,7 @@ test("pending markup and responsive CSS expose accessibility contracts", () => { assert.match(css, /@media\s*\(prefers-reduced-motion:\s*reduce\)/); assert.match(css, /@media\s*\(max-width:\s*430px\)[\s\S]*\.rectification-message-details/); assert.doesNotMatch(component, /确认放弃且不应用候选|本轮技术回执/); - assert.match(component, /controller\.answer\(undefined, controller\.draft\.trim\(\)\)/); + assert.match(component, /controller\.answer\(undefined, text\)/); assert.match(component, /event\.key === "Enter" && !event\.shiftKey/); assert.match(component, /onPendingChange/); assert.match(component, /onPendingChange:\s*props\.onPendingChange/); @@ -749,7 +751,7 @@ test("real Chromium at 390px verifies layout, keyboard focus, streamlined contro await cdp.evaluate("globalThis.__rectificationHarness.setTurn('activeA1')"); await waitFor( () => cdp?.evaluate(`document.body.textContent.includes('当前候选 05:18') - && document.body.textContent.includes('已记录:2021-07')`) ?? Promise.resolve(false), + && document.body.textContent.includes('2021-07 · 开始第一份长期工作')`) ?? Promise.resolve(false), "streamlined async initial turn", );