Front End Testing

The following test class tests the basic create functionality:

private ChromeDriver driver;
private WebDriverActor actor;
private CrudsSetup crudsSetup;

@Before
public void setUp() throws Exception {
  crudsSetup = new CrudsSetup();

  driver = new WebDriverSetup().setUp();
  actor = new WebDriverActor(driver);

  new WebLoginSetup(driver).doLogin();
}


@Test
public void testCreateNewElement() throws Exception {
  crudsSetup.setupTestData();

  driver.get(ORIGIN + "/stressTest/expander3214Test");

  // Click create button
  actor.clickOnElement(By.cssSelector("#nsx-paging button.create-button"));

  String title = actor.readElement(By.cssSelector("#expander-3-2-1-4-test > .modal-header span"));
  assertEquals("Expander 3 2 1 4 Test", title);


  // Fill name field
  actor.writeInput(By.cssSelector("div[id='expander3214Test.name'] input"), "0_Test_name");
  // Select dropdown field
  actor.writeInput(By.cssSelector("div[id='expander3214Test.targetGroup'] input"), "Grou");
  actor.clickOnElement(By.id("dropdown-option-group-a"));
  // Submit form
  actor.clickOnElement(By.cssSelector("#expander-3-2-1-4-test > .modal-footer button.button-primary"));

  // Check result on table
  String name = actor.readElement(By.id("stressTest-expander3214Test-group-a-0_test_name-name-cell"));
  assertEquals("0_Test_name", name);
}

@After
public void tearDown() throws Exception {
  crudsSetup.cleanup();
  driver.quit();
}

In order to make the testing easier, row-id’s have been added to the tables with the insertTableIds data-option:

<dataOption name="Expander3214Test:insertTableIds">
  <dataOptionType name="insertTableIds"/>
  <value>targetGroup_name</value>
</dataOption>

This test is based on Selenium. Below, the different steps of the test are explained.

Clicking on the create button

The create button is part of the paging. As such the create button on the main table can be found under the div with id nsx-paging. Each cruds-button has been fitted with a specific css-class to make it easier to select (or add layout).

This makes it possible to select the create-button with the css selector #nsx-paging button.create-button.

Checking the title of the dialog

To make sure we have the correct form, we can read out title on the dialog. All dialogs are appended to the span with id dynamicContent. However, each dialog also receives an id based on the title of the dialog. In this case, the title is “Expander 3 2 1 4 Test” and so the element receives an id of expander-3-2-1-4-test.

This id for the dialog is calculated by setting the title to lowercase and replacing the spaces with dashes.

We then select the span in the header of the dialog with #expander-3-2-1-4-test > .modal-header span.

Inserting the name

Each input field on the form is contained in a div with id defined as <element>.<field>. In this case, we select the input for the name field with div[id='expander3214Test.name'] input.

Due to the dot in the id of the field, we cannot use #expander306Test.name input, since that would search for a dom-element with id expander3214Test and class .name.

Selecting a dropdown option

The different options of a field with dropdown receive id’s of the form dropdown-option-<name>, where <name> is the name of the linked element or value of the tagValuePair.

Names are converted to a lowercase format. Special characters such as spaces are converted to dashes. E.g. ‘Group A’ is translated to ‘group-a’.

For the above test, we can select the correct option with id dropdown-option-group-a.

Submitting the form

In order to submit the form, we need to click on the submit button in the footer of the dialog. Since this button does not have any id, at the moment we can only identify it with the selector #expander-3-2-1-4-test > .modal-footer button.button-primary.

Alternatively, we can also try to just submit the form. The code will then look like:

driver.findElement(By.cssSelector("#expander-3-2-1-4-test form")).submit();

Which does look more readable, but does not test the functionality of the button.

Reading a cell of the main table

Lastly, we need to check whether a new instance has been created. We can select the main table by its id nsx-list. But, since we’ve added the option insertTableIds, we can find the each cell by its id: stressTest-expander3214Test-group-a-0_test_name-name-cell, which is a combination of the component, element and 2 fields that have been defined in the option.

To make sure the test runs exactly the same each time, the database is cleaned up through scripts after the test.

WebDriverActor class

For reference, here is the implementation of the WebDriverActor class:

package net.democritus.test.web;

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.elementToBeClickable;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

public class WebDriverActor {

  private final ChromeDriver driver;
  private final WebDriverWait wait;

  private static final int MAX_ATTEMPTS = 3;

  public WebDriverActor(ChromeDriver driver) {
    this.driver = driver;
    wait = new WebDriverWait(driver, 10);
    driver.manage().window().maximize();
  }

  public void clickOnElement(By elementRef) throws Exception {
    int nbAttempts = 0;
    while(true) {
      try {
        WebElement webElement = wait.until(elementToBeClickable(elementRef));
        Actions action = new Actions(driver);
        action.moveToElement(webElement).click().perform();
        return;
      } catch (Exception e) {
        if (++nbAttempts > MAX_ATTEMPTS) {
          throw e;
        }
      }
    }
  }

  public String readElement(By elementRef) throws Exception {
    int nbAttempts = 0;
    while(true) {
      try {
        String text = wait.until(visibilityOfElementLocated(elementRef))
            .getText();
        return text;
      } catch (Exception e) {
        if (++nbAttempts > MAX_ATTEMPTS) {
          throw e;
        }
      }
    }
  }

  public void writeInput(By elementRef, String input) throws Exception {
    WebElement element = driver.findElement(elementRef);
    element.sendKeys(input);
  }

}

References