Friday, November 1, 2013

Testing your web app with Selenium

Selenium is a web testing toolkit. This week I tried to use Selenium tools to create a test scenario that actually automates the web browser in order to populate test database. Similar to many open source tools, it has its rough edges.

My first problem is automating the jquery UI datepicker. Recording with Selenium IDE gives a result that is not too reliable :


It isn't easy to change the month or day in this test script. Running this script failed with error message that Selenium couldn't find the '1' link. The '1' is actually a clickable td but the script assumed it was a HTML link (a tag). Finding other sources, I replaced the last row with click css=td.day:contains("1"). Which sometimes doesn't work correctly because sometimes it choose the 31 cell instead of 1 cell. After a while I settled by a runScript command that invokes jQuery to set the datepicker value :

runScript $("Request_kembali").val("2013-01-01");

The second problem is that the application pops up alert boxes that has dynamic id. It uses smoke.js library. So for example it would be 1001.11 in one run, and it could be 2005.13 in another run. The solution is to change the locator from id-based to css-based, using css=.dialog-buttons button

The third problem is that when single-stepping using Selenium IDE, the script works fine, but when we execute the entire test case, there is an 'Element not found' error. The solution is to add waitForElement command before doing a click command.

The fourth problem, is that Selenium having difficult time when the app pops up a dialog box with many widgets such as data table and tabs. Because the pop up dialog box is a bit too complex I cheated by creating a javascript function in the app that I call using runScript command in Selenium IDE.

After the test case runs successfully under Selenium IDE, I tried to convert it into Java-based test case. I use two approaches that works equally well:
A. Create empty java project using IntelliJ IDEA (I had infinite troubles using Spring Tool Suite), add two new library referring to selenium libs folder and selenium jar file.
B. Create empty maven quickstart archetype, adds junit and selenium dependency.

Any of the two approach have similar problems :
1. Open commands converted to get method invocation with wrong url. The application folder name were concatenated twice in the url. The solution is fix the url manually.
2. More often than not, the click command doesn't work. There was no error but the browser seems to ignore the click command. I used latest Firefox (25.0) and Selenium Java driver (2.37), the possible solution is to change font size to 100%, or to downgrade the driver to 2.34, or to disable native events support (which I choose).

    FirefoxProfile profile = new FirefoxProfile();
    profile.setEnableNativeEvents(false);
    driver = new FirefoxDriver(profile);
 3. The runScript command didn't get converted. The solution is to manually convert those commands :
        JavascriptExecutor js = (JavascriptExecutor)driver;
        js.executeScript("formClearPemeriksa();");
        // ERROR: Caught exception [ERROR: Unsupported command [runScript | formClearPemeriksa(); | ]]
4. the CSS :contains selector is not supported by WebDriver. There are some solutions but I managed to replace the selector with other logic, avoiding the issue altogether.

But bandwidth issues makes running the test in my laptop not feasible. So I tried to do install Selenium java in RHEL/Centos Linux. For 5.x releases, I got stuck in exception (cannot find shared object) when trying to launch Firefox (v3.x) process remotely. It seems the built in Firefox is too old for Selenium. For 6.x releases that I had upgraded to Firefox 17.0, no such issue occured.