Java WebDriver.findElements引发InvalidElementStateException
我编写了一个简单的方法来检查WebElement是否已启用,并将此方法放在我的测试用例超级对象中:Java WebDriver.findElements引发InvalidElementStateException,java,selenium,webdriver,selenium-webdriver,Java,Selenium,Webdriver,Selenium Webdriver,我编写了一个简单的方法来检查WebElement是否已启用,并将此方法放在我的测试用例超级对象中: protected boolean isElementEnabled(By by) { // Temporarily set the implicit timeout to zero int originalTimeout = Integer.parseInt(System.getProperty( "com.brainshark.uitests.timeo
protected boolean isElementEnabled(By by) {
// Temporarily set the implicit timeout to zero
int originalTimeout = Integer.parseInt(System.getProperty(
"com.brainshark.uitests.timeout", "120"));
driver.manage().timeouts().implicitlyWait(0, TimeUnit.MILLISECONDS);
// Check to see if there are any elements in the found list
List<WebElement> elements = driver.findElements(by);
boolean isEnabled = (elements.size() == 1)
&& elements.get(0).isEnabled();
// Return to the original implicit timeout value
driver.manage().timeouts()
.implicitlyWait(originalTimeout, TimeUnit.SECONDS);
return isEnabled;
}
为了验证,上面的定位器正在尝试定位带有href属性的锚元素,该属性包含“CorpAdmin/DisplayInformation”,它是id=top nav的div的后代。像我正在使用的CSS定位器不应该为ChromeDriver工作吗?有人知道像findElements这样的方法为什么抛出invalidelementstateException吗?提前谢谢
附录:进一步的调查表明,只有在我通过不同的方法从一个页面导航到另一个页面后,该方法才会失败。感觉好像有些东西过时了,或者指的是不再存在的元素或者类似的东西。然而,我不明白那是什么;测试用例和页面对象可以使用相同的驱动程序对象,并且每次调用isElementEnabled时都会使用相同的驱动程序对象。未缓存或引用以前页面中的Web元素。我是否需要对我的驱动程序执行某些操作来提醒它页面已更改
附录2:绘图变厚。现在我不太确定之前的补遗。导航到一个新页面后,事情仍然会失败,但我不确定定位器是否是问题所在。我尝试在代码中添加如下调用:
debug("Attempt 3...");
things = getDriver().findElements(By.cssSelector("div a"));
debug("Attempt 3 found " + things.size() + " things!");
这些调用会成功,直到我离开开始的页面。它们在页面上定位35个元素,与简单定位器匹配。但是,一旦我导航到新页面,就会出现一个新的异常:
org.openqa.selenium.WebDriverException:返回的findElements无效
值:“[{\'ELEMENT\”:\”:wdc:1347370086846\”,{\'ELEMENT\”:
\“:wdc:1347370086847\”},{“ELEMENT\”:\“:wdc:1347370086848\”},
{\'ELEMENT\':\':wdc:1347370086849\',{\'ELEMENT\':
\“:wdc:1347370086850\”},{“ELEMENT\”:\“:wdc:1347370086851\”},
{\'ELEMENT\':\':wdc:1347370086852\',{\'ELEMENT\':
\“:wdc:1347370086853\”},{“ELEMENT\”:\“:wdc:1347370086854\”},
{\'ELEMENT\':\':wdc:1347370086855\',{\'ELEMENT\':
\“:wdc:1347370086856\”},{“ELEMENT\”:\“:wdc:1347370086857\”},
{\'ELEMENT\':\':wdc:1347370086858\',{\'ELEMENT\':
\“:wdc:1347370086859\”},{“ELEMENT\”:\“:wdc:1347370086860\”},
{\'ELEMENT\':\':wdc:1347370086861\',{\'ELEMENT\':
\“:wdc:1347370086862\”},{“ELEMENT\”:\“:wdc:1347370086863\”},
{\'ELEMENT\':\':wdc:1347370086864\',{\'ELEMENT\':
\“:wdc:1347370086865\”},{“ELEMENT\”:\“:wdc:1347370086866\”},
{\'ELEMENT\':\':wdc:1347370086867\',{\'ELEMENT\':
\“:wdc:1347370086868\”},{“ELEMENT\”:\”:wdc:1347370086869\”}]
(警告:服务器未提供任何stacktrace信息)
命令持续时间或超时:9毫秒生成信息:版本:
“2.23.1”,版本:“未知”,时间:“2012-06-08 12:33:29”系统
信息:os.name:'Windows 7',os.arch:'amd64',os.version:'6.1',
java.version:'1.7.0_05'驱动程序信息:Driver.version:RemoteWebDriver
会话ID:174ADF3205213984172556AF718F6A1
这就是Selenium表示WebElements的方式吗?我想这些只是对对象本身的引用。只有26个,而不是之前返回的35个(因为我们在不同的页面上,这可能是正确的数字)。不确定为什么有些东西是无效的,或者尽管如此。如果我在上面的“管理”按钮的定位器上调用isElementEnabled,我会像以前一样得到InvalideLementsAteeException。1)第一点。坦率地说,我不喜欢你的方法iselementabled
是有组织的。
要了解selenium是否能够使用本地化元素进行操作,请尝试以下操作:
public boolean isElementPresent(By locatorKey) {
try {
driver.findElement(locatorKey);
return true;
} catch (org.openqa.selenium.NoSuchElementException e) {
return false;
}
}
driver.findElement(By.cssSelector(....)).isEnabled();
driver.findElement(By.cssSelector(....)).isDisplayed()
但在使用此方法之前,我建议您使用fluent wait。Fluent wait返回您通过定位器找到的web元素(注意:如果Fluent wait失败,那么您最好注意您的xpath或neded元素的cssselector):
publicwebelement fluentWait(最终由定位器确定){
等待等待=新建FluentWait(驱动程序)
.带超时(30,时间单位。秒)
.轮询间隔(5,时间单位。秒)
.忽略(NoSuchElementException.class);
WebElement foo=wait.until(
新函数(){
公共WebElement应用(WebDriver){
返回驱动程序findElement(定位器);
}
}
);
返回foo;};
等等,我建议你读一下
关于你找到cssSelector的方式坦白说我也不喜欢。
而不是“div#top nav a[href~=CorpAdmin/DisplayInformation]”
试试这个
div[id='top']nav a[href~='CorpAdmin/DisplayInformation']
并始终使用css或xPAth检查本地化元素(例如,在firepath中,firefox插件到firebug)。见下图:
希望这对你有所帮助。1)第一点。坦率地说,我不喜欢你的方法iselementabled
是有组织的。
要了解selenium是否能够使用本地化元素进行操作,请尝试以下操作:
public boolean isElementPresent(By locatorKey) {
try {
driver.findElement(locatorKey);
return true;
} catch (org.openqa.selenium.NoSuchElementException e) {
return false;
}
}
driver.findElement(By.cssSelector(....)).isEnabled();
driver.findElement(By.cssSelector(....)).isDisplayed()
但在使用此方法之前,我建议您使用fluent wait。Fluent wait返回您通过定位器找到的web元素(注意:如果Fluent wait失败,那么您最好注意您的xpath或neded元素的cssselector):
publicwebelement fluentWait(最终由定位器确定){
等待等待=新建FluentWait(驱动程序)
.带超时(30,时间单位。秒)
.轮询间隔(5,时间单位。秒)
.忽略(NoSuchElementException.class);
WebElement foo=wait.until(
新函数(){
公共WebElement应用(WebDriver){
返回驱动程序findElement(定位器);
}
}
);
返回foo;};
等等,我建议你
public WebElement fluentWait(final By locator){
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
WebElement foo = wait.until(
new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
}
);
return foo; } ;
public void jsClickOnElement(String cssSelector){
JavascriptExecutor js = (JavascriptExecutor) driver;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("var x = $(\'"+cssSelector+"\');");
stringBuilder.append("x.click();");
js.executeScript(stringBuilder.toString());
}