WaitEngine
WaitEngine is a static utility class available via WaitEngine.waitForXxx(...) calls. It is pre-configured with the timeout from testfly.yml (timeouts.explicit).
import io.testfly.wait.WaitEngine;
Available methods
Element visibility
WaitEngine.waitForVisible(By.id("modal"));
WaitEngine.waitForInvisible(By.cssSelector(".spinner")); // wait for loaders to disappear
Clickability
WaitEngine.waitForClickable(By.id("submit"));
Enabled / disabled
WaitEngine.waitForEnabled(By.id("submit")); // ready to interact
WaitEngine.waitForDisabled(By.id("submit")); // button is greyed out
Selected
WaitEngine.waitForSelected(By.id("terms")); // checkbox or radio is checked
Text content
WaitEngine.waitForText(By.cssSelector("h1"), "Welcome back");
Attribute value
WaitEngine.waitForAttributeContains(By.id("status"), "class", "active"); // substring
WaitEngine.waitForAttribute(By.id("status"), "aria-expanded", "true"); // exact match
Text matches (regex)
// Wait until the element's visible text matches a regular expression
WaitEngine.waitForTextMatches(By.cssSelector(".total"), "\\$\\d+\\.\\d{2}");
URL matches (regex)
WaitEngine.waitForUrlContains("/orders"); // substring
WaitEngine.waitForUrlMatches(".*/orders/\\d+"); // regular expression
DOM staleness
WebElement old = getDriver().findElement(By.id("row-1"));
WaitEngine.waitForStaleness(old); // wait for DOM replacement / AJAX reload
Page load
WaitEngine.waitForPageLoad(); // waits until document.readyState === "complete"
Windows and frames
WaitEngine.waitForNumberOfWindowsToBe(2); // new tab opened
WaitEngine.waitForFrameAvailableAndSwitchToIt(By.id("payment-iframe"));
Minimum element count
Useful for lists and infinite-scroll feeds that grow asynchronously:
WaitEngine.waitForMinimumElementCount(By.cssSelector(".product-card"), 10);
Custom condition
// Escape hatch — pass any ExpectedCondition
WaitEngine.wait(ExpectedConditions.numberOfWindowsToBe(2));
Custom timeout
WaitEngine always uses the global timeout from testfly.yml. If you need a one-off custom timeout, create a WebDriverWait directly:
// Custom timeout — create a WebDriverWait directly
new WebDriverWait(getDriver(), Duration.ofSeconds(30))
.until(ExpectedConditions.visibilityOfElementLocated(By.id("slow-element")));
Configuration
testfly.yml
timeouts:
explicit: 10 # seconds — default for all WaitEngine calls
pageLoad: 30 # seconds — browser page load timeout
Anti-patterns to avoid
// ❌ never do this
Thread.sleep(3000);
// ✅ do this instead
WaitEngine.waitForVisible(By.id("result"));
// ❌ raw WebDriverWait — bypasses framework timeout config
new WebDriverWait(getDriver(), Duration.ofSeconds(10))
.until(ExpectedConditions.visibilityOfElementLocated(By.id("result")));
// ✅ use WaitEngine — reads timeout from config
WaitEngine.waitForVisible(By.id("result"));