Install xvfbwrapper
masterInstall the xvfbwrapper package via PyPI using pip.
pip install xvfbwrapperrepository·master·Indexed 18 days ago
https://github.com/cgoldberg/xvfbwrapperA Python library for controlling X11 virtual displays using Xvfb (X virtual framebuffer), allowing GUI applications to run on headless systems by simulating a display in memory. It supports usage as a context manager, custom display geometry, and integration with Selenium WebDriver tests.
Install the xvfbwrapper package via PyPI using pip.
pip install xvfbwrapperBefore using xvfbwrapper, ensure your system meets the following requirements:
sudo apt-get install xvfb on Debian/Ubuntu or yum install xorg-x11-server-Xvfb on RHEL/CentOS).fcntl system call (standard on non-Windows systems).The recommended way to use Xvfb is as a context manager. This ensures that the virtual display is automatically stopped when the block completes, preventing leftover junk files in /tmp if errors occur.
from xvfbwrapper import Xvfb
with Xvfb():
# launch stuff inside virtual display here
# (Xvfb will stop when this block completes)You can use xvfbwrapper to run Selenium tests headlessly by starting an Xvfb instance in your test setup and ensuring it is stopped during cleanup.
import unittest
from selenium import webdriver
from xvfbwrapper import Xvfb
class TestPage(unittest.TestCase):
def setUp(self):
# Force X11 to avoid Wayland conflicts
self.xvfb = Xvfb(set_xdg_session_type=True)
self.xvfb.start()
self.driver = webdriver.Chrome()
# Ensure cleanup happens even if test fails
self.addCleanup(self.xvfb.stop)
self.addCleanup(self.driver.quit)
def test_selenium_homepage(self):
self.driver.get("https://www.selenium.dev")
self.assertIn("Selenium", self.driver.title)
if __name__ == "__main__":
unittest.main()If you cannot use a context manager, always wrap your Xvfb usage in a try/finally block to ensure xvfb.stop() is called even if an exception is raised.
from xvfbwrapper import Xvfb
xvfb = Xvfb()
xvfb.start()
try:
# launch stuff inside virtual display here
finally:
xvfb.stop()When running in a Wayland session, GUI toolkits might attempt to use Wayland instead of X11. Setting set_xdg_session_type=True forces XDG_SESSION_TYPE=x11 in the current Python process and all child processes, ensuring they connect to the Xvfb display.
from xvfbwrapper import Xvfb
xvfb = Xvfb(set_xdg_session_type=True)
xvfb.start()You can specify the resolution (width and height) and the specific display number when initializing the Xvfb class.
from xvfbwrapper import Xvfb
# Set resolution to 1280x720
xvfb = Xvfb(width=1280, height=720)
xvfb.start()
# Set specific display number (e.g., :23)
xvfb = Xvfb(display=23)
xvfb.start()You can pass arguments to the underlying Xvfb executable in two ways:
-parameter pattern (e.g., -nolisten tcp), pass them as keyword arguments.+, or arguments with parameters), pass a sequence of strings to the extra_args parameter.from xvfbwrapper import Xvfb
# Using keyword arguments for -parameter style
xvfb = Xvfb(nolisten="tcp")
xvfb.start()
# Using extra_args for complex or non-standard arguments
xvfb = Xvfb(extra_args=("ttyxx", "-nocursor", "+extension", "RANDR"))
xvfb.start()To run multiple Xvfb displays simultaneously in different threads or processes, use the environ keyword. This provides process/thread isolation. When initializing, use os.environ.copy() to ensure each instance gets its own environment dictionary.
import os
from xvfbwrapper import Xvfb
isolated_environment1 = os.environ.copy()
xvfb1 = Xvfb(environ=isolated_environment1)
xvfb1.start()
isolated_environment2 = os.environ.copy()
xvfb2 = Xvfb(environ=isolated_environment2)
xvfb2.start()
try:
# launch stuff inside virtual displays here
finally:
xvfb1.stop()
xvfb2.stop()