Using Selenium to test JSF (myFaces impl) application

I have been looking for a good way to do integration testing of webapplications done in JSF, and decided to give Selenium a try.
First I had a look at the Selenium IDE, it is basically a Firefox “record” tool that remembers the actions you do in the webapp, and then saves these actions as a test-template for you to use later on. But I didn’t want to limit myself to any browser, and I would also like to keep an opening for some continous build processes and frameworks. I therefore decided to go for Selenium Remote Control (Selenium RC), which also allows me to write the tests in java.

I know that Selenium recommends using TestNG instead of JUnit (JUnit should be considered a unit testing tool, not for integration testing) , but since I had some (moderate) experience with JUnit from before I decided to go for this. So I downloaded Selenium RC, and created a new java-project in Eclipse with selenium-java-client-driver.jar, selenium-server.jar and junit.jar in my lib-folder. Both selenium-java-client-driver.jar and junit.jar should be added to the build path, but there’s no need to add selenium-server.jar.

Before you run your tests the selenium server needs to be running, and you can manually start this from command-line by running the command “java -jar selenium-server.jar”. But then, you might want to add some options or specify some properties, and perhaps you don’t want to start messing around with the cmd-window at all. So I created an ant-task for starting and stopping the server. This task I can then set as dependency in another task that runs my tests, but this is of course up to you.

The start task:

	<target name="selenium-start">
		<java jar="${lib.test.dir}/${selenium-jar}" fork="true" spawn="true">
			<arg  line="-port ${selenium.port}" />
			<arg  line="-debug" />
			<arg  line="-log ${build.dir}/selenium.log" /> 		

The stop task:

	<target name="selenium-stop" description="Stop the Selenium RC server on port ${selenium.port}">
		<get taskname="selenium-shutdown" dest="${build.dir}/selenium.log" src="http://localhost:${selenium.port}/selenium-server/driver/?cmd=shutDown" ignoreerrors="true" />

So, what about the testing?

If you’re familiar with JUnit, you know that you need to define the setUp() and tearDown() method. Selenium have created a class SeleneseTestCase that extends TestCase of JUnit, and this class is giving you some selenium-utilities which can be nice to have. I decided to create my tests extending the SeleneseTestCase, but you don’t have to – you can extend TestCase directly. Also, to avoid having to specify the setup() and tearDown() method in all my test-cases I created an abstract class called DefaultTest which I would extend for my test-cases. The DefaultTest has this definition:

public abstract class DefaultTest extends SeleneseTestCase
	protected Selenium browser;
	public static final String DEFAULT_TIMEOUT = "20000";
	public static final String BROWSER_FIREFOX = "*firefox";
	public static final String BROWSER_CHROME = "*chrome";
	public static final String BROWSER_IE = "*iexplore";
	public void setUp() throws Exception
		browser = new DefaultSelenium("localhost", 6666, BROWSER_CHROME, "http://localhost/Test/");

	public void tearDown() throws Exception

To create the “virtual” browser object in Selenium you need to specify the server-host, which port to use, which browser to simulate and so on. I’m doing my tests against a local jboss-server running on port 8080. Note that jboss uses the default port of Selenium (4444), so I specified 6666 for my selenium server to run.

To be able to simulate a user typing something or pressing links, it’s obvious that we in the java-code need some way of locating the different web-elements. In Selenium this is referred to as “locators,” in java you specify them as String objects. You can locate an element in different ways, I mention some of them here:

  • By id: String locator = “id=theIdOfMyComponent”;
  • By name: String locator = “name=theNameOfMyComponent”;
  • By xpath: String locator = “xpath=//table[@id=’myTable’]/tbody/tr/td[2]/span/a”;
  • By link content: String locator = “link=ClickMe”;
  • By table-cell-refernce (TableId.Row.Cell): String locator = “myTable.1.0”;
  • By DOM: String locator = “dom=document.forms[‘myForm’].myElement”;

To start with something simple, we can try a TestCase for logging on to an application. As a convention to follow all the methods in your test-cases should start with “test”, like testLogin():

public class LoginTestCase extends DefaultTest
	public final void testLogin()
		String userNameLocator = "name=username";
		String passwordLocator = "name=password";
		String componentLocator = "id=idOfTheComponentIExpectToBeThereAfterSuccessfullyLoggingIn";"http://localhost:8080/MyWebbAppContextRoot/");
		browser.type(userNameLocator, "myUsername");
		browser.type(passwordLocator, "myPassword");"id=submitButton");
		assertEquals("The title I expect", browser.getTitle());

You run the test by right-clicking the class (run all tests in the class) or individually on each method -> select Run As -> select JUnitTest. Of course this can also be done from an ant task.

The specifies the initial page that should be loaded in the browser. Then you can see that we fill in a value for the username and password, and click a button. Whenever there is a click that requires a page reload, you have to follow that command by a “browser.waitForPageToLoad()”. I set my standard timeout to 20 sec (20000ms), but if the response is sent earlier the browser acts upon it immediately. Then we do an assertion on the title of the page we were sent to, as well as an assertion to check that an expected component on this page actually exist. So, this is a testCase that tests for a successful logon. Another test that could be done is for example to pass invalid username/password, to see that unsuccessful logons are handled correctly.

