Wednesday, November 30, 2011

CI server using Firefox

If you are like me, you always setup a CI to ensure things that you already finished are not broken by things you are currently doing.  And if you are like me, you use capybara, selenium-webdriver, and firefox to actually test the results in a browser.  The rub comes when the CI server (running headless) needs to run firefox, which needs a screen.

Virtual Frame Buffer (xvfb) is a great package.  All it does is provide an X11 interface in memory instead of requiring a screen.  Below I detail what I do on Ubuntu, but it should work the same on any Linux distro.

Installing Firefox

Testing Firefox
Once firefox is installed it can be tested on a X11-forwarded ssh connection.  X11-forwarding has to be enabled on the server and client and can be tested by checking DISPLAY.

Installing Xvfb

Testing Firefox again
The easiest way to test is to use image magick to take a screen shot of the VFB and save it to an image that can be opened in Firefox.  If the image opens and it looks like a firefox browser is running on the google page then you did it correctly.

Create a xvfb startup script
On ubuntu no start script is provided, but a simple one put in /etc/init.d/xvfb is enough.

Getting the CI server to use the VFB
At this point getting a CI server to use Xvfb will depend on how it is started.  If you use the Xvfb startup script then the display is :1.  All you have to do is export DISPLAY=:1 before the CI server starts.

Monday, November 21, 2011

Ruby module instance and class methods

A very common idiom especially when code starts to become complicated is to put functions in modules and mix in that behavior to several classes.  And a common expansion is to have a single "include" add both instance and class methods.

Here is how to do it:


"include" is used to add a module's instance methods as instance methods to the including class, but it doesn't traverse sub modules.  "extend" is used to add a module's instance methods as class methods to a class.

When a module is "included" it can register a callback which is passed the class that is doing the including.  And calling "extend" on the base and passing a submodule will cause it to put those methods at the class level.  This causes a chain reaction of loading both instance and class methods using a single "include".

Pro Tip: It is possible to cause the same behavior using "extend" by using the "extended" callback; however, this is not common and "include 'x'" reads better then "extend 'y'".