2011-07-19 194 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