如何使用Selenium获取并验证Angular AG Grid表格的每一行数据
问题分析
原代码无法成功获取数据主要有以下几个原因:
- 变量配置错误:
packagedItemCount对应的列ID重复配置为warehouseName,无法定位到目标列 - 文本获取方式不适配AG Grid:
getText()仅能获取可见元素的文本,你使用的Angular AG Grid采用虚拟滚动+绝对定位渲染,部分单元格可能不在可视区域导致返回空值,应使用textContent属性获取完整文本 - 缺少等待逻辑:未等待表格数据加载完成就执行元素查找,可能出现元素不存在的报错
- 多余的可见性判断:
isDisplayed()判断会过滤掉不可见的单元格,导致数据采集不全
修正后可运行代码
import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.ui.WebDriverWait; import org.openqa.selenium.support.ui.ExpectedConditions; import java.time.Duration; import java.util.*; // 第一步:先等待表格容器渲染完成,避免提前查找元素报错 WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); WebElement tableContainer = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//div[@class='ag-center-cols-container']"))); // 第二步:获取所有行元素 List<WebElement> tableRows = tableContainer.findElements(By.xpath("./div[@role='row']")); // 定义需要采集的字段和对应列的col-id,可根据实际需求扩展 Map<String, String> colMapping = new HashMap<>(); colMapping.put("projectLookupCodes", "warehouseName"); colMapping.put("loadContainerSequence", "completedDateTime"); colMapping.put("lotCode", "lotCode"); colMapping.put("operationCodeName", "operationCodeName"); // 存储实际采集到的所有行数据 List<Map<String, String>> actualTableData = new ArrayList<>(); for (WebElement row : tableRows) { Map<String, String> rowData = new HashMap<>(); for (Map.Entry<String, String> entry : colMapping.entrySet()) { String fieldName = entry.getKey(); String colId = entry.getValue(); // 用textContent获取文本,不受元素是否可见影响,适配AG Grid虚拟滚动特性 WebElement cell = row.findElement(By.xpath("./div[@col-id='" + colId + "']")); String cellValue = cell.getAttribute("textContent").trim(); rowData.put(fieldName, cellValue); System.out.println(fieldName + ": " + cellValue); } actualTableData.add(rowData); System.out.println("============================="); }
数据校验方案
import org.testng.Assert; // 1. 构造预期数据集,可根据业务场景从数据库、接口返回值中获取 List<Map<String, String>> expectedTableData = new ArrayList<>(); // 第一行预期数据示例 Map<String, String> expectedRow1 = new HashMap<>(); expectedRow1.put("projectLookupCodes", "Warehouse_Modify"); expectedRow1.put("loadContainerSequence", "2021-08-03T12:29:05.123"); expectedRow1.put("operationCodeName", "Create Inventory"); expectedRow1.put("lotCode", "Material_66734-GLot"); expectedTableData.add(expectedRow1); // 剩余行预期数据构造逻辑省略... // 2. 逐行逐列断言对比 Assert.assertEquals("表格总行数不匹配", expectedTableData.size(), actualTableData.size()); for (int i = 0; i < expectedTableData.size(); i++) { Map<String, String> expectedRow = expectedTableData.get(i); Map<String, String> actualRow = actualTableData.get(i); for (String field : expectedRow.keySet()) { Assert.assertEquals("第" + (i+1) + "行" + field + "值不匹配", expectedRow.get(field), actualRow.get(field)); } }
如果是日期、数值类的非固定值字段,可单独增加格式校验、范围校验逻辑,无需完全字符串匹配。
内容的提问来源于stack exchange,提问作者Peter Penzov
相关产品推荐
相关产品推荐

