当前位置: 首页 > 知识库问答 >
问题:

WebDriver/PageObject/FindBy:如何使用动态值指定xpath?

况野
2023-03-14

我试图在Java中使用页面对象模式,并在@FindBy/XPath中遇到一些问题。

之前,我在Groovy中使用了以下构造:

driver.findElement(By.xpath("//td[contains(text(),'$SystemName')]")).click()

Here, SystemName is a parameter that can be different. 

现在,我想做同样的事情,但根据Java中的页面对象范式:

public class ManagedSystems {

    private WebDriver driver;

    @FindBy(id="menu_NewSystem")
    private WebElement menuNewSystem;

    @FindBy (xpath = "//td[contains(text(),'$SystemName')]")  // ??? How to use SystemName from deleteSystem method (below)?
    private WebElement plantSystemName;

    ....

    public SystemHomePage deleteSystem (String systemName) {

        plantSystemName.click();

    }

}

在我的测试中,我调用deleteSystem:

SystemHomePage.deleteSystem("Firestone");

问题:如何链接为PlantSystemName和为deleteSystem指定的SystemName的@FindBy符号?

谢谢,浣熊

共有3个答案

鲁阳焱
2023-03-14

多亏了Ardesco和Robbie,我想出了以下解决方案:

private String RequiredSystemNameXpath = "//td[contains(text(),'xxxxx')]";

private WebElement prepareWebElementWithDynamicXpath (String xpathValue, String substitutionValue ) {

        return driver.findElement(By.xpath(xpathValue.replace("xxxxx", substitutionValue)));
}

public void deleteSystem (String systemName) {


    WebElement RequiredSystemName = prepareWebElementWithDynamicXpath(RequiredSystemNameXpath, systemName);

    RequiredSystemName.click();

}
姚浩歌
2023-03-14

不能这样做,注释是存储在类文件中的常量值。你不能在运行时计算它们。

请参阅可以在运行时确定注释变量吗?

章绪
2023-03-14

为此,我使用了另一种变通方法,它允许我们使用动态xpath,甚至可以与页面工厂一起使用。

解决方案:添加任何静态父元素的xpath,并使用动态路径引用子元素。在您的例子中,//td[contains(text(),“$SystemName”),td的父元素可能是“tr”或“table”。如果table是静态的,请使用以下代码:

@FindBy(xpath = "<..table xpath>")
public WebElement parentElement; 

public WebElement getDynamicEmement(String SystemName){
  parentElement.findElement(By.xpath("//tr/td[contains(text(),'"+SystemName+"')]"))
}

现在在脚本中,首先访问表(以便将其引用加载到内存中),然后调用getDynamicElement方法。

waitForElement(parentElement)
getDynamicElement("System-A")
 类似资料:
  • 我刚刚开始使用WebDriver,我正在尝试学习最佳实践,特别是使用PageObject和PageFactory。 我的理解是,PageObject应该公开网页上的各种操作,并将WebDriver代码与测试类隔离开来。根据所使用的数据,相同的操作通常会导致导航到不同的页面。 例如,在这个假设的登录场景中,提供管理员凭据将带您进入AdminWelcome页面,提供客户凭据将带您进入CustomerW

  • 我正在使用webDrive来测试我们包含表的应用程序,用户可以在其中更改表中列的顺序,还可以删除/添加列(这是开发人员添加的新列旁边)。 找到我需要的列的正确方法是什么?一种方法是遍历表头以找到我要查找的列,这样我就有了列索引并且可以访问正确的单元格。 还有别的办法吗?为表中的每个元素放置唯一的id/类名怎么样? 谢啦

  • 问题内容: 我试图应用与作用域变量相同的类名。 例如: 以便将的值添加到类中。不过,这似乎没有任何作用。有关如何执行此操作的任何建议? 谢谢! 编辑: 这实际上是使用ng-options在select中完成的。例如: 现在,我想应用一个具有以下值的类名: 我发现以下指令似乎有效,但无法对该值进行插值: 问题答案: 我使用的是角度1.5.5,但这些解决方案都不适合我。 尽管仅在这里的最后一个示例中显

  • 我喜欢在我的自动化框架中使用带有FindBy注释的PageFactory来自动定位我的页面对象类中的元素。 我有一个WebElement,我需要能够指定几个不同的定位器。我以为FindBys是我的解决方案,但显然这不是它的工作方式。它相当于Driver.FindElement(option1).FindElement.(option2)。那不是我需要的。我需要的东西,将找到一个元素的一个或其他定位

  • 问题内容: 只要我使用PageObject模式,我就想知道应该在哪里等待动态页面上的元素。假设我们有测试方法和pageObject类。我应该做类似的事情吗(在测试方法中): 点击按钮 等待元素显示 验证元素(例如包含方法isElementDisplayed()) 也许还有其他好的做法来等待该要素?也许我们应该等待PageObject.class中的isElementDisplayed方法中的元素?

  • 我试图使用@FindBy初始化所有页面元素。我知道@FindBy可以用来初始化单个webelement,但它可以用来初始化webelement列表吗?我正在尝试合并司机。findElements(By.xpath()(它将返回webelements的列表)以@FindBy的形式出现。我该怎么做?