From cd840929c4bac9a8079b6b7bc0ea5119a65f6a12 Mon Sep 17 00:00:00 2001 From: Lukas May Date: Sat, 31 Jan 2026 18:08:30 +0100 Subject: [PATCH] test(10-04): add multi-question E2E test - Tests agent asking two questions at once - Verifies both questions present in pending questions - Validates resume with answers for all questions - Confirms task completes after batched answer resume --- src/test/e2e/recovery-scenarios.test.ts | 76 +++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/src/test/e2e/recovery-scenarios.test.ts b/src/test/e2e/recovery-scenarios.test.ts index 0788523..246e75d 100644 --- a/src/test/e2e/recovery-scenarios.test.ts +++ b/src/test/e2e/recovery-scenarios.test.ts @@ -410,5 +410,81 @@ describe('E2E Recovery Scenarios', () => { const clearedQuestions = await harness.getPendingQuestions(dispatchResult.agentId!); expect(clearedQuestions).toBeNull(); }); + + it('should handle agent asking multiple questions at once', async () => { + vi.useFakeTimers(); + const seeded = await harness.seedFixture(SIMPLE_FIXTURE); + const taskAId = seeded.tasks.get('Task A')!; + + // Pre-seed required idle agent + await harness.agentManager.spawn({ + name: 'pool-agent', + taskId: 'placeholder', + prompt: 'placeholder', + }); + await vi.runAllTimersAsync(); + + // Setup: agent asks two questions + harness.setAgentQuestions(`agent-${taskAId.slice(0, 6)}`, [ + { + id: 'q1', + question: 'Which database?', + options: [{ label: 'SQLite' }, { label: 'Postgres' }], + }, + { + id: 'q2', + question: 'Include tests?', + options: [{ label: 'Yes' }, { label: 'No' }], + }, + ]); + + // Queue and dispatch task + await harness.dispatchManager.queue(taskAId); + harness.clearEvents(); + + const dispatchResult = await harness.dispatchManager.dispatchNext(); + await vi.runAllTimersAsync(); + + // Verify: agent:waiting event emitted + const waitingEvents = harness.getEventsByType('agent:waiting'); + expect(waitingEvents.length).toBe(1); + const waitingPayload = (waitingEvents[0] as AgentWaitingEvent).payload; + expect(waitingPayload.taskId).toBe(taskAId); + + // Verify both questions present + const pending = await harness.getPendingQuestions(dispatchResult.agentId!); + expect(pending?.questions).toHaveLength(2); + expect(pending?.questions[0].id).toBe('q1'); + expect(pending?.questions[0].question).toBe('Which database?'); + expect(pending?.questions[1].id).toBe('q2'); + expect(pending?.questions[1].question).toBe('Include tests?'); + + // Resume with answers for both questions + harness.clearEvents(); + await harness.agentManager.resume(dispatchResult.agentId!, { + q1: 'SQLite', + q2: 'Yes', + }); + await vi.runAllTimersAsync(); + + // Verify: agent:resumed event emitted + const resumedEvents = harness.getEventsByType('agent:resumed'); + expect(resumedEvents.length).toBe(1); + + // Verify: agent:stopped event emitted (after resume completes) + const stoppedEvents = harness.getEventsByType('agent:stopped'); + expect(stoppedEvents.length).toBe(1); + const stoppedPayload = (stoppedEvents[0] as AgentStoppedEvent).payload; + expect(stoppedPayload.taskId).toBe(taskAId); + expect(stoppedPayload.reason).toBe('task_complete'); + + // Verify task completed (agent result) + const agentResult = await harness.agentManager.getResult(dispatchResult.agentId!); + expect(agentResult?.success).toBe(true); + + // Verify agent is now idle + const finalAgent = await harness.agentManager.get(dispatchResult.agentId!); + expect(finalAgent?.status).toBe('idle'); + }); }); });