WebDriver/PageObject/FindBy: how to specify xpath with dynamic value?

╄→гoц情女王★ 提交于 2019-12-12 11:09:23

问题


I'm trying to use Page Object pattern in Java and having some trouble with @FindBy/XPath.

Earlier, I used the following construction in Groovy:

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

Here, SystemName is a parameter that can be different. 

Now, I want to do the same thing but in accordance with Page Object paradigm in 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();

    }

}

In my test, I call deleteSystem:

SystemHomePage.deleteSystem("Firestone");

Question: How to link @FindBy notation for PlantSystemName and SystemName specified for deleteSystem?

Thanks, Racoon


回答1:


You can't do that, Annotations are constant values stored in the class file. You can't compute them at runtime.

See Can the annotation variables be determined at runtime?




回答2:


I used another workaround for this which will allow us to use dynamic xpath even with page factory.

Solution: Add the xpath of any parent element that is static and reference child element with dynamic path. In your case, //td[contains(text(),'$SystemName'), parent element of td might be 'tr' or 'table'. If table is static, use below code:

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

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

Now in your script, access table first(so that its reference is loaded in memory) and then call the getDynamicElement method.

waitForElement(parentElement)
getDynamicElement("System-A")



回答3:


Thanks to Ardesco and Robbie, I came up with the following solution:

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

}



回答4:


You are using a page object factory rather than just following the page object pattern.

You can create page objects as simple classes with identifiers stored as private variables, and methods exposing the elements using those variables, and you are still following the page object pattern.

check out this; http://relevantcodes.com/pageobjects-and-pagefactory-design-patterns-in-selenium/

If your identifiers are just variables, then you can use any manipulation you want



来源:https://stackoverflow.com/questions/21263367/webdriver-pageobject-findby-how-to-specify-xpath-with-dynamic-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!