Question

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

Was it helpful?

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

}

OTHER TIPS

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

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?

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top