101

I'm on EC2 instance. So there is no GUI.

$pip install selenium
$sudo apt-get install firefox xvfb

Then I do this:

$Xvfb :1 -screen 0 1024x768x24 2>&1 >/dev/null &

$DISPLAY=:1 java -jar selenium-server-standalone-2.0b3.jar
05:08:31.227 INFO - Java: Sun Microsystems Inc. 19.0-b09
05:08:31.229 INFO - OS: Linux 2.6.32-305-ec2 i386
05:08:31.233 INFO - v2.0 [b3], with Core v2.0 [b3]
05:08:32.121 INFO - RemoteWebDriver instances should connect to: http://127.0.0.1:4444/wd/hub
05:08:32.122 INFO - Version Jetty/5.1.x
05:08:32.123 INFO - Started HttpContext[/selenium-server/driver,/selenium-server/driver]
05:08:32.124 INFO - Started HttpContext[/selenium-server,/selenium-server]
05:08:32.124 INFO - Started HttpContext[/,/]
05:08:32.291 INFO - Started org.openqa.jetty.jetty.servlet.ServletHandler@1186fab
05:08:32.292 INFO - Started HttpContext[/wd,/wd]
05:08:32.295 INFO - Started SocketListener on 0.0.0.0:4444
05:08:32.295 INFO - Started org.openqa.jetty.jetty.Server@1ffb8dc

Great, everything should work now, right?

When I run my code:

from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.keys import Keys

browser = webdriver.Firefox() 
browser.get("http://www.yahoo.com") 

I get this:

Error: cannot open display: :0
2
  • 4
    If you're on a system without X running, display :0 should be available. Try running Xvfb :0 -- also see xvfb-run as mentioned by @ema
    – fijiaaron
    Commented Oct 25, 2012 at 12:48
  • 1
    For future followers, I described my solution for Ubuntu Server: namekdev.net/2016/08/…
    – Namek
    Commented Aug 5, 2016 at 11:11

6 Answers 6

186

You can use PyVirtualDisplay (a Python wrapper for Xvfb) to run headless WebDriver tests.

#!/usr/bin/env python

from pyvirtualdisplay import Display
from selenium import webdriver

display = Display(visible=0, size=(800, 600))
display.start()

# now Firefox will run in a virtual display. 
# you will not see the browser.
browser = webdriver.Firefox()
browser.get('http://www.google.com')
print browser.title
browser.quit()

display.stop()

more info


You can also use xvfbwrapper, which is a similar module (but has no external dependencies):

from xvfbwrapper import Xvfb

vdisplay = Xvfb()
vdisplay.start()

# launch stuff inside virtual display here

vdisplay.stop()

or better yet, use it as a context manager:

from xvfbwrapper import Xvfb

with Xvfb() as xvfb:
    # launch stuff inside virtual display here.
    # It starts/stops in this code block.
5
  • 2
    @Andrei OSX doesn't use X11 by default Commented Jul 21, 2012 at 19:50
  • Used this answer to make it work with vagrant + PyCharm + Django on OS X: stackoverflow.com/q/29343109
    – chachan
    Commented Mar 30, 2015 at 10:44
  • I get a "browser appears to have exited" when I implement the pyvirtualdisplay code above
    – gtownrower
    Commented Jun 25, 2017 at 17:17
  • Message: Service /usr/lib64/chromium-browser/chromium-browser unexpectedly exited. Status code was: 1
    – Haozhe Xie
    Commented Jan 28, 2024 at 15:33
  • The code with pyvirtualdisplay does not work, it gets stuck without any error. However the one with xvfbwrapper does the job.
    – Matteo
    Commented Dec 11, 2024 at 16:01
46

The easiest way is probably to use xvfb-run:

DISPLAY=:1 xvfb-run java -jar selenium-server-standalone-2.0b3.jar

xvfb-run does the whole X authority dance for you, give it a try!

2
  • This is just what I was looking for. Starting Xvfb on its own didn't seem to work for me, but using xvfb-run did the trick. Thanks. Commented Aug 29, 2013 at 20:58
  • 11
    The DISPLAY=:1 is unnecessary; xvfb-run sets the DISPLAY environment variable to something else (usually :99) before starting the specified command (in your case, java -jar selenium-server...)
    – Alex Dupuy
    Commented Nov 13, 2014 at 15:36
37

open a terminal and run this command xhost +. This commands needs to be run every time you restart your machine. If everything works fine may be you can add this to startup commands

Also make sure in your /etc/environment file there is a line

export DISPLAY=:0.0 

And then, run your tests to see if your issue is resolved.

All please note the comment from sardathrion below before using this.

4
  • You just need to execute java -jar selenium-server-standalone-2.0b3.jar from command line and then run your tests
    – A.J
    Commented May 31, 2011 at 5:35
  • I'm on an EC2 instance, so there is no GUI. xhost: unable to open display ":0.0"
    – TIMEX
    Commented May 31, 2011 at 5:38
  • @owa You also need the DISPLAY environment variable in the client environment.
    – Keith
    Commented May 31, 2011 at 11:13
  • 10
    xhost + is insecure. Please do not use it. If you have to use xhost, add the specific machine you want and not + (aka everything whatsoever). Commented Jan 18, 2013 at 10:23
22

This is the setup I use:

Before running the tests, execute:

export DISPLAY=:99
/etc/init.d/xvfb start

And after the tests:

/etc/init.d/xvfb stop

The init.d file I use looks like this:

#!/bin/bash

XVFB=/usr/bin/Xvfb
XVFBARGS="$DISPLAY -ac -screen 0 1024x768x16"
PIDFILE=${HOME}/xvfb_${DISPLAY:1}.pid
case "$1" in
  start)
    echo -n "Starting virtual X frame buffer: Xvfb"
    /sbin/start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile --background --exec $XVFB -- $XVFBARGS
    echo "."
    ;;
  stop)
    echo -n "Stopping virtual X frame buffer: Xvfb"
    /sbin/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
2
  • I did exactly this and then ran my script. However, I still get this: Error: cannot open display: :0. Also, do I need to run the selenium java server? It seems like it doesn't matter if I run it or not...
    – TIMEX
    Commented May 31, 2011 at 21:11
  • 2
    owalla, if you use WebDriver, then you don't need the Selenium Java Server. Commented Jun 10, 2011 at 0:11
4

If you use Maven, you can use xvfb-maven-plugin to start xvfb before tests, run them using related DISPLAY environment variable, and stop xvfb after all.

2

The proper way is:

xvfb-run python ./selenium-script.py

No need to add:

from pyvirtualdisplay import Display
display = Display(visible=0, size=(800, 600))
display.start()
display.stop()

But now, with Selenium WebDriver, there's no need to run also xvfb anymore (see the explanation why).

0

Not the answer you're looking for? Browse other questions tagged or ask your own question.