I'm trying to write a page object in Selenium Webdriver using the page factory @FindBy
annotations. The page object is for a sidebar, and the parent WebElement containing all elements the page object needs to interact with is initialized in this way:
@FindBy (xpath = "//div[contains(@class,'yui3-accordion-panel-content') and child::div[.='Sidebar']]")
WebElement sidebar;
I then want the search input relative to this sidebar
element. Is there a way to do this referencing sidebar
element? I could copy and paste the entire path to the beginning:
@FindBy (xpath = "//div[contains(@class,'yui3-accordion-panel-content') and child::div[.='Sidebar']]//input[@id='search']")
But I'd much rather make it relative to the first element. Is anything like this possible?
@FindBy (parent = "sidebar", xpath = ".//input[@id='search']")
The Selenium documentation on the @FindBy annotation is a bit lacking...
Answer is NO. there will be an element that can be located using the xpath expression “//*[@id='submit']” or “//*[@name='submit']”. WebElement SomeId; So to use other locators like xpath, css etc, we required FindBy annotation.
In Page Factory, testers use @FindBy annotation. The initElements method is used to initialize web elements. Similarly, one can use @FindBy with different location strategies to find web elements and perform actions on them.
This is done to ensure that the web elements are initialized before any relevant actions are performed. One of the Selenium best practices with Page Factory is to create all the web element variables at the beginning of the class and initialize those variables when the page is loaded.
Page Factory in Selenium is an inbuilt Page Object Model framework concept for Selenium WebDriver but it is very optimized. It is used for initialization of Page objects or to instantiate the Page object itself. It is also used to initialize Page class elements without using “FindElement/s.”
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With