Selenium Webdriver: Page factory initialization using paths relative to other elements? Selenium Webdriver: Page factory initialization using paths relative to other elements? selenium selenium

Selenium Webdriver: Page factory initialization using paths relative to other elements?


The answer is to implement an ElementLocatorFactory that allows you to provide a search context (meaning, a driver or a WebElement).

public class SearchContextElementLocatorFactory        implements ElementLocatorFactory {    private final SearchContext context;    public SearchContextElementLocatorFactory(SearchContext context) {        this.context = context;    }    @Override    public ElementLocator createLocator(Field field) {        return new DefaultElementLocator(context, field);    }}

Then, when instantiating your page object, use this locator factory.

WebElement parent = driver.findElement(By.xpath("//div[contains(@class,'yui3-accordion-panel-content') and child::div[.='Sidebar']]"));SearchContextElementLocatorFactory elementLocatorFactory = new SearchContextElementLocatorFactory(parent);PageFactory.initElements(elementLocatorFactory, this);

Now your @FindBy annotations will be relative to parent. For example, to get the main sidebar WebElement:

@FindBy(xpath = ".")WebElement sideBar;


No, it is not possible this way. But you can use getter methods instead of annotation-based initialization:

public class SomePage {    @FindBy (xpath = "//div[contains(@class,'yui3-accordion-panel-content') and   child::div[.='Sidebar']]")    private WebElement sidebar;    private WebElement getSomeChildElement() {        return siderbar.findElement(By.id("somechild"));    }}