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

时间:2014-01-21 16:11:21

标签: java selenium xpath selenium-webdriver pageobjects

我正在尝试在Java中使用 Page Object 模式,并且在 @ FindBy / XPath 时遇到一些问题。

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

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

Here, SystemName is a parameter that can be different. 

现在,我想做同样的事情,但是按照Java中的Page Object范例:

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的@FindBy表示法为deleteSystem指定的SystemName

谢谢, 浣熊

4 个答案:

答案 0 :(得分:4)

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

请参阅Can the annotation variables be determined at runtime?

答案 1 :(得分:2)

感谢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();

}

答案 2 :(得分:1)

您正在使用页面对象工厂而不是仅仅遵循页面对象模式。

您可以将页面对象创建为具有存储为私有变量的标识符的简单类,以及使用这些变量公开元素的方法,并且您仍然遵循页面对象模式。

看看这个; http://relevantcodes.com/pageobjects-and-pagefactory-design-patterns-in-selenium/

如果您的标识符只是变量,那么您可以使用任何想要的操作

答案 3 :(得分:1)

我使用了另一种解决方法,即使是页面工厂也可以使用动态xpath。

解决方案:添加任何静态父元素的xpath,并使用动态路径引用子元素。 在你的情况下,// td [contains(text(),' $ SystemName'),td的父元素可能是' tr'或者'表'。如果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")