Do not use WebDriver APIs in the Test Script

Test automation starts with a test case.

For example:

1. open the home page of the site (http://www.vpl.ca)

2. run a keyword search

3. validate that the number of results for the keyword search is greater than 0

 

The test case is high level and includes actions that a user would take.

 

To automate it, it needs to be described at a lower level:

1. open the home page of the site (http://www.vpl.ca)

2. run a keyword search

2.1 find the search textbox element
2.2 type a keyword in the search textbox element
2.3 find the search button
2.4 click the search button

3. validate that the number of results for the keyword search is greater than 0

3.1 find the result count label element
3.2 get the value of the result count label
3.3 extract the number of results from the result count value
3.4 verify that the number of results is greater than 0

The code of the test automation script is below:

@Test
public void testFirstResult() {

String url = “http://www.vpl.ca”;

By searchTextBoxLocator = By.xpath(“//input[@id=’globalQuery’]”);

By searchButtonLocator = By.xpath(“//input[@class=’search_button’]”);

By resultsCountLocator = By.xpath(“//span[@class=’items_showing_count’]”);

 

driver.get(url);

WebElement searchField = driver.findElement(searchTextBoxLocator );

searchField.click();

searchField.sendKeys(“java”);

WebElement searchButton = driver.findElement(searchButtonLocator );

searchButton.click();

WebElement resultCountLabel = driver.findElement(resultsCountLocator );

String resultCountValue = resultCountLabel.getText();

int index1 = resultCountValue.indexOf(“of”) + 3;
int index2 = resultCountValue.indexOf(“items”) – 1;

resultCountValue = resultCountValue.substring(index1, index2);

int resultCount = Integer.parseInt(resultCountValue);

assertTrue(resultCount > 0);

}

 

The script includes many WebDriver API objects and methods:

  • WebElement objects
  • By objects
  • driver.findElement() method
  • getText() method
  • click(), sendkeys() methods()

 

Manual testers learning test automation write code that looks like this.

The code works.

Imagine having 50 other scripts similar to this.

What’s wrong here?

Scripts like this one have multiple problems:

– they are difficult to understand by manual testers with no programming experience
– they are difficult to change
– they are difficult to maintain

This way of writing test automation code is incorrect as per Simon Stewart, creator of Selenium WebDriver:

If you have WebDriver APIs in your test methods, You’re Doing It Wrong.

Simon Stewart.

 

So how do we fix the test scripts?

The Page Object Model helps:

“A page object wraps an HTML page, or fragment, with an application-specific API, allowing you to manipulate page elements without digging around in the HTML.”

Martin Fowler

 

This model states that page object classes should be created for each web page of the site.

The page object classes implement the interaction with the site using Selenium WebDriver APIs.

The test automation scripts use then the page object classes and assertions.

Basically, what we should do is to structure the test script so that it follows not the detailed test case but the high level one:

 

@Test
public void testResultsInfo()
{

HomePage home = new HomePage(driver);

home.open();

ResultsPage results = home.search();

assertTrue(results.resultsCount() > 0);

}

 

The test script does not include WebDriver API any longer.

It is as easy to read as the high level test case.

It uses 2 page object classes:

  1. HomePage
  2. ResultsPage

Lets see how the code can be added to these 2 classes.

 

HomePage class

It implements all user actions for the home page.

In this case, there are 2 actions only:

  1. open() – open the home page of the site
  2. search() – run a keyword search

 

public class HomePage
{

WebDriver driver;

String url = “http://www.vpl.ca”;

By searchTextBoxLocator = By.xpath(“//input[@id=’globalQuery’]”);

By searchButtonLocator = By.xpath(“//input[@class=’search_button’]”);

public HomePage(WebDriver driver)
{

this.driver = driver;

}
public void open()
{

driver.get(url);

}

public ResultsPage search(String keyword)
{

WebElement searchField = driver.findElement(searchTextBoxLocator);

searchField.click();

searchField.sendKeys(keyword);

WebElement searchButton = driver.findElement(searchButtonLocator);

searchButton.click();

return new ResultsPage(this.driver);

}

 

 

ResultsPage class

For the results page, we just need to have a method that returns the number of results:

public class ResultsPage {

WebDriver driver;

By resultsCountLocator = By.xpath(“//span[@class=’items_showing_count’]”);

public ResultsPage(WebDriver driver)
{

this.driver = driver;

}

public integer resultsCount()
{

WebElement resultCountLabel = driver.findElement(resultsCountLocator);

String resultCountValue = resultCountLabel.getText();

int index1 = resultCountValue.indexOf(“of”) + 3;
int index2 = resultCountValue.indexOf(“items”) – 1;

resultCountValue = resultCountValue.substring(index1, index2);

int resultCount = Integer.parseInt(resultCountValue);

return returnCount;

}

 

To summarize, the test automation scripts should not include WebDriver APIs.

Page object classes should be created for implementing user actions for each page.

The test scripts should use only page objects and assertions.

One Comment

Leave a comment