{"record":{"id":"b2aa79242c845857","repo":"karatelabs/karate","slug":"page-load-complete-but-js-context-not-ready-yet","errorCode":null,"errorMessage":"page load complete but JS context not ready yet","messagePattern":"page load complete but JS context not ready yet","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"karate-core/src/main/java/io/karatelabs/driver/cdp/CdpDriver.java","lineNumber":1397,"sourceCode":"     */\n    public void waitForPageLoad(PageLoadStrategy strategy, Duration timeout) {\n        long deadline = System.currentTimeMillis() + timeout.toMillis();\n        long lastStaleCheck = 0;\n\n        while (true) {\n            // Snapshot the wake-up latch BEFORE evaluating conditions: an event\n            // landing between the check below and the wait completes THIS snapshot,\n            // so the signal cannot be lost (see nudgeLoadWaiter).\n            CompletableFuture<Void> tick = loadTick;\n\n            if (isPageLoadComplete(strategy)) {\n                // Verify JS execution works (execution context is ready)\n                // This handles the case where page events fired but context isn't ready\n                if (verifyJsExecution()) {\n                    return;\n                }\n                // Context not ready yet, keep waiting\n                logger.warn(\"page load complete but JS context not ready yet\");\n            } else if (domContentEventFired && !framesStillLoading.isEmpty()) {\n                // DOM is ready but frames appear to still be loading\n                // Periodically verify these frames still exist - frameStoppedLoading\n                // event can be lost in CI environments (observed as flaky timeout)\n                long now = System.currentTimeMillis();\n                if (now - lastStaleCheck > 2000) {\n                    lastStaleCheck = now;\n                    pruneStaleFrames();\n                }\n            }\n\n            long remaining = deadline - System.currentTimeMillis();\n            if (remaining <= 0 || Thread.currentThread().isInterrupted()) {\n                break;\n            }\n            // Event-driven wait with a CAP, not a pure future wait: the conditions\n            // above include polling fallbacks (document.readyState, pruneStaleFrames)\n            // that exist precisely because load events get lost under CI load — a","sourceCodeStart":1379,"sourceCodeEnd":1415,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/driver/cdp/CdpDriver.java#L1379-L1415","documentation":"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).","triggerScenarios":"driver.get()/loadUrl() where domContentEventFired is true but verifyJsExecution() (a probe script via the context script() will use) throws or returns nothing yet.","commonSituations":"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.","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."],"exampleFix":"// before\nkarate.configure('timeout', 15000); // context probe races load event\n// after\nkarate.configure('timeout', 30000); // allow execution context to register after load events","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { driver.get(url); } catch (RuntimeException e) { if (e.getMessage().contains(\"page load timeout\")) { driver.get(url); } else { throw e; } }","preventionTips":["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"],"tags":["cdp","execution-context","page-load","race-condition"],"backgroundTag":"js-execution-context-not-ready","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}