Selenium Server without X Window System - xvfb
For my acceptance tests configured in Jenkins I wanted to omit installing of any kind of X Window System. That’s pretty obvious when there is not enough RAM or we have to pay for every megs of it. But how a real browser like Firefox or Chrome would run without X servers? The answer is: X virtual buffer.
Let’s configure Selenium Server on top of xvfb on Ubuntu.
xvfb?
To run acceptance web tests on server you don’t need to install desktop environment like Gnome or XFCE just to launch a browser. Better to use Virtual Framebuffer for running Selenium tests without displaying on real screen.
virtual buffer is a graphics buffer kept in memory. It probably won’t be accelerated by graphics card but we can look into it in real time on another computer.
Install xvfb
Open your terminal and type few things:
sudo apt-get install xvfb
sudo nano /etc/init.d/xvfb # paste code from SNIPPET BELOW
sudo chmod +x /etc/init.d/xvfb # make it executable
sudo /etc/init.d/xvfb start # start xvfb
sudo update-rc.d xvfb defaults # add to auto-run
sudo sh -c "echo 'DISPLAY=\":1\"' >> /etc/environment" # env for apps
Here’s the script that will be auto-started with machine. Default X servers run on DISPLAY number 0, so we’ll avoid future conflict. This runs xvfb on DISPLAY number 1:
### BEGIN INIT INFO
# Provides: Xvfb
# Required-Start: $local_fs $remote_fs
# Required-Stop:
# X-Start-Before:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Loads X Virtual Frame Buffer
### END INIT INFO
XVFB=/usr/bin/Xvfb
XVFBARGS=":1 -screen 0 1280x1024x24 -ac +extension GLX +render -noreset"
PIDFILE=/var/run/xvfb.pid
case "$1" in
start)
echo -n "Starting virtual X frame buffer: Xvfb"
start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile --background --exec $XVFB -- $XVFBARGS
echo "."
;;
stop)
echo -n "Stopping virtual X frame buffer: Xvfb"
start-stop-daemon --stop --quiet --pidfile $PIDFILE
echo "."
;;
restart)
$0 stop
$0 start
;;
*)
echo "Usage: /etc/init.d/xvfb {start|stop|restart}"
exit 1
esac
exit 0
Browser
Selenium by default works with Firefox, that’s why I chosed this browser.
But hold your horses. One can’t simply install Firefox. Latest versions don’t work due to problems with dbus-launch. FirefoxDriver built into Selenium is now obsolete so it’s recommended to start using Marionette WebDriver.
The other way is to simply install older version of the browser.
To me, Firefox 40.0.3 seems to work properly, some sources note that 41.0 is the greatest version supporting Selenium. Download some version for your system from Mozilla Firefox builds on SourceForge.
Install it using dkpg:
sudo dpkg -i firefox-mozilla-build_40.0.3-0ubuntu1_amd64.deb
To make sure that your Ubuntu won’t update Firefox hold the installed version:
sudo apt-mark hold firefox
Selenium
You need Java installed.
Download “Selenium Standalone Server” from http://www.seleniumhq.org/download/ To simply run it call: export DISPLAY=":1" && ava -jar selenium-server-standalone-2.53.1.jar .
It would be nice to have it launched when operating system starts:
sudo nano /etc/init.d/selenium
# → paste script from SNIPPET BELOW, save and close file
sudo chmod 755 /etc/init.d/selenium
sudo mkdir -p /var/log/selenium
sudo chmod a+w /var/log/selenium/
sudo /etc/init.d/selenium start
sudo update-rc.d selenium defaults
And here’s the script that starts/stops Selenium:
#!/bin/bash
case "${1:-''}" in
'start')
if test -f /tmp/selenium.pid
then
echo "Selenium is already running."
else
java -jar /usr/lib/selenium/selenium-server-standalone-2.53.1.jar -port 4444 > /var/log/selenium/selenium-output.log 2> /var/log/selenium/selenium-error.log & echo $! > /tmp/selenium.pid
echo "Starting Selenium..."
error=$?
if test $error -gt 0
then
echo "${bon}Error $error! Couldn't start Selenium!${boff}"
fi
fi
;;
'stop')
if test -f /tmp/selenium.pid
then
echo "Stopping Selenium..."
PID=`cat /tmp/selenium.pid`
kill -3 $PID
if kill -9 $PID ;
then
sleep 2
test -f /tmp/selenium.pid && rm -f /tmp/selenium.pid
else
echo "Selenium could not be stopped..."
fi
else
echo "Selenium is not running."
fi
;;
'restart')
if test -f /tmp/selenium.pid
then
kill -HUP `cat /tmp/selenium.pid`
test -f /tmp/selenium.pid && rm -f /tmp/selenium.pid
sleep 1
java -jar /usr/lib/selenium/selenium-server-standalone-2.53.1.jar -port 4444 > /var/log/selenium/selenium-output.log 2> /var/log/selenium/selenium-error.log & echo $! > /tmp/selenium.pid
echo "Reload Selenium..."
else
echo "Selenium isn't running..."
fi
;;
*) # no parameter specified
echo "Usage: $SELF start|stop|restart|reload|force-reload|status"
exit 1
;;
esac
Now, to manually restart Selenium from terminal you simply type:
sudo /etc/init.d/selenium restart
Bonus! See acceptance tests at real time
To achieve this we will use VNC.
apt install x11vnc
sudo x11vnc -display :1 -forever -shared -loop -noxdamage -repeat -rfbport 5900
Now, you can log in using some VNC client/viewer. For Windows, TightVNC Viewer works well.
The hidden benefit here is that we can look into the console under development tools in the browser.
Summary
Acceptance tests are best to be performed in real browsers. Some poeple use headless browsers like PhantomJS, however this approach increses some risk of seeing false positives or having issues with stopped development of these.
Now, go write your tests with some Selenium Driver in your favorite testing framework and feel happy of automated tests with saved memory.
References
- Acceptance Tests with Codeception
- Selenium
- Jenkins
- Wiki: X Window System
- Wiki: X Virtual FrameBuffer (xvfb)
- Wiki: VNC
- Marionette WebDriver
- Mozilla Firefox builds on SourceForge
- Dan Straw: Installing Selenium server 2 as a service on Ubuntu
- https://gist.github.com/dloman/8303932
- https://github.com/SeleniumHQ/selenium/issues/1862