当前环境:
我的测试正在尝试验证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()将刷新缓存。最后,在访问元素之前的显式等待应该确保&lt; TD&gt;标签存在。
可能导致getText()方法返回以下异常:
org.openqa.selenium.StaleElementReferenceException:在缓存中找不到元素 - 自查询以来页面可能已更改
值得注意的是,失败是间歇性的。某些执行失败而其他执行通过相同的代码传递。导致失败的表格单元也不一致。
答案 0 :(得分:0)
使用Html-Agility-Pack可以解决这个问题。
只有当您想要从该页面读取数据时,这才有效。
这就像这样
//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。与driver.FindElement: document.SelectSingleNode类似
2。与driver.FindElements类似: document.SelectNodes
3。与driver.Text类似: document.InnerText。
有关HtmlNode的更多搜索。
答案 1 :(得分:0)
事实证明,我已经提到了竞争条件。由于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);