Skip to content
Back to skills

Swift Testing Wait Until

ASecurity

Use when a test needs to wait for an async state change instead of a fixed delay — the `no_task_sleep_in_tests` lint rule bans arbitrary `Task.sleep` in tests because it causes flaky failures. Provides the `waitUntil` polling helper to add to a test target instead.

  • 3 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 2, 2026
ai-agentsswifttesting

Security analysis

A100/100

Scanned September 2, 2026

npx -y skills add patrickserrano/lacquer --skill swift-testing-wait-until --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Swift Testing Wait Until?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Swift Testing Wait Until
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/patrickserrano-swift-testing-wait-until/badge)](https://www.skillsdirectory.com/skills/patrickserrano-swift-testing-wait-until)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: swift-testing-wait-until
description: >
  Use when a test needs to wait for an async state change instead of a fixed
  delay — the `no_task_sleep_in_tests` lint rule bans arbitrary `Task.sleep`
  in tests because it causes flaky failures. Provides the `waitUntil` polling
  helper to add to a test target instead.
---

# `waitUntil`: No `Task.sleep` in Tests

Wait for the actual state change instead of a fixed delay. Add this
`TestHelpers.swift` to your test target (the lint rules already exclude
`*TestHelpers.swift`):

```swift
import Foundation

/// Thrown by `waitUntil` when the condition never became true within the timeout.
struct WaitTimeoutError: Error, CustomStringConvertible {
    let timeout: Duration
    var description: String { "waitUntil timed out after \(timeout)" }
}

/// Polls `condition` until true, throwing on timeout. Runs on the caller's actor
/// (via `#isolation`) so the closure may read `@MainActor` fixtures safely.
func waitUntil(
    timeout: Duration = .seconds(2),
    pollInterval: Duration = .milliseconds(10),
    isolation _: isolated (any Actor)? = #isolation,
    _ condition: () -> Bool
) async throws {
    let clock = ContinuousClock()
    let deadline = clock.now.advanced(by: timeout)
    while !condition() {
        guard clock.now < deadline else { throw WaitTimeoutError(timeout: timeout) }
        try await Task.sleep(for: pollInterval)
    }
}
```

Usage: `try await waitUntil { viewModel.isLoaded }` instead of
`try await Task.sleep(for: .seconds(1))`.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…