Enhanced Page Object Factory

You must be aware of the Page Object Factory provided as part of selenium webdriver apis. The advantage of using Page Object Factory is that make the test code or page code more readable. You can define page elements as Webdriver WebElement class objects and then use them in your code. This way you will be getting rid of the repeated code of driver.findElementBy(By.id(“locator”)).

One of the problem that most of the people have with Page Object Factory is that the locators for the web-elements have to be mentioned in the FindBy annotation itself. TAF mixes the Page Object Factory with the industry common practise. It provides an extended Page Object Factory implementation of selenium which allow users to provide a web-elements locators in a properties file. User can store represent different web-elements as keys and mention their selectors as value in properties file. TAF automatically load the file and then read/use the respective selector for identifying a element on the page.

Users can initialize the said class using the extended CustomPageFactory class of TAF by providing the file containing the said key and its respective selector as a method argument. TAF fetches this locator at runtime from the said file based on the key provided to Page factory annotations. Following is an example:

Conventional Page Object Factory implementation:

public class GoogleLocator{
	
	@FindBy(how=How.CSS,using="#gbqfq")
	public WebElement searchField;
	
	@FindBy(how = How.CSS,using=".gbqfb")
	public WebElement submitButton;
	
	@FindBy(how = How.CSS,using="h3.r > a")
	public List<WebElement> searchResult;
}

Initialization in conventional way:

GoogleLocator locator = PageFactory.initElements(driver,
		GoogleLocator.class); 

Using the enhanced Page Object Factory:

public class GoogleLocator{
	
	@FindBy(how=How.CSS,using="search_box")
	public WebElement searchField;
	
	@FindBy(how = How.CSS,using="submit_button")
	public WebElement submitButton;
	
	@FindBy(how = How.CSS,using="search_result")
	public List<WebElement> searchResult;
}

The properties file:


search_box=#gbqfq

submit_button=.gbqfb

search_result=h3.r > a

Initialization while using the enhanced Page Factory:


GoogleLocator locator = CustomPageFactory.initElements(driver, 
		GoogleLocator.class,"googlelocator.properties"); 

In the above example you can see that an extra argument is passed to the initElements of the CustomPageFactory class. This argument is the path of the properties file that contains the locator information. There extra overloading methods that are available in CustompageFactory class that allow users to pass a File object too.

Providing default locator file

Users have the provision to provide a default file for each of his locator class if required. The enhanced Page factory of TAF automatically will load the file during initialization. To do so users just have to define a method named getLocaterFile which returns a File class object in the respective class where the page factory based elements are defined. Look at the example below:

public class GoogleLocator{
	
	@FindBy(how=How.CSS,using="search_box")
	public WebElement searchField;
	
	@FindBy(how = How.CSS,using="submit_button")
	public WebElement submitButton;
	
	@FindBy(how = How.CSS,using="search_result")
	public List<WebElement> searchResult;
	
	@Override
	public File getLocatorFile(){
		File file = new File("googlelocator.properties");
		return file;		
	}
}

The default locator file will only be considered if the user haven’t explicitly provided a different file object or file path when using CustomPageFactory initElements method. In case no file is provided while initializing the class or as default the values provided to using attribute of @FindBy annotation will considered as selector value like the original webdriver page factory.

Providing a locator file while navigating or verifying a Page

The above mentioned initialization options is also available to users when they are navigating or validating a page class using the to or at methods. The file can be provided as an argument by passing either the File object or the file-path while using the respective methods: Look at the following example:

@Test
public void googlePageLocatorFileBasedTest(){
	File file = new File("googlelocator.properties");
		
	GoogleHomePage homePage = to(GoogleHomePage.class,file);
		
	homePage.searchForString("Testing");
	
	GoogleResultsPage resultsPage = at(GoogleResultsPage.class,file);
}

Storing locators onto a file rather code provides with different advantages:

  • In case of locator change the locator can just be modified in the file and the user don’t have to change the code in anyway.
  • The said utility can be used to run same functionality on different version of application where the locators may change between different versions.