xvfbwrapper

repository·master·Indexed 18 days ago

https://github.com/cgoldberg/xvfbwrapper

A 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.

Tokens
1.5K
Snippets
8
Records
9
Agent score
13%

What's inside xvfbwrapper

  1. System Requirements for xvfbwrapper

    master

    Before using xvfbwrapper, ensure your system meets the following requirements:

    • Python: 3.10 or higher.
    • X Window System: Must be installed.
    • Xvfb: The X virtual framebuffer server must be installed on the system (e.g., sudo apt-get install xvfb on Debian/Ubuntu or yum install xorg-x11-server-Xvfb on RHEL/CentOS).
    • OS Features: Support for locking via the fcntl system call (standard on non-Windows systems).
  2. Use Xvfb as a context manager

    master

    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)
  3. Run headless Selenium WebDriver tests

    master

    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()
  4. Use Xvfb with try/finally

    master

    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()
  5. Force X11 backend using set_xdg_session_type

    master

    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()
  6. Configure Xvfb display geometry and number

    master

    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()
  7. Pass custom arguments to Xvfb

    master

    You can pass arguments to the underlying Xvfb executable in two ways:

    1. Keyword Arguments: For arguments that follow the -parameter pattern (e.g., -nolisten tcp), pass them as keyword arguments.
    2. extra_args: For all other argument types (unary, unary with +, 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()
  8. Run multiple isolated Xvfb instances

    master

    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()