Namek Dev
a developer's log
NamekDev

Selenium Server without X Window System - xvfb

August 3, 2016
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

web, selenium, linux
comments powered by Disqus