What problem does it solves?
This Skill solves the problem of flaky tests caused by arbitrary timeouts (setTimeout, sleep). It replaces guesswork with precise waiting for actual state changes, making your tests reliable, faster, and immune to timing-related inconsistencies.
Core Features & Use Cases
- Reliable Async Testing: Replaces fixed delays with polling for specific conditions (e.g., event received, state changed, file exists), ensuring tests pass consistently.
- Generic Polling Function: Provides a reusable
waitFor utility that polls a condition until true or a timeout is reached, with clear error messages.
- Domain-Specific Helpers: Includes examples like
waitForEvent, waitForEventCount, and waitForEventMatch for common async scenarios, adaptable to your codebase.
- Use Case: Instead of
await new Promise(r => setTimeout(r, 300)); hoping tools start, use await waitForEventCount(threadManager, threadId, 'TOOL_CALL', 2); to wait precisely for two tool calls, making your tests robust and efficient.
Quick Start
Example: Waiting for a result to be defined
❌ BEFORE: Guessing at timing
await new Promise(r => setTimeout(r, 50));
const result = getResult();
expect(result).toBeDefined();
✅ AFTER: Waiting for condition
async function waitFor<T>(
condition: () => T | undefined | null | false,
description: string,
timeoutMs = 5000
): Promise<T> {
const startTime = Date.now();
while (true) {
const result = condition();
if (result) return result;
if (Date.now() - startTime > timeoutMs) {
throw new Error(Timeout waiting for ${description} after ${timeoutMs}ms);
}
await new Promise(r => setTimeout(r, 10)); // Poll every 10ms
}
}
await waitFor(() => getResult() !== undefined, 'result to be defined');
const result = getResult();
expect(result).toBeDefined();