top of page
hand-businesswoman-touching-hand-artificial-intelligence-meaning-technology-connection-go-

PAGE FACTORY IN SELENIUM

Software Testing enables you to decrease manual effort, but you might come across many functionalities that are repetitive in the test execution. As a result, you might have to use the same locator multiple times. Now, if you duplicate the same code multiple times, it can lead to unmanageable projects. Over to it, if at all a locator changes, you will have to go through the entire code again and make the changes at all the places where that locator is used. Consequently, to overcome this, the Page Object Model using Page Factory is implemented in Selenium automation frameworks. It helps in maintaining the test scripts by separating the test objects from the test scripts. Subsequently, in this blog, you will learn how PageFactory can be used in your Selenium test automation to create an optimized framework. We will cover the below points-


  • What is the Page Object Pattern?

  • How to implement a Page Object Pattern?

  • What is PageFactory in Selenium?

  • What are the PageFactory Annotations?

  • How to implement the Page Object Model using PageFactory?

  • How to create a Page Factory Pattern in the Selenium Project?


  • What is the Page Object Pattern?

Page Object Model /Pattern is a design pattern used in Selenium, where we create an object repository to store web elements. A java class is created that corresponds to each web page, consisting of the WebElements on the page and the corresponding methods that act on elements. In simple words, all web page elements are in a java class by identifying them through their locators. Additionally, the creation of multiple java classes happens for the different web pages of a website. These java classes act as a repository to store the various elements that we can interact with within our test cases. Consequently, the project structure of a simple Page Object Model/Pattern generally looks like below:


You can see that different page classes are kept separate from the test classes in different packages in the above image.

  • How to implement the Page Object Pattern?

A simple implementation of Page Object Patten can happen, as shown below:


You can see how the page elements separate from the test cases in the page object pattern. Now we will see how we can implement the same. There are two ways to implement the Page Object Pattern in your test project:

  1. First, Using the Regular Java Classes- In this method, we create java classes for the different pages that consist of the various web elements on that page. Moreover, we use these web elements in Test Cases that reside in different classes. Additionally, you can check out the Page Object Model article to learn more about this approach.

  2. Second, Using the Page Factory Class- It is an extension to the Page Object design pattern, which we will discuss in this article.

  • What is Page Factory in Selenium?

Page Factory is a class provided by Selenium WebDriver to implement the Page Object Model. The Page Object Repository is separated from the Test Methods using the Page Factory concept. Using it, you can initialize the Page Objects or directly instantiate them. In simple words, the Page Object Model lets you create separate java classes for different pages of a website. These different classes contain the locators for different web elements (like button, text field, dropdown, etc.) present on the page and the methods to perform actions on these elements. By doing so, you can simplify your code and segregate the test methods and the object repository. Subsequently, there are two simple steps through which we need to define and use Page Factory in Selenium projects:

  1. Using the @FindBy annotation-

Unlike the regular approach of initializing web page elements using FindElement or FindElements, the Page Factory uses the @FindBy annotation. The annotations used in Page Factory are descriptive. Moreover, they help improve code readability, which we will discuss in the next section. It provides the following syntax to locate the web elements:


@FindBy(xpath="//body/div[5]/a")WebElement squaresOfASortedArray;

squaresOfASortedArray.click();

2. Initializing the elements using initElements()-

This is a static method used to initialize the web elements that we locate using the @FindBy or other annotation(s), thereby instantiating the page class.


PageFactory.initElements(WebDriver driver,  
                   java.lang.Class.pageObjectClass);

Another interesting concept offered by Page Factory is the lazy load concept using the AjaxElementLocatorFactory. It can be used when your application uses Ajax elements. Additionally, you can use it while trying to find an element to perform an operation and pass a timeout value, until which the driver would wait before throwing an exception. In other words, it is a variant of implicit wait using the class AjaxElementLocatorFactory. Subsequently, the syntax is as follows-


PageFactory.initElements(new AjaxElementLocatorFactory(driver,   
                                                20), this);

  • What are the Page Factory annotations?

As discussed above, Page Factory annotations are very descriptive and make the code very readable. Moreover, the annotations help to set up a location strategy for the web elements. Important annotations used in Page Factory are discussed below:


@FindBy

The @FindBy annotation is the essence of the Page Factory approach. It is used to locate web elements using different locators strategies. Additionally, it helps in quickly locating the web elements using one search criteria. Before declaring the WebElement, we pass its attribute and the corresponding value. Subsequently, there are two ways to use this annotation:

  • , we pass its attribute and the corresponding value.


