Skip to content

Commit e18a1dc

Browse files
authored
🤖 fix: de-flake integration tests (sendMessageAndWait timeout + resumeStream) (#741)
Two fixes for flaky integration tests: **1. sendMessageAndWait timeout handling** When `sendMessageAndWait` times out waiting for `stream-end`, it now throws an error with diagnostics instead of silently returning partial events. - Before: Confusing failures like `expect(createStreamEnd).toBeDefined()` - After: Clear error: `Timeout waiting for stream-end after 15000ms` with event diagnostics **2. resumeStream test fix** Fixed incorrect assumption that `StreamEndEvent` has a `content` field—it has a `parts` array of `MuxTextPart | MuxReasoningPart | MuxToolPart`. Now correctly extracts text from the parts. --- _Generated with `mux`_
1 parent ed754d8 commit e18a1dc

File tree

2 files changed

+20
-12
lines changed

2 files changed

+20
-12
lines changed

‎tests/ipcMain/helpers.ts‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,16 @@ export async function sendMessageAndWait(
232232

233233
// Wait for stream completion
234234
const collector = createEventCollector(env.sentEvents, workspaceId);
235-
await collector.waitForEvent("stream-end", timeoutMs);
235+
const streamEnd = await collector.waitForEvent("stream-end", timeoutMs);
236+
237+
if (!streamEnd) {
238+
collector.logEventDiagnostics(`sendMessageAndWait timeout after ${timeoutMs}ms`);
239+
throw new Error(
240+
`sendMessageAndWait: Timeout waiting for stream-end after ${timeoutMs}ms.\n` +
241+
`See detailed event diagnostics above.`
242+
);
243+
}
244+
236245
return collector.getEvents();
237246
}
238247

‎tests/ipcMain/resumeStream.test.ts‎

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -192,26 +192,25 @@ describeIntegration("IpcMain resumeStream integration tests", () => {
192192
.filter((e) => "role" in e && e.role === "assistant");
193193
expect(assistantMessages.length).toBeGreaterThan(0);
194194

195-
// Verify we received content deltas
196-
const deltas = collector.getDeltas();
197-
expect(deltas.length).toBeGreaterThan(0);
198-
199195
// Verify no stream errors
200196
const streamErrors = collector
201197
.getEvents()
202198
.filter((e) => "type" in e && e.type === "stream-error");
203199
expect(streamErrors.length).toBe(0);
204200

205-
// Verify the assistant responded with actual content and said the verification word
206-
const allText = deltas
207-
.filter((d) => "delta" in d)
208-
.map((d) => ("delta" in d ? d.delta : ""))
209-
.join("");
210-
expect(allText.length).toBeGreaterThan(0);
201+
// Get the final message content from stream-end parts
202+
// StreamEndEvent has parts: Array<MuxTextPart | MuxReasoningPart | MuxToolPart>
203+
const finalMessage = collector.getFinalMessage() as any;
204+
expect(finalMessage).toBeDefined();
205+
const textParts = (finalMessage?.parts ?? []).filter(
206+
(p: any) => p.type === "text" && p.text
207+
);
208+
const finalContent = textParts.map((p: any) => p.text).join("");
209+
expect(finalContent.length).toBeGreaterThan(0);
211210

212211
// Verify the assistant followed the instruction and said the verification word
213212
// This proves resumeStream properly loaded history and continued from it
214-
expect(allText).toContain(verificationWord);
213+
expect(finalContent).toContain(verificationWord);
215214
} finally {
216215
await cleanup();
217216
}

0 commit comments

Comments
 (0)