首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >"window“在java ScriptEngine Selenium中没有定义。

"window“在java ScriptEngine Selenium中没有定义。
EN

Stack Overflow用户
提问于 2018-09-18 04:33:19
回答 1查看 2.6K关注 0票数 1

我在做什么

我正在尝试在javascript中调用一些在页面加载后执行的基本代码。我这样做是为了Selenium。为什么?我听到你在问,这是因为我做了一个简单的等待工具,如果点击或使用webelement导致页面重新加载,它会一直等到页面加载。这个‘工具’简单地使用main的一个线程来尝试webelement,等待它的引用变得陈旧,也等待'onload event‘在javascript中发生。如果这两种情况都发生在某个超时条件之前,那么我知道A: webelement导致页面重新加载,B:我已经适当地等待了页面重新加载。这很有用,因为我可以通过编程来确定给定的webelement是否会导致页面重新加载,只需尝试它并自动等待它。

问题所在

为了做到这一点,我需要在java中运行一个javascript onload事件。我刚接触ScriptEngine,但我研究了java附带的javascript API。我决定使用它,并在onload事件发生时尝试运行一个简单的javascript函数。问题是我一直得到一个“窗口”没有定义的异常。因为我用来运行javascript的ScriptEngine对象只接受我正在运行的内容的字符串,所以我不能很好地检查错误。

我尝试过的

我试着研究了关于这个错误的文档并搜索了堆栈溢出,但我似乎找不到一个以java为中心的答案,也没有一个对我来说解释得足够好的答案。我从研究中收集到的所有信息是,我可能需要指定一个URL作为窗口对象或其他东西,但其他来源使我相信,如果我使用浏览器窗口,则应该已经定义了窗口对象。我不知道该相信什么。有问题的代码是:

代码语言:javascript
复制
WebDriverWait wait = new WebDriverWait(driver, timeoutSeconds);
//initialize a wait for a page to reload
try {
    //wait untill our element we clicked is stale
    wait.until(ExpectedConditions.stalenessOf(webElement));
    //try running javascript to do something (here i tried a popup)
    //later I want this code to wait until the page is loaded and
    //then send something BACK to the javacode that I can wait for
    //so that Basically I wait until the page onload event has fired
    ScriptEngineManager manager = new ScriptEngineManager();
    ScriptEngine javascript = manager.getEngineByName("javascript");
    try {
        javascript.eval("window.addEventListener('load', function() 
                {" +
                " alert(ok); " +
                "})");
    } catch (ScriptException e) {
        e.printStackTrace();
        System.out.println("javascript thing failed");
    }

} catch (TimeoutException e) {
    //page remained static and webelement doesn't cause a page 
    //reload
}

请注意,此代码位于一个线程中,该线程与main一起运行。简单的目的是等待,直到我们单击的元素是陈旧的,并且页面onload事件已经被激发。如果这两种情况都没有发生,我们单击的webelement不会导致页面重新加载。如果元素变得陈旧,我们知道元素会改变,但是页面不会重新加载。如果这两件事都发生了,那么我们知道webelement会重新加载页面。一切都在适当地等待,下一个webelement已经准备好被发现了。这对Selenium很有用,因为我不必担心页面重新加载或元素自行删除,但不需要重新加载页面或任何其他奇怪的边缘情况,这些情况可能会导致StaleReference异常在不应该抛出时抛出。现在运行这段代码会返回这个堆栈跟踪:

在端口30355上启动ChromeDriver 2.41.578737 (49da6702b16031c40d63e5618de03a32ff6c197e),仅允许本地连接。Sep 17,2018 3:59:11 PM org.openqa.selenium.remote.ProtocolHandshake createSession信息:检测到的方言: OSS sendKeys[ChromeDriver: XP上的chrome (1c2e7600f13bc56ff3b60f9a2de6ee93) ->名称: q][Ljava.lang.CharSequence;@6dd2f3a9页面静态提交[ChromeDriver: XP上的chrome (1c2e7600f13bc56ff3b60f9a2de6ee93) ->名称:q]空

javascript failed

javax.script.ScriptException: ReferenceError:"window“未在>第1行处定义

重新加载的页面

at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:469) at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:453) at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:405) at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:401) at jdk.scripting.nashorn/由::1 java.base/java.lang.Thread.run(Thread.java:844)引起的窗口在java.scripting/javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)处的窗口:“ReferenceError”未在java.base/java.lang.Thread.run(Thread.java:844)中定义at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ECMAErrors.referenceError(ECMAErrors.java:319) at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ECMAErrors.referenceError(ECMAErrors.java:291) at jdk.scripting.nashorn/jdk.nashorn.internal.objects.Global.noSuchProperty(Global.java:1615) at jdk.scripting.nashorn.scripts/jdk.nashorn.internal.scripts.Script$Recompilation$1$\^eval_/1394969414.:program(:1)在jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:655) at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:513) at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:527) at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:448) ...还有6个

进程已完成,退出代码为0

补充说明

请注意堆栈跟踪中的粗体行,这些行是我在某些错误状态下添加的打印内容。在正常情况下,“页面已重新加载消息”也会打印为状态消息。它反映了代码的if else状态。javascript的失败在于捕捉javascript异常,并更明显地看到它确实失败了。我只想知道我应该做些什么来定义窗口,这样这段javascript代码(和将来的js代码)就可以为我运行了。考虑到我对java很有经验,但对javascript缺乏经验。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-09-18 08:09:28

ScriptEngineManager只能在JVM中执行javascript,不能在浏览器中执行。

但“window”在浏览器中是全局变量,而不是在JVM中。这就是为什么你会得到window is undefined.

在浏览器中执行javascript需要使用executeScript() Selenium api。

代码语言:javascript
复制
String script = "window.addEventListener('load', function() {" +
                "  alert('ok'); " +
                "})";

JavascriptExecutor js =(JavascriptExecutor)driver;
js.executeScript(script);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52375302

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档