From 0aacee0aebbfcded99522411e78ddbbe261074d6 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Sat, 18 Jul 2026 05:31:01 -0700 Subject: [PATCH] fix(dashboard): align planning tests with clarification default-off (#2299) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Full Suite [29643371961](https://github.com/Runfusion/Fusion/actions/runs/29643371961) after #2298: shards 1–2 green; shard 3 confirm Other race; shard 4 MCP + re-emit planning tests. - MCP lane mock: follow-up prompts return `complete` (product defaults clarification off). - Re-emit suite: pass `clarificationEnabled: true` so multi-question interview invariants still run. - Confirm Other UI test: `findByTestId("planning-other-input")` after click. ## Test plan - [x] mcp-lane-forwarding + planning-answered-question-reemit (14) - [x] confirm Other desktop/mobile planning-flow - [ ] Full Suite all 4 shards green on main ## Summary by CodeRabbit * **Tests** * Improved automated coverage for planning-mode interviews, including “Other” responses and follow-up prompts. * Increased test reliability by handling asynchronous input updates more consistently. * Added validation for clarification-enabled interviews and completion behavior in MCP forwarding scenarios. --- .../PlanningModeModal.planning-flow.test.tsx | 13 +++++-- .../src/__tests__/mcp-lane-forwarding.test.ts | 38 ++++++++++++++----- .../planning-answered-question-reemit.test.ts | 11 ++++++ 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/packages/dashboard/app/components/__tests__/PlanningModeModal.planning-flow.test.tsx b/packages/dashboard/app/components/__tests__/PlanningModeModal.planning-flow.test.tsx index 1ea795b0c3..f11ba3d0dd 100644 --- a/packages/dashboard/app/components/__tests__/PlanningModeModal.planning-flow.test.tsx +++ b/packages/dashboard/app/components/__tests__/PlanningModeModal.planning-flow.test.tsx @@ -835,15 +835,22 @@ describe("PlanningModeModal", () => { expect(screen.getByTestId("planning-option-other")).toBeInTheDocument(); expect(screen.queryByTestId("planning-other-input")).toBeNull(); + /* + FNXC:PlanningModeOptions 2026-07-18-12:15: + Full Suite shard 3 (29643371961) failed when fireEvent.click(Other) did not flush + isOtherSelected before the synchronous getByTestId(planning-other-input) under CI + load. Await findByTestId after the confirm Other button click (same settle discipline + as multi-select Other) before asserting Continue enablement and the _other payload. + */ const continueButton = screen.getByRole("button", { name: "Continue" }); fireEvent.click(screen.getByTestId("planning-option-other")); - expect(screen.getByTestId("planning-other-input")).toBeInTheDocument(); + const otherInput = await screen.findByTestId("planning-other-input"); expect(continueButton).toBeDisabled(); - fireEvent.change(screen.getByTestId("planning-other-input"), { target: { value: " " } }); + fireEvent.change(otherInput, { target: { value: " " } }); expect(continueButton).toBeDisabled(); - fireEvent.change(screen.getByTestId("planning-other-input"), { + fireEvent.change(otherInput, { target: { value: " Ask a different scoping question " }, }); expect(continueButton).toBeEnabled(); diff --git a/packages/dashboard/src/__tests__/mcp-lane-forwarding.test.ts b/packages/dashboard/src/__tests__/mcp-lane-forwarding.test.ts index 2ea5ece800..81557ae546 100644 --- a/packages/dashboard/src/__tests__/mcp-lane-forwarding.test.ts +++ b/packages/dashboard/src/__tests__/mcp-lane-forwarding.test.ts @@ -3,21 +3,41 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; const { createFnAgentMock, resolveMcpServersForStoreMock } = vi.hoisted(() => ({ + /* + FNXC:DashboardTests 2026-07-18-12:20: + Planning defaults clarificationEnabled=false, so createSession forces a summary after the + first question (continueToSummaryAfterSuppressedQuestion). Mock every follow-up prompt as a + complete payload so MCP-forwarding assertions exercise the default product path instead of + throwing Clarification-disabled follow-up did not produce a summary. + */ createFnAgentMock: vi.fn(async () => ({ session: { state: { messages: [] as Array<{ role: string; content: string }> }, prompt: vi.fn(async function (this: { state: { messages: Array<{ role: string; content: string }> } }, _message: string) { + const alreadyAnswered = this.state.messages.some((message) => message.role === "assistant"); this.state.messages.push({ role: "assistant", - content: JSON.stringify({ - type: "question", - data: { - id: "q1", - text: "What should be built?", - type: "text", - required: true, - }, - }), + content: JSON.stringify( + alreadyAnswered + ? { + type: "complete", + data: { + title: "Build a feature", + description: "Materialized MCP planning summary", + suggestedSize: "M", + keyDeliverables: ["docs MCP available"], + }, + } + : { + type: "question", + data: { + id: "q1", + text: "What should be built?", + type: "text", + required: true, + }, + }, + ), }); }), dispose: vi.fn(), diff --git a/packages/dashboard/src/__tests__/planning-answered-question-reemit.test.ts b/packages/dashboard/src/__tests__/planning-answered-question-reemit.test.ts index 748f32d165..cb421b8d61 100644 --- a/packages/dashboard/src/__tests__/planning-answered-question-reemit.test.ts +++ b/packages/dashboard/src/__tests__/planning-answered-question-reemit.test.ts @@ -156,11 +156,22 @@ function setupAgent(behaviors: TurnBehavior[]) { async function startSessionAtFirstQuestion( agent: ReturnType, ): Promise { + /* + FNXC:PlanningRetry 2026-07-18-12:20: + createSessionWithAgent defaults clarificationEnabled=false, which suppresses the first + question into continueToSummaryAfterSuppressedQuestion and consumes the next mock prompt + turn (often the hung turn these re-emit tests need). Opt into clarification so the + multi-question interview invariants under test still run. + */ const sessionId = await createSessionWithAgent( "10.0.2.20", "Plan a feature", "/tmp/project", MOCK_TASK_STORE, + undefined, + undefined, + undefined, + { clarificationEnabled: true }, ); planningStreamManager.consumeInitialTurn(sessionId)?.(); await agent.firstQuestionEmitted;