Hier wird ein Weg gezeigt wie der Browser, den Selenium z.B. während einer cucumber-Session öffnet headless in einem virtuellen Framebuffer ausführbar wird. Auf der Entwicklungsmaschine wäre das nicht unbedingt nötig, aber wenn das Ganze in der CI auf einem Stagingserver läuft, geht’s wohl nicht anders.
Man startet zuerst den Xvfb-Server – hier auf Display Nummer 99 – der das virtuelle Gerät bereitstellt. Dann sorgt man dafür, dass X-Clients wie der Firefox dieses Display auch nutzen und ab geht’s:
Xvfb-Server starten:
Bei mir auf einer Ubuntu 8.04-Maschine in /etc/rc.local:
export PATH=/opt/ruby-enterprise/bin:/usr/local/sbin:
/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export DISPLAY=:99
su - -c 'nohup startx -- `which Xvfb` :99 -screen 0 1680x1024x24 &' www-data
su - -c '/opt/ruby-enterprise/bin/thin -C /var/www/integrity/thin.yml
-R /var/www/integrity/config.ru start' www-data
(Nebenbei: auf Osx Leopard musste ich explizit /usr/X11R6/bin/Xvfb :99 -screen 0 1680x1024x24 & benutzen, weil sonst der Xvfb aus der port-Installation gestartet wurde und dieser beharrlich die fixed-fonts nicht findet. Das oben beschriebene Verfahren funktioniert allerdings trotzdem nicht auf dem Mac, da der Firefox keine X11-Anwendung ist und daher nicht den Xvfb nutzt.)
thin-Konfiguration:
Ich habe dem Testserver eine eigene IP verpasst und starte einen thin-Server unter einer unprivilegierten Portnummer (8910). Der Versuch, die Konfiguration im Apache mit Passenger/ruby-Enterprise zum Laufen zu bringen schlug leider fehl, da aus unklaren Gründen keine Browserinstanz im virtuellen Framebuffer hochfahren wollte.
Hier also die thin-Konfiguration. Sie wird auf Wunsch von integrity erzeugt. /var/www/integrity/thin.yml:
--- environment: production chdir: /var/www/integrity address: 10.10.1.180 port: 8910 pid: /var/www/integrity/thin.pid rackup: /var/www/integrity/config.ru log: /var/www/integrity/log/thin.log max_conns: 1024 timeout: 30 max_persistent_conns: 512 daemonize: true servers: 1
Bildschirmfotos grabben
Wer dem Unsichtbaren nicht traut, kann zwischendurch einen Screenshot vom Xvfb grabben:
DISPLAY=:99 import -window root /var/www/integrity/public/screenshot.png
Wenn man dies geschickt in seine cucumber-Steps einbaut, gibt’s einen Screenshot bei Beendigung des Tests (und vor allem nach dem letzten Fehler) gratis. Hier wird zu Diagnosezwecken gleich noch ein Datenbankdump angehängt:
1 2 3 4 5 6 |
After do system("import -window root /home/www-data/Desktop/snap_#{Time.now.strftime '%y%m%d_%H%M%S'}.png") system("mysqldump -upplpool -pp4ssw0rd pplpool_test > /home/www-data/Desktop/ dump_#{Time.now.strftime '%y%m%d_%H%M%S'}.sql") end |
ein neuer rake-Task
Für die CI in integrity (siehe letzter Blogeintrag) habe ich den aufrufenden rake-Task etwas geändert:
1 2 3 4 5 6 7 8 9 10 |
desc "Execute cucumber features in integrity" task :integrity do require 'ftools' File.move(RAILS_ROOT+"/config/database.yml.test", RAILS_ROOT+"/config/database.yml") File.move(RAILS_ROOT+"/config/ldap.yml.test", RAILS_ROOT+"/config/ldap.yml") ENV["DISPLAY"] = ":99" res = `cucumber -p enhanced features/enhanced`.split("\n") puts res.join("\n") raise if res.grep(/^\d+ failed step/).size != 0 end |
geänderter git-Hook für Port 8910
Abschließend habe ich noch den Hook im aufrufenden git-Repo verändert, um der neuen Portnummer Rechnung zu tragen:
wget -q --post-data="" integrity.int.bm.net:8910/marsxpress/builds -O- >/dev/null