The Enhanced POM

Selenium Page Factory Pattern is like an extension to Page Object Model, but Page Factory is much enhanced model.

We use Page Factory pattern to initialize web elements which are defined in Page Objects.

We should initialize page objects using initElements() method from PageFactory Class as below, Once we call initElements() method, all elements will get initialized. PageFactory.initElements() static method takes the driver instance of the given class and the class type, and returns a Page Object with its fields fully initialized.

public HompePage(WebDriver driver) {           
this.driver = driver; 
PageFactory.initElements(driver, this);
}

Page Factory will initialize every WebElement variable with a reference to a corresponding element on the actual web page based on “locators” defined. This is done by using @FindBy annotations.

  • @FindBy is used to identify Web Elements in the page
@FindBy(id="username")
private WebElement userName;

When we have multiple elements (list of WebElements), we can initialize them using PageFactory as below :

@FindBy(tagName = "mylist") 
private List<WebElement> links;
  • @FindBy

It is used to locate WebElement with more than one criteria and need to match all of the given criteria. These criteria should be mentioned in a parent-child relationship. In other words, this uses AND conditional relationship to locate the WebElements using the criteria specified. It uses multiple @FindBy to define each criterion.

@FindBys({
 @FindBy(id = "searchId_1"),
 @FindBy(name = "search_field")
 })

WebElementSearchButton;
  • @FindAll

It is used to locate WebElement with more than one criteria and it needs to match at least one of the given criteria. This uses OR conditional relationships in order to locate WebElements. It uses multiple @FindBy to define all the criteria.

@FindAll({
@FindBy(id = "UsernameNameField_1"), // doesn’t match
 @FindBy(name = "User_Id") //matches
@FindBy(className = “UserName_r”) //matches
})
WebElementUserName;
  • @CacheLookUp

When the WebElement is more often used in test cases, Selenium looks up for the WebElement each time when the test script is run. In those cases, wherein certain WebElements are globally used for all TC (For Example, Login scenario happens for each TC), this annotation can be used to maintain those WebElements in cache memory once it is read for the first time.

This, in turn, helps the code to execute faster because each time it doesn’t have to search for the WebElement in the page, rather it can get its reference from the memory.

This can be as a prefix with any of @FindBy, @FindBys and @FindAll.

@CacheLookUp
@FindBys({
@FindBy(id = "UsernameNameField_1"), 
 @FindBy(name = "User_Id") 
@FindBy(className = “UserName_r”) 
})
WebElementUserName;

About the author

Deepak Sood

Deepak Sood is Lead Consultant in an IT firm holding expertise in Devops and QA Architecture with 8 years of experience.

His expertise is in building highly scalable frameworks. His skills include Java, Configuration Management, Containers, and Kubernetes.

Reach out to him using contact form.

View all posts