{"record":{"id":"c8bb65e06d954601","repo":"karatelabs/karate","slug":"waitfor-timeout-locator","errorCode":null,"errorMessage":"waitFor timeout: ${locator}","messagePattern":"waitFor timeout: (.+?)","errorType":"exception","errorClass":"DriverException","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/driver/w3c/W3cDriver.java","lineNumber":529,"sourceCode":"    }\n\n    // ========== Wait Methods ==========\n\n    @Override\n    public Element waitFor(String locator) {\n        return waitFor(locator, options.getTimeoutDuration());\n    }\n\n    @Override\n    public Element waitFor(String locator, java.time.Duration timeout) {\n        long deadline = System.currentTimeMillis() + timeout.toMillis();\n        while (System.currentTimeMillis() < deadline) {\n            if (exists(locator)) {\n                return BaseElement.existing(this, locator);\n            }\n            sleep(options.getRetryInterval());\n        }\n        throw new DriverException(\"waitFor timeout: \" + locator);\n    }\n\n    @Override\n    public Element waitForAny(String locator1, String locator2) {\n        return waitForAny(new String[]{locator1, locator2});\n    }\n\n    @Override\n    public Element waitForAny(String[] locators) {\n        return waitForAny(locators, options.getTimeoutDuration());\n    }\n\n    @Override\n    public Element waitForAny(String[] locators, java.time.Duration timeout) {\n        long deadline = System.currentTimeMillis() + timeout.toMillis();\n        while (System.currentTimeMillis() < deadline) {\n            for (String locator : locators) {\n                if (exists(locator)) {","sourceCodeStart":511,"sourceCodeEnd":547,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/driver/w3c/W3cDriver.java#L511-L547","documentation":"W3cDriver.waitFor polls for the locator's existence every options.getRetryInterval() until the deadline (options.getTimeoutDuration()) elapses. If the element never exists within the timeout, a DriverException is thrown naming the locator. This is Karate's driver-level wait mechanism, distinct from UI implicit waits.","triggerScenarios":"Calling driver.waitFor(locator) (or waitFor(locator, timeout)) when the element matching the locator is not present in the DOM at each poll within the timeout window; also triggered by a wrong selector, an element inside an unopened iframe, or a timeout too short for a slow page load.","commonSituations":"Wrong/typo'd selector; element rendered lazily by SPA after timeout; element in a shadow DOM or iframe not switched to; test env slower than CI defaults (timeout too small); selector targets an element removed before polling starts.","solutions":["Verify the locator matches in the browser (devtools querySelector) and fix selector syntax","Increase the timeout: waitFor(locator, 30000) or set the driver timeout option in karate-config","If the element is inside an iframe/shadow DOM, switch context or use the appropriate locator strategy first","If the element should genuinely not exist, use exists()/waitForAbsent-style logic instead of waitFor"],"exampleFix":"// before\nElement el = driver.waitFor('#slow-widget'); // 10s default, SPA loads in 20s\n// after\nElement el = driver.waitFor('#slow-widget', 30000);","handlingStrategy":"try-catch","validationCode":"if (!driver.exists(locator)) {\n    // optionally poll manually or extend timeout before calling waitFor\n}","typeGuard":null,"tryCatchPattern":"try {\n    Element el = driver.waitFor(locator, timeout);\n} catch (DriverException e) {\n    // log driver.html('body') snapshot, fail or fall back\n}","preventionTips":["Always pass an explicit timeout sized for your slowest environment","Verify selectors in devtools before committing them to tests","Switch to iframe/shadow context before waiting on nested elements"],"tags":["webdriver","timeout","wait","dom"],"backgroundTag":"request-timeout","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"}