karatelabs/karate · warning

timeout waiting for OOPIF readiness: frameId=

Error message

timeout waiting for OOPIF readiness: frameId={}, expectedUrl={} (will retry on first use)

What it means

For cross-origin (OOPIF) frames, CdpDriver polls document.readyState (and document.URL vs the expected URL) on the OOPIF's own CDP session for up to 2s. If the frame's document never leaves 'loading' or the URL never commits, this warning is logged. It is intentionally non-fatal: the element-level retry logic (retryIfNeeded) will retry on first use.

Solutions

  1. Increase the driver's retry interval / timeouts so the first-use retry absorbs the remainder of the load.
  2. Wait for the iframe's content (e.g. waitFor on an element inside the frame or waitForUrl) before interacting.
  3. Ensure the iframe URL is final — avoid switching frames while the iframe is still redirecting.
  4. Free CI resources / reduce load; OOPIF readiness polling is latency-sensitive.

Example fix

// before
driver.switchFrame("iframe.cross-origin");
driver.click("#button-in-frame"); // races parser
// after
driver.switchFrame("iframe.cross-origin");
driver.waitFor("#button-in-frame");
driver.click("#button-in-frame");
Defensive patterns

Strategy: retry

Validate before calling

// wait for the iframe to finish its own navigation before switching
driver.waitForUrl("**/checkout");
driver.waitFor("iframe.cross-origin");

Try / catch

driver.switchFrame(iframeLocator);
driver.waitFor("#element-inside-frame"); // built-in retry absorbs OOPIF readiness remainder

Prevention

When it happens

Trigger: switchFrame() into a cross-origin iframe whose document takes longer than 2s to parse, or whose document.URL never matches the URL captured at match time — slow networks, heavy OOPIF pages, or cross-process navigation delays.

Common situations: Testing embedded third-party iframes (payment, captcha, video) on slow CI networks, OOPIF iframes redirecting again immediately after load, or resource-starved CI containers where parsing is slow.

Understand the failure class

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/e625c10a105e8e69. Report an issue: GitHub.

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/driver/cdp/CdpDriver.java:2609

                            logger.trace("OOPIF ready: frameId={}, readyState={}, url={}", frameId, r, u);
                            return true;
                        }
                    }
                } else {
                    Object value = response.getResult("result.value");
                    if (value instanceof String && !"loading".equals(value)) {
                        logger.trace("OOPIF ready: frameId={}, readyState={}", frameId, value);
                        return true;
                    }
                }
            } catch (Exception e) {
                logger.trace("OOPIF readiness check failed (will retry): {}", e.getMessage());
            }
            return false;
        });
        if (!ready) {
            // Not fatal — element-level retry in retryIfNeeded() will absorb any remainder.
            logger.warn("timeout waiting for OOPIF readiness: frameId={}, expectedUrl={} (will retry on first use)",
                    frameId, expectedUrl);
        }
    }

    /**
     * Verify a (non-main) frame's execution context is actually ready for JS
     * execution. Context-id ARRIVAL is event-driven (see awaitFrameContext); this
     * probe is deliberately still a poll — "the id exists" does not mean "the
     * frame's document is ready to run script" (it may still be loading), and no
     * CDP event announces that transition for a contextId-addressed world.
     */
    private void waitForFrameContextReady(String frameId) {
        boolean ready = pollUntil(1000, 50, () -> {
            Integer contextId = frameContexts.get(frameId);
            if (contextId == null) {
                return false;
            }
            try {

View on GitHub (pinned to a22eb90246)