You have a test case to automate for a website.
Here it is:
open home page of the site
check that home page is displayed
search by keyword in home page
check that results page is displayed after searching
get pagination info from results page
check that pagination info contains "1 to 10"
How should your Selenium test look like?
It should not look like this:
@Test
public void searchReturnsResults() {
driver.get("https://www.vpl.ca");
Assert.assertTrue(driver.getCurrentUrl().contains("vpl.ca"));
WebElement searchBox = driver.findElement(By.id("edit-search"));
searchBox.sendKeys("java");
WebElement searchButton = driver.findElement(By.id("edit-submit"));
searchButton.click();
Assert.assertTrue(driver.getCurrentUrl().contains("bibliocommons.com"));
WebElement paginationInfoLabel = driver.findElement(
By.xpath("(//span[@data-key = 'pagination-text'])[1]"));
String paginationInfotext = paginationInfoLabel.getText();
Assert.assertTrue(paginationInfoText.getText().contains("1 to 10"));
}
This test does not follow a lot of good practices:
the test is focused not on the user actions (example: search for keyword) but on how the user does his actions (type keyword into search box, click search button)
it is not clear what code runs on home page and what runs on results page
it is not clear the site navigation from home page to results page
it uses Selenium objects and methods in the test; it should not
it hard-codes values such as urls (vpl.ca), keyword (java) and locators
it does not use synchronization when finding elements
it uses incorrect assertions (assertTrue to verify if a text is included in a String value)
it creates unnecessary variables (paginationInfoText)
it is not easy to understand (by people with no coding experience)
it is not simple
it is not short
The test should not look like this either:
@Test
public void searchReturnsResults() {
utilities.openPage(homePageUrl);
Assert.assertTrue(utilities.getUrl().contains(homePageUrl));
utilities.typeIntoTextBox(searchTextBoxId, keyword);
utilities.clickButton(searchButtonId);
Assert.assertTrue(utilities.getUrl().contains(resultsPageUrl));
String paginationInfoText = utilities.getText(paginationTextXpath);
Assert.assertTrue(paginationInfoText.contains("1 to 10"));
}
This test is not much better than the previous one.
Yes, it does not use Selenium objects and methods.
Yes, it does not hard-code urls, locators and the keyword.
But all other problem are still there.
How should the test look like?
This is how:
@Test
public void searchReturnsResults() {
HomePage homePage = new HomePage(driver);
homePage.open();
Assert.assertTrue(homePage.isDisplayed(), "home page is not displayed!");
ResultsPage resultsPage = homePage.searchBy(KEYWORD);
Assert.assertTrue(resultsPage.isDisplayed(),
"results page is not displayed!");
assertContains(resultPage.getPaginationInfo(),
"1 to 10",
"pagination info does not include 1 to 10!");
}
This test solves all previous issues:
no Selenium objects and methods are used in the test
the test is focused on the user actions instead on how the user does his actions
it is clear what code runs on home page and what runs on results page
it is clear the site navigation from home page to results page; results page is the outcome of searching in home page
it does not hard-code values such as urls (vpl.ca), keyword (java) and locators
it uses synchronization when finding elements (inside of the page methods)
it uses correct assertions (assertContains to verify if a text is included in a String value)
it does not create unnecessary variables
it is easy to understand
it is short
it is simple