Sunday, March 21, 2010

New Richfaces Selenium Library for Automated functional testing of RichFaces 3.3.x

Motivation

We needed this library because we wanted to have stable automated tests against different browsers and on different platforms for RichFaces functional testing. It encapsulates good functionalities for testing AJAX behaviours and is ready for testing Firefox and Internet Explorer. Its' first implementation is used for testing RichFaces 3.3.X in 403 unique tests for in over 76 test cases for each RichFaces component.

Internet Explorer ready

What makes this project unique is its own implementation of own HttpCommandProcessor which enables functionality in Internet Explorer – it handles known Permission denied exceptions in Selenium when you are trying to access JavaScript from TestRunner window before the page is loaded. This is caused by security model of Internet Explorer and really harden usage of selenium functions in Internet Explorer in comparison to Firefox.

JQuery Selectors over the XPath

The support for JQuery Selectors as location strategy isn't unique but it is complete and nice to have to support multiple browsers for test. This makes test suite run with Internet Explorer more reliable. This browser has at the moment very slow Xpath evaluator and that's why test cases written in this language suffer in execution speed. Implementation of JQuery Selectors to our test cases was simple, but we had to rewritte all of the locators to JQuery Selector syntax. It actually reduced execution time from 4:30hr to 1:30hr and made lots of test cases pass. It enabled to have same test suites for Firefox and Internet Explorer.

Testing Dragable

Also the Drag class is important – it encapsulates sequence of commands to drag one object to target object and enables testing of behaviour of dragged object in each phase of dragging sequence. Nice for testing Drag-and-Drop support in RichFaces.

Waiting-improved

Waiting for satisfying conditions

The last big feature which needs to be mentioned is Wait class. It is similar to Wait class from Selenium 1.0, but it has much more readable and customizable syntax, for example:

Wait.dontFail().timeout(5000).interval(500).until(new Condition() { … })

or

Waiting waitForModelUpdate = Wait.timeout(30000).interval(2000);

waitForModelUpdate.failWith(“Causes {0}”, someObjectToFormat).until(new Condition() { … });

Customizable behaviour of failure

It wasn't something what we could not implement with Selenium's Wait class (except the dontFail/failWith handling the resulting exception when waiting timeouts).

Wait for change conditions

Pretty usable is also addition of waitForChange(...) and waitForChangeAndReturn(...) methods. Its purpose is also quite self-describing. Sample followes:

waitForModelUpdate.waitForChange(“phase 2”, new Retrieve() { String retrieve() { selenium.getText(locator); });

Maven-based integration

What I'm really proud of is Maven configuration for Selenium tests (it isn't a part of the library yet, but we are planning so). For better overview, take a look at readme doc or POM. It enables us to have same configuration for Windows and Linux Hudson machines incl. various browsers (Firefox and IE) and various containers (JBossAS and Tomcat). It contains selenium-maven-plugin, cargo deployer and maven-surefire-plugin executing test suite. Really nice is the debugging feature (look for Debugging in readme.html) when you are running the SeleniumServer on one host, container on another host and you are running test suite in debugging mode from your preferred IDE.

Stay warmed...

Please keep an eye on this blog space. We are planning new version of richfaces-selenium library introducing type-safety and commonness to full-featured AJAX testing!

How to start?

Source code of richfaces-selenium library

RichFaces LiveDemo and it's test-suite
(example of test case - Editable Table with Modal Panel)

3 comments:

  1. I am getting an error message that says the fields does not exist.

    I could map the field using:
    WebElement modalPanel = driver.findElement(By.id("corpo:formulario:painelGenericoContainer"));
    WebElement dsArquivo = modalPanel.findElement(By.xpath("//*[@id='corpo:formulario:dsArquivo']"));

    But I could not sendKeys using:
    dsArquivo.sendKeys("testing");

    It displays the following error message:
    Exception in thread "main" org.openqa.selenium.NoSuchElementException: Unable to locate element: {"method":"xpath","selector":"//*[@id='corpo:formulario:despachanteText']"}
    For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
    Build info: version: '2.5.0', revision: '13516', time: '2011-08-23 18:30:44'
    System info: os.name: 'Windows XP', os.arch: 'x86', os.version: '5.1', java.version: '1.6.0_27'
    Driver info: driver.version: RemoteWebDriver
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:131)
    at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:105)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:409)
    at org.openqa.selenium.remote.RemoteWebElement.execute(RemoteWebElement.java:191)
    at org.openqa.selenium.remote.RemoteWebElement.findElement(RemoteWebElement.java:114)
    at org.openqa.selenium.remote.RemoteWebElement.findElementByXPath(RemoteWebElement.java:167)
    at org.openqa.selenium.By$ByXPath.findElement(By.java:350)
    at org.openqa.selenium.remote.RemoteWebElement.findElement(RemoteWebElement.java:110)
    at org.openqa.selenium.example.Script_003.runTest003(Script_003.java:63)
    at org.openqa.selenium.example.Script_003.main(Script_003.java:115)

    Can you help me?

    ReplyDelete
  2. Hi , Thanks for the article and its very informative.

    I am facing a problem in checking out the code from
    http://anonsvn.jboss.org/repos/richfaces/branches/community/3.3.X/samples/richfaces-demo/functional-test/src/test/java/org/jboss/richfaces/integrationTest/

    tried to check out svn co "URL" and tortoise svn client as well,

    Error running context: No connection could be made because the target machine

    ReplyDelete