我正在通过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);
}
将等待放在任何其他位置也不起作用......
答案 0 :(得分: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);
}