Page Factory



The PageFactory Class is an extension to the Page Object design pattern. It is used to initialize the elements of the Page Object or instantiate the Page Objects itself. Web page classes or Page Objects containing web elements need to be initialized using Page Factory before the web element variables can be used. This can be done simply through the use of initElements function on PageFactory:
It is used to initialize elements of a Page class without having to use ‘FindElement’ or ‘FindElements’.

They are different ways to initialize elemens using  pagefactory , depends on  flexibility

1) LoginPage lPage = new LoginPage(driver);
PageFactory.initElements(driver, lPage);

2) LoginPage lpage = PageFactory.intElements (driver, LoginPage.class)

3) page class constructor
public  LoginPage(WebDriver  driver) {         
         this.driver = driver;
         PageFactory.initElements(driver, this);
}

The InitElements method of PageFactory initializes the elements of the PageObject.
Page Factory  model  using @FindBy, FindBys,@Findall and @CacheLookup  annotations

@FindBy:
To indicate an alternative mechanism for locating the element or a list of elements. Used in conjunction with Page Factory this allows users to quickly and easily create PageObjects. It can be used on a types as well, but will not be processed by default.
You can either use this annotation by specifying both "how" and "using" or by specifying one of the location strategies (eg: "id") with an appropriate value to use.
@FindBy(how=How.ID, using =”email”)
In the above example, PageFactory.InitElements facilitates searching for elements marked with the @FindsBy attribute by using the ID property (notice: How = How.ID) to find the target element. Using= then defines the corresponding value of the How= parameter.
This entire definition of the WebElement variable can be replaced with its much more concise form:
Ex: 1) @FindBy(name=”email’)
In the above example, PageFactory.InitElements facilitates searching for elements marked with the @FindsBy attribute by using the Name property to find the target element
@FindBy handles id, name, className, css, tagName, linkText, partialLinkText, xpath as attributes
@FindBy(id="email")
private WebElement username;
@FindBy(name="pass")
private WebElement userpassword;
@FindBy(className="placeholder")
private WebElement label;
@FindBy(css=”#content”)
private WebElement text;

@FindBys: This annotation is used to find a list of elements on page.
Ex:
@FindBys({@FindBy(className="placeholder"),
(Id=”email”),
(name=”pass”)})
private List<WebElement> listElements;

@FindAll : This Attribute indicate that lookup should use a series of @FindBy tags It will then search for all elements that match any of the FindBy criteria. Note that elements are not guaranteed to be in document order. It can be used on a types as well,
Ex: @FindAll({@FindBy(how = How.ID, using = "email"),
@FindBy(className = "placeholder")})

@CacheLookup
The CacheLookupAttribute can be used to instruct the InitElements method to cache the element once its located. any attribute marked [CacheLookup] will not be searched over and over again, this is useful for elements is always going to be there and won’t change
@FindBy(how=How.NAME=”email”)
@CacheLookup
private WebElement username;

Below is the Example using PageFactory

1) Create a Project,

Create a FB login Page using PageFactory
package com.pf.pages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.CacheLookup;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
import org.openqa.selenium.support.PageFactory;
public class FBLoginPage {
WebDriver driver;
@FindBy(name="email")
WebElement wUserName;
@FindBy(how=How.ID,using="pass")
WebElement wPassword;
@FindBy(how=How.XPATH ,using ="//*[@value='Log In']")
@CacheLookup
WebElement wLoginBtn;
public FBLoginPage(WebDriver driver){
this.driver=driver;
PageFactory.initElements(driver,this);
}
public void setLoginUserName(String userName){
wUserName.sendKeys("satishd77@gmail.com");
}
public void clickSignIn(){
wLoginBtn.click();
}
public void setLoginPassword(String Password){
wPassword.sendKeys("Tester1");
}
public String verifyTitle() throws InterruptedException{
Thread.sleep(1000);
String sTitle=driver.getTitle();
System.out.println("Title"+sTitle);
return sTitle;
}
public void SingInToFB(String UserName, String Password){
this.setLoginUserName(UserName);
this.setLoginPassword(Password);
this.clickSignIn();
}
}

Create a FBHomePage using Page Factory

package com.pf.pages;
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;
public class FBHomePage {
WebDriver driver;
@FindBy(how=How.XPATH,using="//*[contains(text(),'Update Status')]")
WebElement wUpdateLbl;
public FBHomePage(WebDriver driver){
this.driver=driver;
PageFactory.initElements(driver, FBHomePage.class);
}
public void ClickHomeLink(){
System.out.println("Lable name is "+wUpdateLbl.getText());
}
public String VerifyNewMessage(){
String x=driver.getTitle();
System.out.println(x);
return driver.getTitle();
}
}// FBHomePage class end

Create a Test Case
package com.pf.testcase;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.PageFactory;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.pf.pages.*;

public class loginTC {
WebDriver driver;
FBLoginPage fbLogin;
FBHomePage fbhomePage;
@BeforeClass()
public void Configuration(){
driver = new FirefoxDriver();
driver.get("https://www.facebook.com/");
}

@Test()
public void HomePageTestCase() throws InterruptedException{
fbLogin=new FBLoginPage(driver);
String sVerifyTitle=fbLogin.verifyTitle();
Assert.assertTrue(sVerifyTitle.contains("Facebook - Log In or Sign Up"));
fbLogin.SingInToFB("satishd77@gamil.com", "Tester1");
fbhomePage=new FBHomePage(driver);
fbhomePage.ClickHomeLink();
String homePageTitle=fbhomePage.VerifyNewMessage();
Assert.assertTrue(homePageTitle.contains("Facebook"));
}
}

Create a TestNG.xml

<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEsuiteSYSTEM"http://testng.org/testng-1.0.dtd">
<suitename="Suite"parallel="none">
<testname="Test">
<classes>
<classname="com.pf.testcase.loginTC"/>
</classes>
</test><!-- Test -->
</suite><!-- Suite -->

Project Structure will looks like
clip_image001

AjaxElementLocatorFactory

AjaxElementLocatorFactory is another type of waiting technique for web elements , it behaves similar to implicit wait,It is basically used where application have more Ajax component Elements.

Ex 1): AjaxElementLocatorFactory AELFactory=AjaxElementLocatorFactory(driver,100);
PageFactory.initElements(AELFactory,this)

Ex:2)page class constructor
public  LoginPage(WebDriver  driver) {         
         this.driver = driver;
         PageFactory.initElements(new AjaxElementLocatorFactory(driver,100), this);
}

Note: After 100 sec if element is not visible to perform an operation, we will time out exceptions

Below is the Example using AjaxElementLocatorFactory

1) Create a Project,
Create a FB login Page using AjaxElementLocatorFactory
package com.pf.pages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.CacheLookup;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
import org.openqa.selenium.support.PageFactory;
public class FBLoginPage {
WebDriver driver;
@FindBy(name="email")
WebElement wUserName;
@FindBy(how=How.ID,using="pass")
WebElement wPassword;
@FindBy(how=How.XPATH ,using ="//*[@value='Log In']")
@CacheLookup
WebElement wLoginBtn;
public FBLoginPage(WebDriver driver){
this.driver=driver;
PageFactory.initElements(new AjaxElementLocatorFactory(driver,100) , this);
}
public void setLoginUserName(String userName){
wUserName.sendKeys("satishd77@gmail.com");
}
public void clickSignIn(){
wLoginBtn.click();
}
public void setLoginPassword(String Password){
wPassword.sendKeys("Tester1");
}
public String verifyTitle() throws InterruptedException{
Thread.sleep(1000);
String sTitle=driver.getTitle();
System.out.println("Title"+sTitle);
return sTitle;
}
public void SingInToFB(String UserName, String Password){
this.setLoginUserName(UserName);
this.setLoginPassword(Password);
this.clickSignIn();
}
}

Create a FBHomePage using AjaxElementLocatorFactory

package com.pf.pages;
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;
public class FBHomePage {
WebDriver driver;
@FindBy(how=How.XPATH,using="//*[contains(text(),'Update Status')]")
WebElement wUpdateLbl;
public FBHomePage(WebDriver driver){
this.driver=driver;
PageFactory.initElements(new AjaxElementLocatorFactory(driver,100) , this);
}
public void ClickHomeLink(){
System.out.println("Lable name is "+wUpdateLbl.getText());
}
public String VerifyNewMessage(){
String x=driver.getTitle();
System.out.println(x);
return driver.getTitle();
}
}// FBHomePage class end

Create a Test Case
package com.pf.testcase;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.PageFactory;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.pf.pages.*;
public class loginTC {
WebDriver driver;
FBLoginPage fbLogin;
FBHomePage fbhomePage;
@BeforeClass()
public void Configuration(){
driver = new FirefoxDriver();
driver.get("https://www.facebook.com/");
}
@Test()
public void HomePageTestCase() throws InterruptedException{
fbLogin=new FBLoginPage(driver);
String sVerifyTitle=fbLogin.verifyTitle();
Assert.assertTrue(sVerifyTitle.contains("Facebook - Log In or Sign Up"));
fbLogin.SingInToFB("satishd77@gamil.com", "Tester1");
fbhomePage=new FBHomePage(driver);
fbhomePage.ClickHomeLink();
String homePageTitle=fbhomePage.VerifyNewMessage();
Assert.assertTrue(homePageTitle.contains("Facebook"));
}
}

Create a TestNG.xml

<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEsuiteSYSTEM"http://testng.org/testng-1.0.dtd">
<suitename="Suite"parallel="none">
<testname="Test">
<classes>
<classname="com.pf.testcase.loginTC"/>
</classes>
</test><!-- Test -->
</suite><!-- Suite -->

Comments