How to Use WaitHelper in Ocaramba for Reliable Test Synchronization

WaitHelper in Ocaramba provides synchronous polling utilities that pause test execution until a condition becomes true or a timeout expires, throwing WaitTimeoutException when the deadline is missed.

The WaitHelper class is a core component of the Ocaramba test automation framework, offering reusable wait utilities designed for synchronous test steps. Located in OcarambaLite/Helpers/WaitHelper.cs, this helper eliminates fragile Thread.Sleep calls by continuously evaluating a condition until it succeeds or a configurable timeout elapses.

Understanding WaitHelper Architecture

Core Polling Mechanism

Under the hood, WaitHelper implements an asynchronous polling loop using Task.Run and Task.Delay. The helper spins up two concurrent tasks: one repeatedly evaluates the supplied condition at a configurable interval, and another simply delays for the timeout duration. Whichever task completes first determines the outcome.

If the condition task finishes first, its result (or any thrown exception) is propagated immediately. If the timeout task wins, the method either returns false or throws WaitTimeoutException depending on the overload used. A short Thread.Sleep in the coordination loop prevents CPU spinning while awaiting task completion.

Exception Handling with WaitTimeoutException

When a wait operation exceeds its timeout, WaitHelper throws WaitTimeoutException defined in OcarambaLite/Exceptions/WaitTimeoutException.cs. This custom exception carries a descriptive message indicating which condition failed to materialize, making test failures easier to diagnose without debugging.

WaitHelper Methods and Overloads

The WaitHelper class in OcarambaLite/Helpers/WaitHelper.cs provides three distinct overload patterns to accommodate different testing scenarios.

Void Overloads That Throw on Timeout

The most common pattern for page-object methods uses the void overloads that throw WaitTimeoutException on failure:

// Basic void wait with custom message
WaitHelper.Wait(
    () => condition,
    timeout,
    message);

// Void wait with custom polling interval
WaitHelper.Wait(
    () => condition,
    timeout,
    interval,
    message);

These signatures appear throughout the framework, such as in FormAuthenticationPage.cs, where waits ensure elements are ready before interaction.

Boolean Overload for Conditional Logic

When tests need to branch based on availability rather than fail immediately, use the boolean-returning overload:

bool result = WaitHelper.Wait(
    () => condition,
    timeout,
    interval);

This returns true if the condition succeeds within the timeout, or false if the deadline passes without throwing an exception.

Customizing Polling Intervals

All overloads support custom intervals to balance responsiveness with system load. The default interval is typically one second, but you can reduce this for rapidly-changing conditions:

// Poll every 500ms for faster detection
WaitHelper.Wait(
    () => Driver.GetElement(locator).Displayed,
    TimeSpan.FromSeconds(10),
    TimeSpan.FromMilliseconds(500),
    "Element failed to display");

Practical Code Examples

Waiting for UI Elements in Page Objects

The canonical use case appears in page-object classes like FormAuthenticationPage.cs. Here, WaitHelper pauses execution until a login button becomes visible before attempting interaction:

// Wait up to the global long timeout for a button to become visible.
// If it never appears, a WaitTimeoutException with a clear message is thrown.
WaitHelper.Wait(
    () => Driver.GetElement(loginButtonLocator).Displayed,
    TimeSpan.FromSeconds(BaseConfiguration.LongTimeout),
    "Login button never became visible");

This pattern prevents NoSuchElementException or ElementNotVisibleException by ensuring state readiness before action.

Handling File System Operations

WaitHelper also handles non-UI polling scenarios. In FilesHelper.cs, the utility waits for file system changes such as file creation or deletion:

// Wait for a file to appear in a directory
WaitHelper.Wait(
    () => File.Exists(filePath),
    TimeSpan.FromSeconds(30),
    TimeSpan.FromSeconds(1),
    $"File {fileName} was not created within timeout");

This demonstrates the framework's flexibility beyond browser automation.

Unit Testing Timeout Behavior

The test suite in WaitHelperTests.cs verifies that WaitHelper correctly throws WaitTimeoutException when conditions fail:

[Test]
public void ShouldThrowWhenConditionNeverMet()
{
    Assert.Throws<WaitTimeoutException>(() =>
        WaitHelper.Wait(
            () => false,
            TimeSpan.FromSeconds(2),
            TimeSpan.FromSeconds(1),
            "Condition never became true"));
}

This pattern ensures your own wait logic behaves predictably under failure conditions.

Best Practices for WaitHelper in Ocaramba

  • Prefer explicit messages: Always provide the message parameter in void overloads to produce actionable failure logs.
  • Match timeout to context: Use BaseConfiguration.LongTimeout for page loads, but shorter durations for element visibility checks.
  • Adjust polling intervals: Reduce the interval to 500ms for rapidly-appearing elements, but keep 1-2s for slow-loading resources to reduce CPU load.
  • Handle exceptions explicitly: Catch WaitTimeoutException only when implementing fallback logic; otherwise, let it propagate to fail the test with a clear message.
  • Avoid sub-millisecond intervals: The helper uses Task.Delay, which has ~15ms granularity on Windows; finer polling wastes resources without improving reliability.

Summary

  • WaitHelper in OcarambaLite/Helpers/WaitHelper.cs provides synchronous polling utilities that wait until a condition becomes true or a timeout expires.
  • The helper offers three overload patterns: void methods that throw WaitTimeoutException, and a boolean-returning method for conditional logic.
  • Under the hood, it uses dual Task coordination—one for condition polling and one for timeout—to efficiently manage wait operations without blocking threads indefinitely.
  • Practical applications include waiting for UI element visibility in page objects, polling file system changes, and verifying timeout behavior in unit tests.
  • Always provide descriptive timeout messages and choose appropriate polling intervals to balance test reliability with system performance.

Frequently Asked Questions

What exception does WaitHelper throw when a timeout occurs?

When the specified timeout expires before the condition becomes true, WaitHelper throws WaitTimeoutException. This custom exception is defined in OcarambaLite/Exceptions/WaitTimeoutException.cs and includes the descriptive message you provided in the method call, making it easy to identify which specific wait condition failed during test execution.

How do I configure the polling interval in WaitHelper?

You can configure the polling interval by using the overload that accepts a TimeSpan interval parameter. For example: WaitHelper.Wait(() => condition, timeout, TimeSpan.FromMilliseconds(500), message). This polls the condition every 500 milliseconds rather than using the default interval. Adjust this value based on how quickly you expect the condition to change—shorter intervals for fast-appearing UI elements, longer intervals for slow-loading resources.

Can WaitHelper return a boolean instead of throwing an exception?

Yes, WaitHelper provides a boolean-returning overload located at lines 85-120 in WaitHelper.cs. Use the signature bool result = WaitHelper.Wait(() => condition, timeout, interval). This returns true if the condition succeeds within the timeout period, or false if the timeout expires. This pattern is useful when you need to implement conditional logic or fallback behavior rather than failing the test immediately.

Where can I find real-world examples of WaitHelper usage in Ocaramba?

Real-world examples appear throughout the Ocaramba repository, particularly in the page-object classes and helper utilities. Check Ocaramba.Tests.PageObjects/PageObjects/TheInternet/FormAuthenticationPage.cs to see how WaitHelper waits for login button visibility. For file-system polling examples, examine OcarambaLite/Helpers/FilesHelper.cs. The unit test suite in Ocaramba.UnitTests/Tests/WaitHelperTests.cs provides additional examples of verifying timeout behavior and exception handling.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →