import { describe, expect, it } from "vitest"; import { buildFlockProgressPayload, flockStageIndex, mapFlockErrorToStage, parseFlockProgress, shouldOverwriteFlockFailureStage, } from "@/lib/flock/rpa-progress"; describe("flock rpa-progress", () => { it("build + parse roundtrip", () => { const payload = buildFlockProgressPayload("login"); const parsed = parseFlockProgress(payload); expect(parsed?.stage).toBe("login"); expect(parsed?.label).toContain("登录"); }); it("maps FLOCK_LOGIN_FAILED to login stage", () => { const mapped = mapFlockErrorToStage( "FLOCK_LOGIN_FAILED:无法填写登录表单(locator.waitFor: Timeout 15000ms)", ); expect(mapped.stage).toBe("login"); expect(mapped.matched).toBe(true); expect(mapped.hint).toContain("卡在登录"); }); it("未识别错误不得默认钉在互斥锁", () => { const mapped = mapFlockErrorToStage("不明错误 xyz"); expect(mapped.matched).toBe(false); expect(mapped.stage).not.toBe("lock"); }); it("浏览器关闭 / 未返回报价 / 超时映射到 wait_quote", () => { expect(mapFlockErrorToStage("Target closed").stage).toBe("wait_quote"); expect(mapFlockErrorToStage("未返回 Flock 报价档位").stage).toBe( "wait_quote", ); expect(mapFlockErrorToStage("Flock 询价超时,请稍后重试").stage).toBe( "wait_quote", ); }); it("失败写进度禁止从 wait_quote 回退到 lock", () => { expect( shouldOverwriteFlockFailureStage("wait_quote", { stage: "lock", matched: true, }), ).toBe(false); expect( shouldOverwriteFlockFailureStage("lock", { stage: "wait_quote", matched: true, }), ).toBe(true); expect( shouldOverwriteFlockFailureStage("wait_quote", { stage: "wait_quote", matched: false, }), ).toBe(false); }); it("stage index order", () => { expect(flockStageIndex("queued")).toBeLessThan(flockStageIndex("login")); expect(flockStageIndex("login")).toBeLessThan(flockStageIndex("fill_form")); }); });