Headless Selenium+Firefox+Xvfb stack (on Gentoo CI server)

Headless Selenium+Firefox+Xvfb stack (on Gentoo CI server)

12 Jun 2010 – Warsaw

The background

There’s this app we’re doing at Aenima that has a pretty large test suite. It’s nothing to brag about in the Ruby community, but here’s the problem: there are a few things covered with Selenium tests (that is, Cucumber tests ran in Selenium environment). Only the Javascript stuff that we cannot otherwise tests, as we’re not big fans of C{u|e}lerity. These Selenium-driven scenarios run great on our development boxes, but recently we have set up Integrity (actually Strzałek did it) on our internal development server for some Continuous Integration goodness.

Having Continuous Integration was a must: the test suite grew so large that a complete run (RSpec + Cucumber) takes from 20 to 40 minutes on our laptops, so it was natural that the frequency of running full test suite dropped considerably within the team, which of course increases the risk of regressions.

Anyway, the dev/CI server is of course headless, no display nor X, so for some time the Cucumber tests were ran with -selenium parameter, but we all knew it was a temporary workaround (I can’t even call that a “solution”). The CI server had to get a running Firefox-Selenium stack.

It was a natural choice to go with Xvfb, the only problem remaining was setting it up and building the rest of the stack on top of it. The man responsible for administration of the dev server, Imanel, has installed Gentoo on it (despite being a Gentoo-fanboy he’s a great guy). Something I can sympathize with, considering my (and not only mine) experience with Ubuntu Server. But still if something can be done in a simple way on most of the distros, it probably cannot be done simply in Gentoo.

Installing Xvfb on Gentoo

Xvfb is basically a part of Xorg system and installing it on a display-less server is something like “installing X without X”. For that I needed some ebuild and USE-flag magic. I’ve copied (with a slight version bump to avoid collision) the latest Xorg ebuild from portage directory that was considered stable on x86, xorg-server-1.7.6.ebuild

mkdir -p /usr/local/portage/x11-base/xorg-server/
cp /usr/portage/x11-base/xorg-server/xorg-server-1.7.6.ebuild /usr/local/portage/x11-base/xorg-server/xorg-server-1.7.6.1.ebuild

And here are two lines the ebuild I had to change (coming from this thread Gentoo Forums) in unified diff format:

--- /usr/portage/x11-base/xorg-server/xorg-server-1.7.6.ebuild  2010-06-04 16:07:04.000000000 +0200
+++ /usr/local/portage/x11-base/xorg-server/xorg-server-1.7.6.ebuild    2010-06-10 14:13:29.000000000 +0200
@@ -16,7 +16,8 @@
 DESCRIPTION="X.Org X servers"
 KEYWORDS="~alpha amd64 arm hppa ~ia64 ~mips ppc ppc64 ~sh ~sparc x86 ~x86-fbsd"

-IUSE_SERVERS="dmx kdrive xorg"
+# IUSE_SERVERS="dmx kdrive xorg"
+IUSE_SERVERS="dmx kdrive xorg xvfb"
 IUSE="${IUSE_SERVERS} tslib hal ipv6 minimal nptl sdl"
 RDEPEND="hal? ( sys-apps/hal )
        tslib? ( >=x11-libs/tslib-1.0 x11-proto/xcalibrateproto )
@@ -152,7 +153,7 @@
                $(use_enable kdrive)
                $(use_enable tslib)
                $(use_enable tslib xcalibrate)
-               $(use_enable !minimal xvfb)
+               $(use_enable xvfb)
                $(use_enable !minimal xnest)
                $(use_enable !minimal record)
                $(use_enable !minimal xfree86-utils)

And now installing Xvfb-exclusive X was as simple as running

USE="minimal xvfb -xorg" emerge xorg-server

Big thanks to Imanel for reviewing the ebuild, building the digest and making it click.

Running Cucumber-Selenium-Firefox trio under Xvfb

To run Xvfb and have all X-demanding applications run within it, issue these two commands:

nohup Xvfb -ac -screen scrn 1280x2000x24 :2.0 &
export DISPLAY=:2.0

And now everything that needs X — including Firefox — will run seamlessly. There are some scrolling/visibility issues with Selenium, that’s why I’ve allocated a larger vertical size for the Xvfb display.

And… that’s it! Withing the same screen session you can just run your Cucumber tests and see the selenium ones running and passing (preferably!). Xvfb can even let you make some screenshots of Firefox as the Selenium tests are running, but I haven’t set that up yet. I’ll probably be lazy and wait for Hubert to crack this nut.

To make it roll with Integrity, wrap the two lines above in a bash script (not ruby script, as the “&” operand won’t work) and have it ran right before the Cucumber suite itself.

Credit for the idea, inspiration and relevant bash lines goes to Hubert Łępicki, to be more specific — a blog post about setting great Rails test stack

Integrating it with multi-project Integrity

Every project added to Integrity should have its own instance of Xvfb, running on separate display, to avoid collision.

…rest is coming soon.