有一个基于Angular
的站点,它不使用唯一的名称/ ID作为元素。元素的XPATH
在页面上不是永久性的,因此在每次网站修改后都必须更改基于WebDriver
的测试。如何在不使用XPATH
的情况下管理此页面上的元素?
首先,按照Page Object pattern至少在一个地方定义定位器 - 内部页面对象。这有助于解决不断变化的用户界面问题。
其他需要考虑的事项:
- 这是所有人中最慢和最脆弱的定位策略
- 标记非常容易更改,因此xpath定位器需要大量维护
- xpath表达式是不可读的,很难调试
div
或span
这样的元素只是容器 - 在定位器中使用它们很少被证明是合理的col-md-4
或col-xs-6
这样的Bootstrap面向布局的类不要依赖JUST一个选择器方法!
您可以使用任何其他findElement()选项,例如cssSelector,name,tagName等。更重要的是,您不必单独使用它们。换句话说,尽可能通过一种方法然后切换到另一种方法。这是一个从XPath开始并使用css完成的Java示例:
private final String xGrid = "//div[contains(@class,'lists-grid')]/div[contains(@class,'ui-grid')]";
private final String xGridWrapper = "/div[contains(@class,'ui-grid-contents-wrapper')]";
@FindBy(xpath = xGridScopeSubscriptions + xGridWrapper)
private List<WebElement> gridRecordList;
public void clickGridSubscriptionActionEditByRow(int row) {
int totalColumns = gridRecordList.size();
int actionColumn = getColumnIdByHeader("Action");
WebElement actionCell = gridRecordList.get((totalColumns * row) + actionColumn);
WebElement editButton = actionCell.findElement(By.cssSelector("button.subscription-edit-btn"));
editButton.click();
}
请注意,这是一种不同的大杂烩,但我希望你能得到这个想法。
从字符串开始,在代码中定义关键标记。连接字符串以为起始点分配WebElement变量。然后在方法中,使用起点,根据不同的选择器从那里做findElements()。
您甚至可以一次性完成所有操作。
private WebElement deleteIcon driver.findElement(By.id("name-list")).findElement(By.cssSelector("div.grid-ui div.grid-cell")).findElement(By.xpath("./td[3]/i[contains(@class,'fa-trash')]"));
我知道你说ID不稳定,但我只想给你一个例子,将不同的查找元素的方法串联起来,以达到你的最终目标。