By directly using locator(id, XPath, CSS, etc.) You can explore more about the methods to find elements using Selenium.


@FindBy (xpath="//body/div[2]/div/div[2]/a")WebElement tryHere;

tryHere.click();

@FindBys

To locate a web element with more than one search criteria, you can use @FindBys annotation. This annotation locates the web element by using the AND condition on the search criteria. In simple words, @FindBys uses multiple @FindBy for each search criteria.


@FindBys({
 @FindBy(class="custom-control-check-box"),
 @FindBy(id="game-chk-box")
})

WebElement chkBox;

@FindAll

The @FindAll annotation locates the web element using more than one criteria, given that at least one criteria match. Contrary to @FindBys, it uses an OR conditional relationship between the multiple @FindBy.


@FindAll({
 @FindBy(id="btn", //doesn't match
 @FindBy(name="sbmtBtn"), //Matches
 @FindBy(class="btn-primary") //doesn't match
})

@CacheLookUp

The @CacheLookUp annotation is very useful when you are referring to the same web element multiple times. Consider an application where each test case requires Login operation. In such a scenario, using @CacheLookUp, we can store the web elements in cache memory right after reading for the first time. It fastens our execution and the code, need not look up for the element on the web page and directly references it from memory.

The @CacheLookUp can be prefixed with any of the annotations discussed above, i.e., @FindBy, @FindBys & @FindAll.



@CacheLookUp@FindBys({
 @FindBy(class="custom-control-check-box"),
 @FindBy(id="game-chk-box") 
})

WebElement chkBox;

  • How to Use Page Factory in Selenium

This guide will use Java to implement Page Factory in Selenium. The following steps are necessary to follow this guide.

1. Steps

To automate the test case above, we’ll first create a new Maven project. Next, let’s give both the groupID and attributeID the value PageFactoryID.

Now, add the dependencies for Selenium and Junit. The {junit.version} and {selenium.version} should be replaced with the version on their website.


<dependencies>
  <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
	<dependency>
	    <groupId>org.seleniumhq.selenium</groupId>
	    <artifactId>selenium-java</artifactId>
	    <version>4.8.0</version>
	</dependency>
	<!-- https://mvnrepository.com/artifact/org.testng/testng -->
	<dependency>
	    <groupId>org.testng</groupId>
	    <artifactId>testng</artifactId>
	    <version>7.7.1</version>
	    <scope>test</scope>
	</dependency>

2. Classes

Next, let’s create a class named CollectionsPage. This is where the locators and methods for the homepage will be stored. This class imports the webdriver, webelement, annotation, and pagefactory.



public class CollectionsPage {
	public static WebDriver driver=driverFactory.getdriver();
	 By getStarted=By.xpath("//a[@href='/home']");
	 @FindBy (xpath="//a[contains(text(),'Data Structures')]")
	                                        WebElement dropDown;
	@FindBy (linkText ="Stack")WebElement dropDown_stack;
	 
public CollectionsPage()
	{
		PageFactory.initElements(driver, this);
		//this.driver=driver;
	}	
public void clickOndropDownDS()
	{
		dropDown.click();
	}
	public void clickOneFromDropDown() {
		dropDown_stack.click();
	}

3. Testing

We have now created the class for the page; the next class to create is for the test instance. Create a class named Collections_step. In this class, the webdriver objects are used to open the chrome browser, getStarted is defined.


public class Collections_step {

	 WebDriver driver;

	CollectionsPage collection=new CollectionsPage();
	 
	 public void clickOngetStarted() throws InterruptedException
	{	
		driver.findElement(getStarted).click();
		 
	}
	public void  dropdown_arrow {
	
		collection.clickOndropDownDS();
	}
	  public void user_clicks_from_dropdown() {
	
		collection.clickOneFromDropDown();
	}

Conclusion

When carrying out test automation, consider implementing Page Factory in Selenium. And remember to use @CacheLookup within InitElements(). This will ensure the web elements load just once and do not have to reload whenever the method is called. Also, note that asides from single web elements, Page Factory also locates lists of elements. Hope this blog is useful. Happy Learning.

112 views0 comments

Recent Posts

See All

Snowflake is a cloud native database and can be hosted on any of the clouds namely AWS, GCP or Azure. While using snowflake we pay for only the storage we use and the compute which was actually used d

bottom of page