Tuesday, July 11, 2017

Selenium Java getting started

1. Intro

What is selenium?

From wiki:
Selenium is a portable software-testing framework for web applications. Selenium provides a record/playback tool for authoring tests without the need to learn a test scripting language (Selenium IDE). It also provides a test domain-specific language (Selenese) to write tests in a number of popular programming languages, including C#GroovyJavaPerlPHPPythonRuby and Scala. The tests can then run against most modern web browsers. Selenium deploys on WindowsLinux, and OS X platforms. It is open-source software, released under the Apache 2.0 license: web developers can download and use it without charge.

Let's try to do some simple tasks using this library. I want to use if for testing my simple ReactJS application, which I created week ago.


2. How it works. 

With selenium we can "emulate" all user actions we need: entering text into input fields, clicking the buttons, checking checkboxes and many others. But first of all, we need to find somehow element for which we want to perform such actions. In selenium there are a lot of options for doing this:

  • by id
  • by name
  • by tag name 
  • ....




In this post I'm using the simplest way: by element id.
Example: driver.findElement(By.id("submit-department").click();

Here is a list of html elements which I will be accessing by theirs ids:



3. SetUp

There are just few things to start working with selenium:

  • first of all we have to add to our project selenium dependency. Example for  gradle:

      compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '2.41.0'
  • also we need the driver for your favorite browser. For example for ChromeBrowser you can download it from here. You have have to unpack it and put it somewhere in file system. 
  • And finally, driver binary from previous step, have to be set up as system property in your code this way:
System.setProperty("webdriver.chrome.driver", "d:/dev/selenium/chromedriver.exe");

After that we can try to create the instance of driver and open something with the browser:
WebDriver driver = new ChromeDriver();
driver.get("http://localhost:3000");

-it should run the browser and navigate it to page from code above.



4. Testing 

I wrote very simple application which creates several departments and after that several users. And users creation goes using departments created before. At the end I'm checking if all departments and users were created.


package com.demien.seltest;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.Select;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

public class App {

    static WebDriver driver;

    public static void clearAndSet(String id, String value) {
        driver.findElement(By.id(id)).clear();
        driver.findElement(By.id(id)).sendKeys(value);
    }

    public static void click(String id) {
        driver.findElement(By.id(id)).click();
    }

    public static void select(String id, String option) {
        Select select = new Select(driver.findElement(By.id(id)));
        select.selectByVisibleText(option);
    }

    public static void addDepartment(String id, String name) {
        clearAndSet("input-departments-id", id);
        clearAndSet("input-departments-name", name);
        click("submit-departments");
    }

    public static void addUser(String id, String name, String email, String department) {
        clearAndSet("input-users-id", id);
        clearAndSet("input-users-name", name);
        clearAndSet("input-users-email", email);
        select("select-users-department", department);
        click("submit-users");
    }

    public static void checkTable(String id, List<String> values) {
        WebElement table = driver.findElement(By.id(id));

        List<WebElement> allRows = table.findElements(By.tagName("tr"));
        for (WebElement row : allRows) {
            List<WebElement> cells = row.findElements(By.tagName("td"));
            for (WebElement cell : cells) {
                values.remove(cell.getText());
            }
        }

        if (values.size() > 0) {
            throw new RuntimeException("Some elements are absent in table:" + Arrays.toString(values.toArray()));
        }
    }

    public static void checkTable(String id, String... values) {
        checkTable(id, new LinkedList<>(Arrays.asList(values)));
    }

    public static void main(String[] args) {
        System.setProperty("webdriver.chrome.driver", "d:/dev/selenium/chromedriver.exe");
        driver = new ChromeDriver();

        driver.get("http://localhost:3000");

        addDepartment("IT", "Informational technologies");
        addDepartment("ADM", "Administration");
        addDepartment("SEQ", "Security");

        checkTable("table-departments", "IT", "ADM", "SEQ", "Informational technologies", "Administration", "Security");

        addUser("JBL", "Joe Black", "joe.black@email.com", "Security");
        addUser("HSEB", "Huan Sebastyan", "huan.sebastyan@email.com", "Administration");

        checkTable("table-users", "JBL", "Joe Black", "joe.black@email.com", "Security", "HSEB", "Huan Sebastyan", "huan.sebastyan@email.com", "Administration");

    }
}

5. The end 

As a result, using just code from above, I created 3 departments and 2 users.




Source code can be downloaded from here