karatelabs/karate · error · DriverException
timeout waiting for URL to contain
Error message
timeout waiting for URL to contain: ${expected} What it means
CdpDriver.waitForUrl(expected, timeout) repeatedly reads the current page URL via CDP and returns it once it contains the expected substring; if the poll never matches within the timeout, a DriverException is thrown. This is the designated wait for client-side navigations / SPA route changes.
Solutions
- Increase the timeout to cover slow environments
- Print the actual URL (driver.getUrl()) after failure and correct the expected substring
- Wait for the condition that causes navigation (click/login response) to succeed before waiting on the URL
- Use waitForUrl with a stable path fragment rather than volatile query params
Example fix
// before
String url = driver.waitForUrl("http://localhost:8080/app?token=", Duration.ofSeconds(5));
// after
String url = driver.waitForUrl("/app", Duration.ofSeconds(15)); Defensive patterns
Strategy: try-catch
Validate before calling
String current = driver.getUrl();
if (current != null && current.contains("/app")) { /* already there, skip wait */ } Try / catch
try {
String url = driver.waitForUrl("/dashboard", Duration.ofSeconds(20));
} catch (DriverException e) {
logger.error("URL wait failed; actual={}, expected-contains={}", driver.getUrl(), "/dashboard");
throw e;
} Prevention
- Match on a stable path fragment, not volatile query params or full URLs
- Log the actual URL on failure to distinguish wrong-route vs slow-load
- Verify the navigation trigger (click/login) succeeded before waiting
When it happens
Trigger: driver.waitForUrl("/dashboard", Duration.ofSeconds(10)) when navigation did not happen, happened to a different URL, or took longer than the timeout; expected substring spelled differently from the actual URL (query params, hash, trailing slash).
Common situations: Login failed so the app stayed on the login page; SPA router redirected to an error route; redirect chain exceeded the wait budget on slow CI; expected substring includes a host while the URL compared is a path, or vice versa.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- waitForUrl timeout: expected URL containing
- driver URL evaluated to null:
- page load timeout after
- element not found after
- timeout waiting for element
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/2151eb9a80d57346.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/driver/cdp/CdpDriver.java:3390
}
/**
* Wait for URL to contain expected string.
*/
public String waitForUrl(String expected) {
return waitForUrl(expected, options.getTimeoutDuration());
}
/**
* Wait for URL to contain expected string with custom timeout.
*/
public String waitForUrl(String expected, Duration timeout) {
String found = pollFor(timeout.toMillis(), options.getRetryInterval(), () -> {
String url = getUrl();
return url != null && url.contains(expected) ? url : null;
});
if (found == null) {
throw new DriverException("timeout waiting for URL to contain: " + expected);
}
return found;
}
/**
* Wait until a JavaScript expression on an element evaluates to truthy.
* The element is available as '_' in the expression.
*/
public Element waitUntil(String locator, String expression) {
return waitUntil(locator, expression, options.getTimeoutDuration());
}
/**
* Wait until a JavaScript expression on an element evaluates to truthy.
*/
public Element waitUntil(String locator, String expression, Duration timeout) {
Element found = pollFor(timeout.toMillis(), options.getRetryInterval(),
() -> exists(locator) && Terms.isTruthy(script(locator, expression))View on GitHub (pinned to a22eb90246)