【问题标题】:WebDriver executing javascript strange behaviourWebDriver 执行 javascript 奇怪的行为
【发布时间】:2011-07-27 16:26:37
【问题描述】:

我正在通过 JBehave-Web 分发版 (3.3.4) 使用 Webdriver 来测试应用程序,但我遇到了一些很奇怪的事情:

我正在尝试与 Richfaces 中的 modalPanel 进行交互,这给了我很多问题,因为它抛出了 ElementNotVisibleException。我通过使用 javascript 解决了它:

这是从 org.jbehave.web.selenium.WebDriverPage 扩展而来的页面对象中的代码

protected void changeModalPanelInputText(String elementId, String textToEnter){
    makeNonLazy();
    JavascriptExecutor je = (JavascriptExecutor) webDriver();
    String script ="document.getElementById('" + elementId + "').value = '" + textToEnter + "';";
    je.executeScript(script);
}

奇怪的行为是,如果我正常执行测试,它什么也不做,但是如果我在最后一行(在 Eclipse 中)放置一个断点,选择该行并从 Eclipse 执行(Ctrl + U),我可以看到浏览器的变化。

我检查了 JavascriptExecutor 和 WebDriver 类以查看是否有任何类型的缓冲,但我找不到任何东西。有什么想法吗?

编辑 我发现让线程休眠 1 秒钟可以让它工作,所以它看起来是某种竞争条件,但不知道为什么......

这是它“工作”的方式,但我对此不太满意:

protected void changeModalPanelInputText(String elementId, String textToEnter){
    String script ="document.getElementById('" + elementId + "').value = '" + textToEnter + "';";
    executeJavascript(script);
}

    private void executeJavascript(String script){
    makeNonLazy();
    JavascriptExecutor je = (JavascriptExecutor) webDriver();
    try {
        Thread.sleep(1500);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    je.executeScript(script);       
}

将等待放在任何其他位置也不起作用...

【问题讨论】:

    标签: javascript testing selenium webdriver


    【解决方案1】:

    第一个想法:

    确保目标元素已初始化且可枚举。看看这是否返回null

    Object objValue = je.executeScript(
        "return document.getElementById('"+elementId+"');");
    

    由于您使用的是makeNonLazy(),因此可能只需将目标添加为页面对象的 WebElement 成员(假设 JBehave 中的初始化类型为 Page Factory)。

    第二个想法:

    在变异前明确等待元素可用:

    /**
     * re-usable utility class
     */
    public static class ElementAvailable implements Predicate<WebDriver> {
    
        private static String IS_NOT_UNDEFINED = 
            "return (typeof document.getElementById('%s') != 'undefined');";
        private final String elementId;
    
        private ElementAvailable(String elementId) {
            this.elementId = elementId;
        }
    
        @Override
        public boolean apply(WebDriver driver) {
            Object objValue = ((JavascriptExecutor)driver).executeScript(
                    String.format(IS_NOT_UNDEFINED, elementId));
            return (objValue instanceof Boolean && ((Boolean)objValue));
        }
    }
    
    ...
    
    protected void changeModalPanelInputText(String elementId, String textToEnter){
        makeNonLazy();
    
        // wait at most 3 seconds before throwing an unchecked Exception
        long timeout = 3;
        (new WebDriverWait(webDriver(), timeout))
                .until(new ElementAvailable(elementId));
    
        // element definitely available now
        String script = String.format(
                "document.getElementById('%s').value = '%s';",
                elementId,
                textToEnter);
        ((JavascriptExecutor) webDriver()).executeScript(script);
    }
    

    【讨论】:

    • 嗨,乔,感谢您的回复。不幸的是,它不起作用:在第一种情况下,我总是可以正确获取元素,这似乎不是问题。对于第二个,在检索元素之前添加等待不起作用,它只有在我在检索元素之后和执行 javascript 之前放置等待时才有效
    • 当你说“在检索元素之后”时,你指的是哪一行代码?
    • 如果我按照您在代码中的方式等待,使用 WebDriverWait 它将不起作用。不会给出任何错误,但不会更新网站。但是如果我在调用 executeScript 方法之前添加等待,它就可以工作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-20
    • 1970-01-01
    • 2011-07-28
    • 2012-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多