Creating a simple webpage test with Selenium Webdriver

In the previous post I have written about how to get started writing tests in Java with Selenium Webdriver. In this post I’ll guide you how to write a simple test using the project structure created in the previous post. As an example, I’ll use this website (fullstackvlad.com).

Step 1. Clearly define what you want to check on the webpage

A correct question is a half of  the answer.  To write an accurate test you should first define a criteria of correct work (it’s also a great way to know your system better!). In this example, I’m going to check if fullstackvlad.com main webpage contains the search input (marked by the red rectangle in the picture below).


Step 2. Find out how to implement the criteria in Selenium

To locate webpage elements I recommend using XPath selectors – they are more suitable for testing purposes then CSS selectors. Read this post to find out how to obtain a web page element’s XPath. In this case search input has XPath:

//*[@id="secondary"]/div[1]/div/form/div[1]/label/input

As for me, it’s not enough. The input field is not specified by id, class or any other attribute. Let’s take a look on the element to find more accurate search criteria:

<input type="search" class="search-field" placeholder="Search..." value="" name="s" title="Search for:">

I would use type=”search” as a criteria in this case. So we can now rewrite XPath:

//*[@id="secondary"]/div[1]/div/form/descendant::input[@type="search"]

That’s  better!

Step 3. Create a Java class for the page

Creating a separate class for each webpage and element is a good practice (generally, I recommend you follow PageFactory pattern). Since we use an existing project structure I’m going to use com.mysite.pages.HomePage.java class for interacting with the main page.

If you want to create a new class you can just copy HomePage.java class (writing tests is almost always about copying and pasting. That’s a QA secret, though – don’t tell anyone:)).

Step 4. Create a class for the target element

Following PageFactory pattern you should create a class for the target element a set it as a property of the page class. In this example, we have the input field which is a part of the search form. Usually in such cases I create a class for the form. The form class has a method for checking form elements existence.

package com.mysite.elements;

import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebElement;

public class SearchForm
{
    protected WebElement form;

    public void setForm(WebElement object){
        form = object;
    }

    public boolean checkElementExistsByType(String type){
        try{
            form.findElement(By.xpath("./descendant::input[@type=\""+type+"\"]"));
            return true;
        }catch(NoSuchElementException e){
            return false;
        }
    }
}

The SearchForm.java class has WebElement form property to store the WebElement object, setter method and checkElementExistsByType method. In the Step 1 I have defined the search criteria based on the page element type attribute, so checkElementExistsByType method realize this logic. It looks for the form’s child input element with the specified type. If such element is not found, then NoSuchElementException exception is catched and false value is returned.

Step 5. Placing target element in the page class

I’ve created searchForm property in the HomePage.java class to store a SearchForm entity. Also I’ve added checkSearchFormExists method to be sure that search form exists in the page.

public class HomePage extends Page {

  private SearchForm searchForm;

  public HomePage(WebDriver webDriver) {
    super(webDriver);
  }

  public boolean checkSearchFormExists()
  {
    try{
        getSearchForm();
        return true;
    }catch(NoSuchElementException e){
        return false;
    }
  }

  public SearchForm getSearchForm()
  {
    if(searchForm == null){
      searchForm = new SearchForm();
      searchForm.setForm(driver.findElement(By.xpath("//*[@id=\"secondary\"]/div[1]/div/form")));
    }
    return searchForm;
  }
}

Step 6. Create a test

Finally I’ve added a test method testSearchInputExists. The method checks if search form exits on the page and it has search input element.

public class SampleTestNgTest extends TestNgTestBase {

  private HomePage homepage;

  @BeforeMethod
  public void initPageObjects() {
    homepage = PageFactory.initElements(driver, HomePage.class);
  }

  @Test
  public void testSearchInputExists() {
    driver.get(baseUrl);
    Assert.assertTrue(homepage.checkSearchFormExists());
    Assert.assertTrue(homepage.getSearchForm().checkElementExistsByType("search"));
  }
}

Step 7. Run the test

Now I’m ready to run the test (you can read how to run tests in this post). The result is:

===============================================
Tests
Total tests run: 1, Failures: 0, Skips: 0
===============================================