Wednesday 11 May 2016

How PageFactory DP is different from Page Object Model

Assume you are already aware of Page Object Design pattern.

Quick Recap:
 Each web page in the application there should be corresponding page class.
- Object Repository is independent of test cases.
- Flows in the UI should be separated from verification.

Advantages:
- Easy to Maintain
- Easy Readability of scripts
- Reduce or Eliminate duplicacy
- Re-usability of code

- Reliability


Page Factory :

- Extension to Page Object Model , but Page Factory is much enhanced model.


"Factory class can be used to make using Page Objects simpler and easier".

- We use Page Factory pattern to initialize web elements which are defined in Page Objects.
  Once we call initElements() method, all elements will get initialized.
- It is used to initialize elements of a Page class without having to use ‘FindElement’ or ‘FindElements’. Annotations can be used to supply descriptive names of target objects to improve code readability.

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
import org.openqa.selenium.support.PageFactory;

import com.abof.selenium_pagefactory.pom.utils.WebElementWait;

public class HeaderPage {
WebDriver driver;

@FindBy(how = How.LINK_TEXT, using = "Track my order")
private WebElement linkTrackMyOrder;

@FindBy(how = How.ID, using = "Header_GlobalLogin_signInQuickLink")
private WebElement linkSignIn;

@FindBy(how = How.ID, using = "Header_GlobalLogin_signOutQuickLinkUser")
private WebElement linkSignOut;

@FindBy(how = How.ID, using = "Header_GlobalLogin_loggedInDropdown_SignOut")
private WebElement btnSignOut;

public HeaderPage(WebDriver driver) throws Exception {
this.driver = driver;
PageFactory.initElements(driver, this);
}

public void navigateToSignInPage() {
linkSignIn.click();
}

public void signOut() {
linkSignOut.click();
btnSignOut.click();
}

public void navigateToTrackingOrderPage() {
linkTrackMyOrder.click();
}

public String getMeLoggedInPersonFirstName() {
WebElementWait.elementIsDisplayedFluentlyPredicate(linkSignOut, 5, 500);
return linkSignOut.getText();
}


}


PageFactory Instantiates all the elements of the web page at the start when we Initialized any page class objects. But think of the elements which will display on the web page after some action, say Ajax action. In PageFactory, every time when we call a method on the WebElement, the driver will go and find it on the current page once again.

In an AJAX-heavy application this is what we would like to happen, but in the case of regular application where elements are stable and when we know that the element is always going to be there and won’t change.  It would be handy if we could ‘cache’ the element once we’d looked it up and save some time of execution by commanding PageFactory to not search the WebElements on the page again.

Advantages of PageFactory
- less code using @FindBy
- Initialize all elements at a time
- using cache feature, we can save execution time
AjaxElementLocatorFactory feature