Skip to content

workflow-editor 上传参考图那条测试间歇失败,会随机染红无关 PR #272

Description

@johnnyzhang-eng

现象

frontend/src/pages/workflow-editor/index.test.tsx

上传角色参考图期间禁止生成,成功后写回 WorkflowRun

间歇失败

AssertionError: expected { id: 'character-setup', …(7) } to match object { input: { …(2) } }

拿到的节点没有 input 字段——说明断言跑在写回完成之前。

复现率

在一个零前端改动的分支上(前端与 main 逐字节一致)本地连跑 6 次:

结果
1 / 2 / 3 29 passed
4 1 failed
5 / 6 29 passed

1/6。CI 上也复现过一次(432 项里就它一个红)。

根因方向

index.test.tsx:131-143

await act(async () => {
  pendingUpload.resolve('opaque-reference-1' as MediaReference)
  await pendingUpload.promise
})

await waitFor(() =>
  expect(session.controller.getWorkflow().nodes[0]).toMatchObject({
    input: { prompt: ..., referenceMedia: ['opaque-reference-1'] },
  }),
)

await pendingUpload.promise 只等到那个 promise 自己兑现,不保证它的 .then 链(真正执行写回的那段)已经跑完。waitFor 本该兜住这个,但它默认的轮询间隔与 act 的调度在偶发时序下会错开——断言在第一次轮询就取到了尚未写回的节点,而 toMatchObject 对"缺字段"是立即失败、不重试到超时。

影响

它会随机把无关 PR 的 CI 染红。 已经发生:一个零前端改动的后端 PR 因为它 Frontend checks 失败。这类失败最贵的地方不是重跑一次,是让人开始怀疑自己的改动,以及久了之后大家默认"前端红了再跑一次就好"——那时真失败也会被当成 flaky 忽略掉。

建议

  • 让断言等到写回真的发生,而不是等 promise 自己兑现:waitFor 里改成先断言一个必然出现的中间态(如 已关联 1 个参考媒体 这条文案),再断言节点结构;或给 waitFor 显式的 timeout / interval
  • 同一文件里其它用了 deferred + act 的用例值得一起看,可能是同型

验收

连跑 30 次零失败(npx vitest run src/pages/workflow-editor/index.test.tsx --repeat 30 或脚本循环)。只跑一次通过不算修好——本 issue 的复现率就是 1/6。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions