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
$ sudo apt-get install firefox

Testing Firefox
$ echo $DISPLAY
localhost:10.0
$ firefox
view raw test_firefox.sh hosted with ❤ by GitHub
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
$ sudo apt-get install xvfb
...Lots of stuff...
view raw install_xvfb.sh hosted with ❤ by GitHub

Testing Firefox again
$ sudo apt-get install imagemagick
$ Xvfb :1 &
$ export DISPLAY=:1
$ firefox http://google.com
...from another terminal...
$ export DISPLAY=:1
$ import -window root example.png
...from another terminal...
$ killall firefox
$ firefox example.png
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
/usr/bin/Xvfb :1 &
view raw xvfb.sh hosted with ❤ by GitHub
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:
module Foo
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def bar
end
end
def baz
end
end
class Test
include Foo
end
Test.bar # class method
Test.new.bar # No method error
Test.baz # No method error
Test.new.baz # Instance method
view raw include.rb hosted with ❤ by GitHub


"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'".