From a6d76df4f0c0d2192a393c0c5e250fa7014beac5 Mon Sep 17 00:00:00 2001 From: Shakker Date: Wed, 8 Apr 2026 20:39:20 +0100 Subject: [PATCH] test: cover qa scenario wait failure replies --- extensions/qa-lab/src/suite.test.ts | 67 +++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 extensions/qa-lab/src/suite.test.ts diff --git a/extensions/qa-lab/src/suite.test.ts b/extensions/qa-lab/src/suite.test.ts new file mode 100644 index 00000000000..28e7336e752 --- /dev/null +++ b/extensions/qa-lab/src/suite.test.ts @@ -0,0 +1,67 @@ +import { describe, expect, it } from "vitest"; +import { createQaBusState } from "./bus-state.js"; +import { qaSuiteTesting } from "./suite.js"; + +describe("qa suite failure reply handling", () => { + it("detects classified failure replies before a success-only outbound predicate matches", async () => { + const state = createQaBusState(); + state.addOutboundMessage({ + to: "dm:qa-operator", + text: "⚠️ Something went wrong while processing your request. Please try again, or use /new to start a fresh session.", + senderId: "openclaw", + senderName: "OpenClaw QA", + }); + + const message = qaSuiteTesting.findFailureOutboundMessage(state); + expect(message?.text).toContain("Something went wrong while processing your request."); + }); + + it("fails success-only waitForOutboundMessage calls when a classified failure reply arrives first", async () => { + const state = createQaBusState(); + const pending = qaSuiteTesting.waitForOutboundMessage( + state, + (candidate) => + candidate.conversation.id === "qa-operator" && + candidate.text.includes("Remembered ALPHA-7."), + 5_000, + ); + + state.addOutboundMessage({ + to: "dm:qa-operator", + text: '⚠️ No API key found for provider "openai". You are authenticated with OpenAI Codex OAuth. Use openai-codex/gpt-5.4 (OAuth) or set OPENAI_API_KEY to use openai/gpt-5.4.', + senderId: "openclaw", + senderName: "OpenClaw QA", + }); + + await expect(pending).rejects.toThrow('No API key found for provider "openai".'); + }); + + it("fails raw scenario waitForCondition calls when a classified failure reply arrives", async () => { + const state = createQaBusState(); + const waitForCondition = qaSuiteTesting.createScenarioWaitForCondition(state); + + const pending = waitForCondition( + () => + state + .getSnapshot() + .messages.filter( + (message) => + message.direction === "outbound" && + message.conversation.id === "qa-operator" && + message.text.includes("ALPHA-7"), + ) + .at(-1), + 5_000, + 10, + ); + + state.addOutboundMessage({ + to: "dm:qa-operator", + text: '⚠️ No API key found for provider "openai". You are authenticated with OpenAI Codex OAuth. Use openai-codex/gpt-5.4 (OAuth) or set OPENAI_API_KEY to use openai/gpt-5.4.', + senderId: "openclaw", + senderName: "OpenClaw QA", + }); + + await expect(pending).rejects.toThrow('No API key found for provider "openai".'); + }); +});