Testing your webapp like this is integration testing, not unit testing. It is therefore likely that to be able to do your test you need to other actions first, like you follow a chain of commands; you might have to log on, maybe click a link to go on the proper page, or you need to do some other actions before you can do your assertions. Thus, I created some static methods in a utility-class that handles the most common operations, so that I can reuse those from my TestCases. Consider a class like this:

public class InteractionUtil extends DefaultTest
	public static void login(Selenium browser)
		String userNameLocator = "name=username";
		String passwordLocator = "name=password";"http://localhost:8080/MyWebbAppContextRoot/");
		browser.type(userNameLocator, "myUsername");
		browser.type(passwordLocator, "myPassword");"id=submitButton");

Then, my testLogin() method would simply be like this:

	public final void testLogin()
		String componentLocator = "id=idOfTheComponentIExpectToBeThereAfterSuccessfullyLoggingIn";
		assertEquals("The title I expect", browser.getTitle());

And it is very easy to also include this logon-action in other testCases where it is needed. All actions you need to do often can go into such a utility-class.

As a final example I will show how to use the JsCookMenu of tomahawk library from Selenium. I struggled quite a bit with this one before I was able to make the action trigger. Since triggering an element in a dropdown-menu like this can be considered a “generic” action I include it in my utility-class:

	public static void clickJsCookMenu(Selenium browser, String theme, String jsCookId, String itemValue)
		String fieldRowLocator = "xpath=//div[@id='"+jsCookId+"']/div/table/tbody/tr[@class='"+theme+"MenuItem' and td = '"+itemValue+"']";
		String jsCookMenuTdLocator = "xpath=//div[@id='"+jsCookId+"']/table/tbody/tr/td[@class='"+theme+"MainItem']";
		String fieldRowHoverLocator = "xpath=//div[@id='"+jsCookId+"']/div/table/tbody/tr[@class='"+theme+"MenuItemHover']";
		String fieldRowActiveLocator = "xpath=//div[@id='"+jsCookId+"']/div/table/tbody/tr[@class='"+theme+"MenuItemActive']";
		browser.waitForCondition("selenium.isVisible(\""+ fieldRowLocator+"\");", DEFAULT_TIMEOUT);

To explain a bit, I pass as parameters the browser object, the jsCook theme being used (office, ie and so on), the id I’ve given the jscookMenu component in my jsp and the value/text of the item I want to click. I first do a mouseOver to display the menu, and notice the “waitForCondition” command that follows. This means that the browser should wait for the menu to be visible. Then i figured out I needed to do a mouse-over on the row holding the item. This makes the css class change, so I do mouseDown on the “hovered” row. But the mouseDown-event in the jsCook javascript doesn’t trigger the link, actually a mouseUp does, so finally I do a mouseUp-event on the active row. And of course I then wait for the page to reload.

Then from my test-method I can simply do:

	public void testJsCookMenu()
		UserInteractionUtil.clickJsCookMenu(browser, "ThemeIE", "myJsCookId", "theElementIWantToClick");
		//--- assertions ---

I hope this post will give you a brief understanding on how to use Selenium for testing your webapps!


6 Responses to “Using Selenium to test JSF (myFaces impl) application”

  1. nanao Says:

    i’m having problem trying to click on a hidden link that is only visible when mouse is hover over it. how can i click on this link via selenium? many thanks.

    html code of page:

    var sensorListForm__idJsp26_menu =
    [[”, ‘Sensorpoint Actions’, null, ‘sensorListForm’, null,[”, ‘Add New Sensorpoint’, ‘sensorListForm__idJsp26_menu:A]#{BinaryCRUD.initSensor}’, ‘sensorListForm’, null],
    [”, ‘Delete Selected’, ‘sensorListForm__idJsp26_menu:A]#{BinaryCRUD.deleteFromList}’, ‘sensorListForm’, null]]];

    • roneiv Says:


      Do you mean that the link has a style which is set to visibility: hidden? In that case it’s still a part of the dom, and it should be possible to get it with the selenium-parser, maybe using xpath? But if the link is set to display:none, then it’s not possible to get it I guess.



  2. Sanjeev Says:

    Hi Eivind,

    First of all, thank you soo much for a very detailed blog on junit and selenium integration.

    Have you had any success with running these selenium tests in headless mode as part of a continuous build system?


    • roneiv Says:

      Hi Sanjeev,

      Thanks for positive feedback. When it comes to your question about running these tests as part of a continous build system – I have merely used this for integration testing and have not spent much time in trying to use this together with a build system. Lack of time and other priorities set a stop for that part, however, this is something I would really like to dive into – when I get a chance to do it 😉

      Thanks for your interest in my post anyway!



  3. youandnaveen Says:


    I am Naveen.I had learnt ,how to run selenium IDE & selenium RC.The main thing is how to generate a Test Report after the running the test Succesfully.I am using the Selenium RC and NUNIT for the testing .How to get the Test actions and descriptions in a Report.And another thing is How to run Selenium Core and when it is useful .And suggest some more open source tools for testing .Net and Java Projects ………………………..

    Try to help me…..


  4. el_harrathi Says:

    thanks for the blog,it’s so useful.
    i’m testing a JSF application with Selenium ans i have a great problem with pagination.Selemnium IDE can’t locate any element in the paginate bar but the first element i click on.if i locate the element by myself and i run the test, Selenium fail.have you any idea how to resolve this?

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your 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

%d bloggers like this: