当前环境:
- Selenium服务器2.37.0版
- 在Firefox上运行的RemoteWebDriver
- 没有Ajax/异步加载的内容
我的测试试图验证HTML表中每个单元格的内容。在访问任何表元素之前,显式等待验证<tbody>元素存在
ExpectedCondition<WebElement> recruitTableIsPresent = ExpectedConditions.presenceOfElementLocated(By.id("newRecruitFieldAgentWidget:newRecruitDataTable_data"));
new WebDriverWait(driver, 5).until(recruitTableIsPresent);
一旦表被验证存在,数据就会按行和列提取出来
private Stats[] parseStats() {
String xpath = "//tbody[@id='regionalFieldAgentWidget:regionalDataTable_data']/tr[%d]/td[%d]";
Stats[] stats = new Stats[3];
for (int i = 0; i < stats.length; i++) {
String inProgresOrders = cellContent(xpath, i, 1);
String maxCapacity = cellContent(xpath, i, 2);
String allocationRatio = cellContent(xpath, i, 3);
Stats[i] = new Stats(inProgressORders, maxCapacity, allocationRatio);
}
return stats;
}
private String cellContent(String xpathTemplate, int row, int cell) {
String xpath = String.format(xpathTemplate, row + 1, cell + 1);
new WebDriverWait(driver, 10).until(ExpectedConditions.presenceOfElementLocated(By.xpath(xpath)));
WebElement elementByXPath = driver.findElementByXPath(xpath);
return elementByXPath.getText();
}
我没有看到任何竞争条件,因为表内容是用页面填充的,而不是在异步调用中。此外,我看到了其他答案,这些答案建议通过驱动程序实例调用findElement()将刷新缓存。最后,访问元素之前的显式等待应该确保<TD>标记存在。
是什么原因导致getText()方法返回以下异常:
org.openqa.selenium.StaleElementReferenceException:在缓存中找不到元素-也许页面在查找后发生了更改
值得注意的是,故障是间歇性的。某些执行失败,而其他传递通过相同的代码传递。导致失败的表单元格也不一致。
有一个使用Html敏捷包的解决方案。
只有当您想从该页面读取数据时,这才会起作用。
这就像这个
//Convert the pageContent into documentNode.
void _getHtmlNode(IWebDriver driver){
var htmlDocument = new HtmlDocument();
htmlDocument.LoadHtml(driver.PageSource);
return htmlDocument.DocumentNode;
}
private Stats[] parseStats(){
String xpath = "//tbody[@id='regionalFieldAgentWidget:regionalDataTable_data']/tr[%d]/td[%d]";
Stats[] stats = new Stats[3];
for (int i = 0; i < stats.Length; i++) {
String inProgresOrders = cellContent(xpath, i, 1);
String maxCapacity = cellContent(xpath, i, 2);
String allocationRatio = cellContent(xpath, i, 3);
Stats[i] = new Stats(inProgressORders, maxCapacity, allocationRatio);
}
return stats;
}
private String cellContent(String xpathTemplate, int row, int cell) {
String xpath = String.format(xpathTemplate, row + 1, cell + 1);
new WebDriverWait(driver, 10).until(ExpectedConditions.presenceOfElementLocated(By.xpath(xpath)));
var documentNode = _getHtmlNode(driver);
var elementByXPath = documentNode.SelectSingleNode(xpath);
return elementByXPath.InnerText;
}
现在读取任何数据。
关于使用htmlNode的一些提示。
1。类似于驾驶员。FindElement:文档。选择单个节点
2。类似于驾驶员。FindElements:文档。选择节点
3。类似于驾驶员。文本:文档。InnerText。
有关HtmlNode的更多搜索。
正如我已经提到的那样,事实证明存在竞争条件。由于jQuery可以通过PrimeFaces获得,所以在其他几篇文章中提到了一个非常方便的解决方案。我实现了以下方法,在解析页面元素之前等待任何异步请求返回
public static void waitForPageLoad(JavascriptExecutor jsContext) {
while (getActiveConnections(jsContext) > 0) {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
}
}
private static long getActiveConnections(JavascriptExecutor jsContext) {
return (Long) jsContext.executeScript("return (window.jQuery || { active : 0 }).active");
}
每个内置的驱动程序实现都实现了JavascriptExecutor接口,因此调用代码非常简单:
WebDriver driver = new FirefoxDriver();
waitForPageLoad((JavascriptExecutor) driver);