
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.
Here are the main advantages of Page Object Pattern using:
So we have the page LoginPage shown on the image above.
This page contains the following elements:
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.
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.
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();
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
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.