我编写了一个简单的方法来检查是否启用了 WebElement,并将此方法放入我的测试用例 Super Object 中:
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;
}
我一直在毫无问题地使用它,但突然间我遇到了一个可重复的实例,该方法抛出了 InvalidElementStateException:
org.openqa.selenium.InvalidElementStateException:findElements 执行失败;SYNTAX_ERR:DOM 异常 12(警告:服务器未提供任何堆栈跟踪信息)命令持续时间或超时:13 毫秒构建信息:版本:'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:ed1a9cbb238fa4dfb616ad81e7f60141
看来失败取决于我正在搜索的定位器。这个定位器有什么本质上的问题吗?
final By AdministrationButton = By
.cssSelector("div#top-nav a[href~=CorpAdmin/DisplayInformation]");
为了验证,上面的定位器正在尝试使用包含“CorpAdmin/DisplayInformation”的 href 属性来定位锚元素,该属性是 id=top-nav 的 div 的后代。不应该像我正在使用的那样为 ChromeDriver 工作的 CSS 定位器吗?有谁知道为什么像 findElements 这样的方法会抛出 InvalidElementStateExceptions?提前致谢!
附录:进一步的调查表明,只有在我通过不同的方法从一个页面导航到另一个页面后,该方法才会失败。感觉有些东西变得陈旧或引用不再存在的元素或类似的东西。但是,我无法理解那是什么;相同的驱动程序对象可用于测试用例和页面对象,并且每次调用 isElementEnabled 时都会使用该驱动程序对象。没有缓存或引用来自先前页面的 WebElement。我需要对我的驱动程序做些什么来提醒它页面已更改吗?
附录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\" }, {\"元素\": \":wdc:1347370086857\"}, {\"元素\": \":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\"}]" (警告:服务器没有提供任何堆栈跟踪信息)命令持续时间或超时: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:174adf3205213984172556afa718f6a1
这就是 Selenium 代表 WebElements 的方式吗?我想这些只是对对象本身的引用。其中只有 26 个,而不是之前返回的 35 个(因为我们在不同的页面上,这可能是正确的数字)。不确定为什么某些东西是无效的或者是什么。如果我改为在上面的 AdministrationButton 的定位器上调用 isElementEnabled,我会像以前一样得到 InvalidElementSateException。