You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法从Karate Feature文件执行JS实现浏览器元素动态等待

Karate中执行JS实现元素动态等待报错问题

我尝试在Karate Feature文件中执行JavaScript,实现浏览器Web元素的动态等待。按照文档说明,我用script方法定义了如下脚本:

* def waitForElementToDisplay =
 """
 function (selector, checkFrequencyInMs, timeoutInMs) {
 var startTimeInMs = Date.now();
 (function loopSearch() {
 if (document.evaluate(selector, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, 
 null).singleNodeValue != null) {
 return ;
}
else {
  setTimeout(function () {
    if (timeoutInMs && Date.now() - startTimeInMs > timeoutInMs)
      return;
    loopSearch();
  }, checkFrequencyInMs);
}
})();
}
"""

之后我在Feature文件中通过以下代码直接调用该JS函数:

* script(waitForElementToDisplay("//*[text()='Show card number']",1000,10000))

但执行时出现了如下错误:

109 * script(waitForElementToDisplay("//*[text()='Show card number']",1000,10000))
14:33:22.972 src/test/java/tests/android/imageText.feature:109
* script(waitForElementToDisplay("//*[text()='Show card number']",1000,10000))
js failed:
>>>>>>
01: script(waitForElementToDisplay("//*[text()='Show card number']",1000,10000))
<<<<<<
org.graalvm.polyglot.PolyglotException: ReferenceError: "document" is not defined
- <js>.loopSearch(Unnamed:4)

src/test/java/tests/android/imageText.feature:109

问题原因及解决办法

报错document is not defined是因为你写的JS函数跑在Karate的服务器端JS引擎里,根本碰不到浏览器的document对象——Karate的script方法默认是在自身上下文执行代码,不是在浏览器里。

其实Karate本身就有原生的元素等待能力,完全不用自己写JS:

  • 最简单的写法,直接等待元素出现:
* waitFor('//*[text()="Show card number"]')
  • 要自定义轮询间隔(1000ms)和超时时间(10000ms),先配置再调用:
* configure waitFor = { interval: 1000, timeout: 10000 }
* waitFor('//*[text()="Show card number"]')

如果非要用自定义JS逻辑,得把整个函数和调用逻辑作为字符串传给script,让它在浏览器环境里执行,而不是提前定义在Karate的上下文:

* script("""
function waitForElementToDisplay(selector, checkFrequencyInMs, timeoutInMs) {
  var startTimeInMs = Date.now();
  (function loopSearch() {
    if (document.evaluate(selector, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue != null) {
      return;
    } else {
      setTimeout(function () {
        if (timeoutInMs && Date.now() - startTimeInMs > timeoutInMs)
          return;
        loopSearch();
      }, checkFrequencyInMs);
    }
  })();
}
waitForElementToDisplay("//*[text()='Show card number']", 1000, 10000)
""")

内容的提问来源于stack exchange,提问作者abdul khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 12:31:25