karatelabs/karate · warning
page load complete but JS context not ready yet
Error message
page load complete but JS context not ready yet
What it means
During waitForPageLoad, the driver's load-complete condition requires not only page-load events but also a working JS execution context. This warning is logged when page load events (DOMContentLoaded/load) fired but verifyJsExecution() still fails, meaning script() cannot yet execute in the context. The wait loop keeps polling rather than returning, so the caller experiences a delayed return or, if the context never becomes ready, the eventual page-load timeout (error 844).
Solutions
- Increase the page-load timeout to give the execution context time to register.
- Retry the navigation; the race usually resolves on a second attempt.
- Update Chrome/Chromium — older builds emit context events late under load.
- If persistent, log window performance and reduce page JS (extensions, analytics) slowing context creation.
Example fix
// before
karate.configure('timeout', 15000); // context probe races load event
// after
karate.configure('timeout', 30000); // allow execution context to register after load events Defensive patterns
Strategy: retry
Try / catch
try { driver.get(url); } catch (RuntimeException e) { if (e.getMessage().contains("page load timeout")) { driver.get(url); } else { throw e; } } Prevention
- Increase page-load timeout on CI
- Keep Chrome/Chromium updated
- Trim heavy page JS (extensions/analytics) in test environments
- Retry navigation once when this warning precedes a timeout
When it happens
Trigger: driver.get()/loadUrl() where domContentEventFired is true but verifyJsExecution() (a probe script via the context script() will use) throws or returns nothing yet.
Common situations: Fast page-load events racing execution-context creation in headless Chrome, heavy page JS delaying context readiness, or CI environments where frame/context events arrive out of order.
Related errors
- dialog accept failed
- dialog dismiss failed
- page load timeout after
- readyState check failed
- main-frame context not ready, retry
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/b2aa79242c845857.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/driver/cdp/CdpDriver.java:1397
*/
public void waitForPageLoad(PageLoadStrategy strategy, Duration timeout) {
long deadline = System.currentTimeMillis() + timeout.toMillis();
long lastStaleCheck = 0;
while (true) {
// Snapshot the wake-up latch BEFORE evaluating conditions: an event
// landing between the check below and the wait completes THIS snapshot,
// so the signal cannot be lost (see nudgeLoadWaiter).
CompletableFuture<Void> tick = loadTick;
if (isPageLoadComplete(strategy)) {
// Verify JS execution works (execution context is ready)
// This handles the case where page events fired but context isn't ready
if (verifyJsExecution()) {
return;
}
// Context not ready yet, keep waiting
logger.warn("page load complete but JS context not ready yet");
} else if (domContentEventFired && !framesStillLoading.isEmpty()) {
// DOM is ready but frames appear to still be loading
// Periodically verify these frames still exist - frameStoppedLoading
// event can be lost in CI environments (observed as flaky timeout)
long now = System.currentTimeMillis();
if (now - lastStaleCheck > 2000) {
lastStaleCheck = now;
pruneStaleFrames();
}
}
long remaining = deadline - System.currentTimeMillis();
if (remaining <= 0 || Thread.currentThread().isInterrupted()) {
break;
}
// Event-driven wait with a CAP, not a pure future wait: the conditions
// above include polling fallbacks (document.readyState, pruneStaleFrames)
// that exist precisely because load events get lost under CI load — aView on GitHub (pinned to a22eb90246)