condition-based-waiting

Replace arbitrary timeouts with condition polling for asynchronous tests.

270k|24.1k|Updated Oct 9, 2025
One-click install
npx skills add https://github.com/obra/superpowers --skill condition-based-waiting-obra
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: condition-based-waiting
Source: https://github.com/obra/superpowers/tree/main/skills/condition-based-waiting
Command: npx skills add https://github.com/obra/superpowers --skill condition-based-waiting-obra

SYSTEM DOCUMENTATION & REQUIREMENTS

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();

Frequently Asked Questions about condition-based-waiting

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I eliminate flaky tests caused by timing issues?

Replace arbitrary timeouts with condition-based polling. Instead of guessing delays with `setTimeout`, use a `waitFor` function that repeatedly checks a condition until it's true or a timeout occurs, making tests reliable and immune to timing inconsistencies.

What's the best way to wait for asynchronous state changes in tests?

Implement a polling mechanism that evaluates a condition at regular intervals (e.g., every 10ms) until it succeeds or times out. This approach handles race conditions, event arrivals, state transitions, and resource availability without arbitrary delays.

How do I replace sleep and setTimeout in async tests?

Use condition-based polling instead. Define a condition function that returns the expected value or state, then poll it with a timeout. This eliminates guesswork, speeds up tests, and provides clear error messages when conditions aren't met.

Can I use polling for unit, integration, and end-to-end tests?

Yes. Condition-based polling works across all test levels. Create domain-specific helpers like `waitForEvent`, `waitForEventCount`, or `waitForEventMatch` tailored to your framework and codebase for consistent, reusable async waiting.

What's the difference between timeouts and condition polling?

Timeouts are fixed delays that hope state changes occur; polling actively checks if a condition is true at regular cadences. Polling is faster, more reliable, and provides meaningful failure messages when the expected state never arrives.

Do I need special setup to implement condition-based waiting?

No. The pattern requires only basic async/await support and a simple polling loop with a condition evaluator and timeout. No external dependencies are needed; you can implement it directly in your test framework.