On a recent project we developed a comprehensive set of acceptance tests driven by Selenium RC. The UI acceptance tests were written using JUnit which meant we could easily run them as single tests directly from our IDE. In addition, because our build and deploy processes were driven entirely by ant, it made sence to use an ant task to run the acceptance tests too, and this was where I ran into a annoying little problem with Selenium RC on Linux.
The problem
When tests are executed a browser window will automatically open and close during setup and tear down of each JUnit test. When there are a large set of tests that take more than a few minutes to run, the opening and closing of the browser window can be very distracting!
On my Ubuntu Linux desktop whenever I ran a build in the background I was distracted by the browser window popping up and taking focus away from where I was working. Developers that used Mac's didn't have this problem because on a Mac the browser window opens in the background and doesn't take focus from the active window.
The solution
My solution was to run the Selenium RC server in a different virtual display. A side effect of this solution was that we could also easily run builds on headless servers too, which meant it integrated well with our cruise control continuous integration environment.
Initially there were 2 ant tasks used to run the selenium tests; "selenium-start" to start the Selenium RC server so it's available to run the tests, and then a JUnit task to run the tests. I added the following ant task to create a virtual display:
<target name="xserver-start" description="Start a virtual X-server to run visual targets on a headless machine."> <exec executable="vncserver" os="Linux" failifexecutionfails="false" failonerror="false" resultproperty="xserver.running"> <arg value="${virtual.display}"/> </exec> <echo message="Starting vncserver using display ${virtual.display} result was ${xserver.running}"/> <condition property="displayToUse" value="${virtual.display}" else=":0"> <or> <equals arg1="${xserver.running}" arg2="0"/> <equals arg1="${xserver.running}" arg2="98"/> </or> </condition> <echo message="X-server is running on display ${displayToUse}"/> </target>
I've used an ant property (virtual.display=:5) to control which display number should be used. Next, I changed the way the selenium server is started by setting the environment variable DISPLAY=:5. Once the display has been set, all future x-window commands are targeted at this new virtual diaply instead of the main display, which normally runs as :0 (zero).
<target name="selenium-start" depends="xserver-start" description="Start the Selenium RC server on port 4444."> <java jar="${dir.lib.acceptance}/selenium-server.jar" spawn="true" fork="true"> <arg value="-log"/> <arg value="${dir.deploy}/logs/selenium.log"/> <env key="DISPLAY" value="${displayToUse}" /> <env key="TZ" value="/usr/share/zoneinfo/GB"/> </java> </target>
When selenium starts firefox, the browser will now be displayed on virtual display :5 and can be viewed using the vncviewer :5 command.
The final change I made was to stop the virtual display when the selenium server was stopped.
<target name="selenium-stop" description="Stop the Selenium RC server on port 4444."> <get taskname="selenium-shutdown" src="http://localhost:4444/selenium-server/driver/?cmd=shutDown" dest="${dir.deploy}/logs/selenium-server-shutdown.txt" ignoreerrors="true" /> <antcall target="xserver-stop" /> </target> <target name="xserver-stop" description="Stop the X-server if it's running."> <echo message="Stopping X-server on display ${displayToUse}"/> <exec executable="vncserver" os="Linux" failifexecutionfails="false" failonerror="false"> <arg value="-kill"/> <arg value="${displayToUse}"/> </exec> </target>
This solution requires vncserver to be installed. sudo apt-get install vncserver should do the trick on debian.


