Selenium Page Object Java example

selenium page object java exampleIn this guide we will show the example of implementing Page Object pattern for Selenium automated tests using Java API. It has a brand new approach comparing to usual WebDriver functionality.

What is Page Object?

Page Object is a software design pattern used in test automation of web UI. It’s main idea is to describe web-pages as java classes with methods. It provides a good level of logic encapsulation. Just look through the example to clarify:

selenium page-object javaWhat does it give to you? Usually, test automation engineers write test by scenarios. In a lot of cases it all leads to creating the sequence of low-level scenarios like “find that” or “click this”. It may work perfectly untill UI changes. If you hardcoded all selectors to your web elements in scenarios you will need a lot of affort to fix that (I worked on a project with thousands of such scenarios).

In case of Page Object pattern the page logic is encapsulated inside page’s methods. So, for example, if the posts layout on the Main page has changes, just improve the logic inside getPostNames() and openPost() methods, so test scenarios would not be affected.

Page Object Java Example

Let’s automate some behavior on our blog. At first, we need to create classes for 2 pages:

  • MainPage (the root page that opens when you visit 10minbasics.com)
  • PostPage (the page that opens when you click on some post)

To determine page elements we use class field annotated by @FindBy. It has the same selectors as WebDriver’s findElement() method.

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

import java.util.ArrayList;
import java.util.List;

public class MainPage {
    public MainPage(WebDriver driver) {
        PageFactory.initElements(driver, this);
    }

    @FindBy(xpath = "//*[@id='entry-title']/a")
    private List<WebElement> postHeaders;

    public List<String> getPostNames(){
        List<String> postNames = new ArrayList<>();
        for (WebElement header : postHeaders) {
            postNames.add(header.getText());
        }
        return postNames;
    }

    public void openPost(String postName){
        for (WebElement header : postHeaders) {
            if (header.getText() == postName) {
                header.click();
                break;
            }
        }
        try {
            Thread.sleep(5000); // to wait while new page opens
            // it need to be replaced by a normal wait mechanism
        } catch (InterruptedException e) {}
    }
}
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;

import java.util.ArrayList;
import java.util.List;


public class PostPage {
    public PostPage(WebDriver driver) {
        PageFactory.initElements(driver, this);
    }

    @FindBy(id = "entry-title")
    private WebElement postHeader;

    @FindBy(className = "//*[@class='wc-comment-text']/p")
    private List<WebElement> comments;

    @FindBy(tagName = "img")
    private List<WebElement> images;

    public String getPostHeader(){
        return  postHeader.getText();
    }

    public List<String> getComments(){
        List<String> commentStrings = new ArrayList<>();
        for (WebElement comment : comments) {
            commentStrings.add(comment.getText());
        }
        return commentStrings;
    }

    public int getImagesCount(){
        return images.size();
    }
}

Now we need to create a simple test example using our Page-Object classes:

public class TestExample {

    private WebDriver driver = new FirefoxDriver();

    @Test
    public void test() throws InterruptedException {
        driver.get("http://10minbasics.com");
        Thread.sleep(3000); // wait for page loading. Replace with a correct wait mechanism
        MainPage mainPage = new MainPage(driver);
        // get all posts names
        List<String> postNames = mainPage.getPostNames();
        System.out.println("The number of posts on the Main page: " + postNames.size());
        // open the first post in a list
        mainPage.openPost(postNames.get(0));

        //Now we are on the Post page
        // initialize the page class
        PostPage postPage = new PostPage(driver);
        System.out.println("The number of images in the latest post: " + postPage.getImagesCount());

        driver.close();
    }
}

 

Leave a Reply

Be the First to Comment!