2011-07-19 108 views
0

我使用的webdriver通过JBehave的Web分布(3.3.4)来测试应用程序,我面临着很奇怪的东西:的webdriver执行JavaScript奇怪的行为

我试图用来自modalPanel互动Richfaces,它给我很多问题,因为它抛出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);  
} 

把等待其他任何位置不工作,要么...

回答

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); 
} 
+0

喜乔,感谢您的答复。不幸的是,它不起作用:在第一种情况下,我总是可以正确地获取元素,这似乎不是问题所在。对于第二个,在检索元素之前添加一个等待不起作用,它只在等待检索元素之后并且在执行javascript之前进行等待。 – jasalguero

+0

当您说“检索元素后”时,哪一行代码你指的是? –

+0

如果我把你在代码中的等待,使用WebDriverWait它不起作用。不会给出任何错误,但不会更新网站。但是如果我在调用executeScript方法之前添加等待,它就会起作用 – jasalguero