Selenium Webdriver: Page Object Pattern and Pagefactory - IntexSoft
February 5, 2014 • by Alexandra

Selenium Webdriver: Page Object Pattern and Pagefactory

Tech Staff
image

How does webdriver work in selenium?

 

Page Object Pattern is a pattern that displays user interface as a class. In addition to user interface, functionality of the page is also described in this class. This provides a bridge between page and test.

 

 

Why should it be used?

 

Here are the main advantages of Page Object Pattern using:

 

  • Simple and clear tests.
  • Good support of tests, because everything is stored in one place.
  • Easy creation of new tests. In fact, tests can be created by a person not knowing the features of automation tools.
  • Simple example of using Page Object Pattern and PageFactory in Selenium WebDriver.

 

So we have the page LoginPage shown on the image above.

 

This page contains the following elements:

 

  • login field;
  • password field;
  • button «LoginButton»;
  • And the following functionality:
  • to enter something into login field;
  • to enter something into password field;
  • to click on the button «LoginButton»;
  • to log in to the application.

 

So our class describing LoginPage will look the following way:

 

 public class LoginPage {
     final WebDriver driver;@
     FindBy(how = How.NAME, using = "login") private WebElement loginEdit;
   	 @FindBy(how = How.NAME, using = "pass") private WebElement passwordEdit;
     @FindBy(how = How.NAME, using = "button") private WebElement loginButton;
     public LoginPage(WebDriver driver) {
         this.driver = driver;
     }
     public void enterLogin(String login) {
         loginEdit.clear();
         loginEdit.send(login);
     }
     public void enterPassword(String password) {
         loginEdit.clear();
         passwordEdit.send(password);
     }
     public void clickLoginButton() {
         loginButton.click();
     }
     public HomePage login(String login, String password) {
         enterLogin(login);
         enterPassword(password);
         clickLoginButton();
         return PageFactory.initElements(driver, HomePage.class);
     }
 }

 

Before we’ll examine the above code, let’s look at another HomePage page that we enter after clicking the login button.

 

This page contains the following elements:

 

  • Text «Hello!»
  • button «ExitButton»

 

And the following functionality:

 

  • Logout

 

So, our class describing HomePage will look the following way:

 

public class HomePage {
     final WebDriver driver;@
     FindBy(how = How.NAME, using = "text") private WebElement helloText;
     @FindBy(how = How.NAME, using = "exit") private WebElement exitButton;
     public HomePage(WebDriver driver) {
         this.driver = driver;
     }
     public void clickExitButton() {
         exitButton.click();
     }
     public LoginPage logout() {
         clickExitButton();
         return PageFactory.initElements(driver, LoginPage.class);
     }
 }

 

Now let’s look at our code:

 

Here we use the annotation FindBy for making the WebElement object to know to which element it belongs on web page (for example helloText belongs to the element whose attribute is name = text, and exitButton belongs to the element whose attribute is name = exit)

 

public HomePage(WebDriver driver) {
…
constructor of our class must take one WebDriver object
public void clickExitButton() {
…
public LoginPage logout() {
…
functionality described above
public LoginPage logout() {
…

 

This method returns to us the page class to which we go after a successful logout

 

clickExitButton();

 

here we describe the main steps of logout

 

 return PageFactory.initElements(driver, HomePage.class);

 

and so we return the page class initialized with PageFactory.

 

The same situation is with LoginPage.

 

It seems to be easy.

 

How will our test look?

 

public class LoginLogoutTest extends TestCase {
    WebDriver driver;
    private static String login = "admin";
    private static String pass = "test";
  @Before public void setUp() throws Exception {
        driver = new FirefoxDriver();
    }
  @Test public void testLoginLogout() throws Exception {
        driver.get("yousite.ru");
        LoginPage loginPage = PageFactory.initElements(driver, LoginPage.class);
        HomePage homePage = loginPage.login(login, pass);
        LoginPage loginPageAfterLogout = homePage.logout();
    }
  @After public void tearDown() throws Exception {
        driver.quit();
    }
}

 

 

As we see we’ ve got a simple and intuitive description of our test:

 

 

LoginPage loginPage = PageFactory.initElements(driver, LoginPage.class);
HomePage homePage = loginPage.login(login, pass);
LoginPage loginPageAfterLogout = homePage.logout();

 

 

Why use PageFactory?

 

For example, in the above classes, we used the following description of the elements on the page:

 

 @FindBy(how = How.NAME, using = "text") 
	private WebElement helloText;

 

But as we use PageFactory, code can be written as follows:

 

private WebElement text;

 

where text will refer to an element with the attribute name = text

 

What’s going on?

 

 

When we initialize the page using PageFactory, then, if annotation FindBy is not specified, PageFactory searches for elements on the page which name or id attributes match the name of WebElement. As a result, we actually do not have to worry about searching for elements on the page. If the element will appear on the page, so when we turn to it, it will be initialized.

 

Also, if we know that element is always present on the page, it is best to use the following declaration:

 

@FindBy(how = How.NAME, using = "text") 
@CacheLookup private WebElement helloText;

 

If we don’t do it, then every time when we turn to our element, WebDriver will check if the element is present on the page.

WRITTEN BY

image

Alexandra

Marketing Manager

FAVORITES OF THE MONTH

Don't miss our updates