More Unit-testing with Selenium

Some of my first Selenium unit-tests showed some strange behaviour: Every now and then a test would fail, even though a minute ago it worked and neither the test-code nor the webapp has been changed, I almost got the impression that it would be impossible to use Selenium for automated unit-testing of our framework: oo many releases would not be flagged as stable, because of erratically failed unit-tests.

Don’t know why, but at some point it dawned that maybe there was … a timing problem. Maybe some assertions were called before the result was delivered to the browser… and in the Selenium API I found methods like selenium.waitForPageToLoad(PAGE_LOAD_TIMEOUT) … isn’t that inspiring? Some tests and yes that was the solution. But use that method-call after each action? NO WAY

So time to write my SeleniumTestCase to be used as the base class and full of goodies (convenience methods):

import static org.junit.Assert.assertEquals;

import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.openqa.selenium.server.SeleniumServer;

import com.thoughtworks.selenium.DefaultSelenium;
import com.thoughtworks.selenium.Selenium;
import com.thoughtworks.selenium.SeleniumException;

public abstract class SeleniumTestCase {

  public static final String PAGE_LOAD_TIMEOUT = "10000";
  public static final String BASE_URL = "http://localhost:8080/myWebApp/";

  protected static Selenium seleniumStatic;
  protected Selenium selenium = null;

  public SeleniumTestCase() {
    this.selenium = seleniumStatic;
  }

  @BeforeClass
  public static void setUpBeforeClass() throws Exception {
    seleniumStatic = new DefaultSelenium("localhost", SeleniumServer.getDefaultPort(), "*firefox", BASE_URL);
    seleniumStatic.start();
  }

  @AfterClass
  public static void tearDownAfterClass() throws Exception {
    seleniumStatic.stop();
  }

  @Before
  public void setUp() throws Exception {
  }

  public boolean isAttributeMissing(String xPath){
    boolean result = true;
    try {
      selenium.getAttribute(xPath);
      result = false;
    } catch (SeleniumException e) {
      if (e.getMessage().contains("ERROR: Could not find element attribute: " + xPath)) {
        result = true;
      } else {
        throw(e);
      }
    }
    return result;
  }

  public boolean isElementMissing(String xPath){
    boolean result = true;
    try {
      selenium.getElementIndex(xPath);
      result = false;
    } catch (SeleniumException e) {
      if (e.getMessage().contains("ERROR: Element " + xPath + " not found")) {
        result = true;
      } else {
        throw(e);
      }
    }
    return result;
  }

  public Object getAttribute(String xPath){
    Object result = null;
    try {
      result = selenium.getAttribute(xPath);
    } catch (SeleniumException e) {
      if (e.getMessage().contains("ERROR: Could not find element attribute: " + xPath)) {
        result = null;
      } else {
        throw(e);
      }
    }
    return result;
  }

  public boolean submitAndWait(String formLocator) {
    boolean result = false;
    try {
      selenium.submit(formLocator);
      selenium.waitForPageToLoad(PAGE_LOAD_TIMEOUT);
      result = true;
    } catch (Throwable t) {
      result = false;
      System.err.println("--- received an exception: " + t);
    }

    return result;
  }

  public boolean clickAndWait(String elementLocator) {
    boolean result = false;
    try {
      selenium.click(elementLocator);
      selenium.waitForPageToLoad(PAGE_LOAD_TIMEOUT);
      result = true;
    } catch (Throwable t) {
      result = false;
      System.err.println("--- received an exception: " + t);
    }

    return result;
  }

  public boolean openAndWait(String url) {
    boolean result = false;
    try {
      selenium.open(url);
      selenium.waitForPageToLoad(PAGE_LOAD_TIMEOUT);
      result = true;
    } catch (Throwable t) {
      result = false;
      System.err.println("--- received an exception: " + t);
    }

    return result;
  }
}

With that base class, the tests can look like this:

selenium.type("id=containerForm:hideUser", "hide");
submitAndWait("id=containerForm");

… to be continued …

Advertisements

One Comment on “More Unit-testing with Selenium”

  1. […] UnitTest — ajesse @ 6:47 pm Since the original post introducing SeleniumControl and SeleniumTestCase these two classes learned some more […]


Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s