The following page object classes are slightly different than before.
First, HomePage:
public class HomePage {
private WebDriver driver;
private static final String HOME_PAGE_URL = "https://www.vpl.ca/";
public HomePage(WebDriver driver) {
this.driver = driver;
}
public void open() {
driver.get(HOME_PAGE_URL);
}
public boolean isDisplayed() {
return getUrl().equalsIgnoreCase(HOME_PAGE_URL);
}
public String getUrl() {
return driver.getCurrentUrl();
}
public ResultsPage searchBy(String keyword) {
WebElement searchBox = driver.findElement(Locators.SEARCH_BOX_ID);
searchBox.sendKeys(keyword);
WebElement searchButton = driver.findElement(Locators.SEARCH_BUTTON_ID);
searchButton.click();
return new ResultsPage(driver);
}
}
Then, ResultsPage:
public class ResultsPage {
private WebDriver driver;
private static final String RESULTS_PAGE_URL =
"https://vpl.bibliocommons.com";
public ResultsPage(WebDriver driver) {
this.driver = driver;
}
public String getUrl() {
return driver.getCurrentUrl();
}
public boolean isDisplayed() {
return getUrl().startsWith(RESULTS_PAGE_URL);
}
public String getResultsFound() {
WebElement label = driver.findElement(Locators.RESULTS_FOUND_XPATH);
return label.getText();
}
public void goToPage2() {
WebElement page = driver.findElement(Locators.PAGE_2_XPATH);
page.click();
}
public void goToPage3() {
WebElement page = driver.findElement(Locators.PAGE_3_XPATH);
page.click();
}
public void goToPage4() {
WebElement page = driver.findElement(Locators.PAGE_4_XPATH);
page.click();
}
}
They do not have any locator fields, relying instead on variables of the Locators class:
public final class Locators {
public static By SEARCH_BOX_ID = By.id("edit-search");
public static By SEARCH_BUTTON_ID = By.id("edit-submit");
public static By RESULTS_FOUND_XPATH =
By.xpath("(//span[@data-key = 'pagination-text'])[1]");
public static By PAGE_2_XPATH =
By.xpath("//li[contains(@class, 'page-number')]/a[@data-page = '2']");
public static By PAGE_3_XPATH =
By.xpath("//li[contains(@class, 'page-number')]/a[@data-page = '3']");
public static By PAGE_4_XPATH =
By.xpath("//li[contains(@class, 'page-number')]/a[@data-page = '4']");
}
Both HomePage and ResultsPage classes are shorter without locators.
Their code is as simple as before as the only change to it is that each locator is prefixed by the Locators class.
Still, this is something to avoid, moving all locators out of the page classes and into a locators class.
There are multiple reasons for it:
each class should have fields and methods; the fields are related to the state of the class’s objects, the methods describe the behavior of the objects; with no locators, the page object class becomes a collection of methods
locator classes start small but tend to grow in time as you add more and more locators; after a while, you will add comments describing which locators belong to each page class; and due to size, you will need to scroll up and down in the class looking for locators.
when the locator class becomes big, you may be tempted to break it down in multiple locator classes, each linked to a specific page class; this is more complex than just keeping everything in the same page class, locators and page methods
every time you need to see the value of a locator, you will leave the current class, navigate to the locators class, make the change and then come back to the page class; this is more complex than just staying in the same class all the time
moving locators out of the page classes will not help much with reducing the page class size
So, keep the locators in the page classes.
Do not move them to a dedicated locator class.
And, yes, moving locators to a property file is even worse.