Initializing proxied objects

For the PageFactory annotation to work, you must initialize your class.  WebElement objects will not be proxied and the annotations that you have specified will not be applied if you forget to do this. Initializing your class is one very simple line of code:

PageFactory.initElements(DriverBase.getDriver(), LoginPage.class);

While this is easy, it is also quite ugly and not instantly obvious to people who don't know about the PageFactory class. Let's make this easier and more understandable for any developers who are going to look at our code. What we are going to do is initialize our class in the constructor of our page object:

package com.masteringselenium.page_factory_objects;

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 LoginPage {

@FindBy(how = How.ID, using = "username")
private WebElement usernameField;

@FindBy(how = How.ID, using = "password")
private WebElement passwordField;

@FindBy(how = How.ID, using = "login")
private WebElement loginButton;

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

public void logInWithUsernameAndPassword(String username,
String password) {
usernameField.sendKeys(username);
passwordField.sendKeys(password);
loginButton.click();
}
}

Now, our code that creates a new page object instance will look like this:

LoginPage loginPage = new LoginPage(getDriver());

It's much cleaner and a pattern that all Java developers will instantly recognize. We do still have a code smell here though. We are needlessly passing around a driver object all the time, so how can we go one step further? Well, the getDriver() method that we are using to pass our driver object into the page object is static. This means that anything can use it to get the driver object associated with the current thread. We can use this in our page objects to remove the need to pass around the driver object:

package com.masteringselenium.page_factory_objects;

import com.masteringselenium.DriverBase;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

public class LoginPage {

@FindBy(how = How.ID, using = "username")
private WebElement usernameField;

@FindBy(how = How.ID, using = "password")
private WebElement passwordField;

@FindBy(how = How.ID, using = "login")
private WebElement loginButton;

public LoginPage() throws Exception {
PageFactory.initElements(DriverBase.getDriver(), this);
}

public void logInWithUsernameAndPassword(String username,
String password) throws Exception {
usernameField.sendKeys(username);
passwordField.sendKeys(password);
loginButton.click();

WebDriverWait wait = new
WebDriverWait(DriverBase.getDriver(), 15, 100);
wait.until(ExpectedConditions.visibilityOfElementLocated
(By.id("username")));
}
}

This now means that all we need to create a new page object instance is:

LoginPage loginPage = new LoginPage();

Our page objects now look like any other object in Java and the fact that we can just new-up our page object without providing any parameters means that it is easy to start using our page objects as building blocks.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.114.38