This test script uses 2 page objects, a home page and a results page:
@Test
public void canNavigateToOtherPagesTest() {
HomePage homePage = new HomePage(driver);
homePage.open();
Verify.verify(homePage.isDisplayed(), "home page is not displayed!");
ResultsPage resultsPage = homePage.searchBy(KEYWORD);
Verify.verify(resultsPage.isDisplayed(), "results page is not displayed!");
Verify.verify(resultsPage.getResultsFound().contains("1 to 10"),
"results found label does not include 1 to 10!");
resultsPage.goToPage(2);
Assert.assertTrue(resultsPage.isPageDisplayed(2));
resultsPage.goToPage(3);
Assert.assertTrue(resultsPage.isPageDisplayed(3));
resultsPage.goToPage(4);
Assert.assertTrue(resultsPage.isPageDisplayed(4));
}
The home page object is used with a few methods:
isDisplayed()
searchBy()
The results page object is used with
isDisplayed()
getResultsFound()
goToPage()
isPageDisplayed()
All methods used with the home page and results page objects in the test script are declared as public.
A quick look at the HomePage class shows something interesting:
public class HomePage {
private WebDriver driver;
private static final String HOME_PAGE_URL = "https://www.vpl.ca/";
private static final By SEARCH_BOX_ID = By.id("edit-search");
private static final By SEARCH_BUTTON_ID = By.id("edit-submit");
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) {
typeKeyword(keyword);
clickSearchButton();
return new ResultsPage(driver);
}
public void typeKeyword(String keyword) {
WebElement searchBox = driver.findElement(SEARCH_BOX_ID);
searchBox.sendKeys(keyword);
}
public void clickSearchButton() {
WebElement searchButton = driver.findElement(SEARCH_BUTTON_ID);
searchButton.click();
}
}
Interestingly, all methods are declared as public in this class.
Is that ok?
It is not ok.
Any class should have only a small number of its methods declared as public and the majority of the methods declared as private. Only the methods that are really used in test scripts should be public. All other methods that are used by the public methods should be private.
So, which methods should be public?
Which methods should be public? Which private?
isDisplayed() and searchBy() are used in the test script so they should be public.
getUrl(), typeKeyword(), clickSearchButton() are not used in test scripts. They are used by the class’s public methods so can be private.
The updated HomePage class is below:
public
class HomePage {
private WebDriver driver;
private static final String HOME_PAGE_URL = "https://www.vpl.ca/";
private static final By SEARCH_BOX_ID = By.id("edit-search");
private static final By SEARCH_BUTTON_ID = By.id("edit-submit");
public HomePage(WebDriver driver) {
this.driver = driver;
}
public void open() {
driver.get(HOME_PAGE_URL);
}
public boolean isDisplayed() {
return getUrl().equalsIgnoreCase(HOME_PAGE_URL);
}
private String getUrl() {
return driver.getCurrentUrl();
}
public ResultsPage searchBy(String keyword) {
typeKeyword(keyword);
clickSearchButton();
return new ResultsPage(driver);
}
private void typeKeyword(String keyword) {
WebElement searchBox = driver.findElement(SEARCH_BOX_ID);
searchBox.sendKeys(keyword);
}
private void clickSearchButton() {
WebElement searchButton = driver.findElement(SEARCH_BUTTON_ID);
searchButton.click();
}
}
The same thing can be done for the ResultsPage class.
Only the methods needed in the test script are public, all other methods being private:
public class ResultsPage {
private WebDriver driver;
private static final String RESULTS_PAGE_URL =
"https://vpl.bibliocommons.com";
private static final By RESULTS_FOUND_XPATH =
By.xpath("(//span[@data-key = 'pagination-text'])[1]");
private String pageXpath =
"//li[contains(@class, 'page-number')]/a[@data-page = '%s']";
public ResultsPage(WebDriver driver) {
this.driver = driver;
}
public boolean isDisplayed() {
return getUrl().startsWith(RESULTS_PAGE_URL);
}
public boolean isPageDisplayed(int n) {
return getUrl().contains("page=" + n);
}
private String getUrl() {
return driver.getCurrentUrl();
}
public String getResultsFound() {
WebElement label = driver.findElement(RESULTS_FOUND_XPATH);
return label.getText();
}
public void goToPage(int n) {
scrollToBottom();
By xpath = getPageXpath(n);
WebElement page = driver.findElement(xpath);
page.click();
}
private By getPageXpath(int n) {
String locator = String.format(pageXpath, n);
return By.xpath(locator);
}
private void scrollToBottom() {
((JavascriptExecutor) driver).executeScript(
"window.scrollTo(0, document.body.scrollHeight)");
}
}