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