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

Racoon picture Racoon · Jan 21, 2014 · Viewed 20.8k times · Source

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

Answer

Aftaab Siddiki picture Aftaab Siddiki · Jun 5, 2018

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")