0
# xvfbwrapper
1
2
A Python wrapper for managing X11 virtual displays with Xvfb (X virtual framebuffer). This library enables headless GUI application testing and automation by providing a simple, context-manager-compatible API for starting and stopping virtual displays on headless servers.
3
4
## Package Information
5
6
- **Package Name**: xvfbwrapper
7
- **Language**: Python
8
- **Installation**: `pip install xvfbwrapper`
9
- **Python Requirements**: Python 3.9+
10
- **System Requirements**: Xvfb installation required
11
- Ubuntu/Debian: `sudo apt-get install xvfb`
12
- CentOS/RHEL/Fedora: `sudo yum install xorg-x11-server-Xvfb`
13
- Arch Linux: `sudo pacman -S xorg-server-xvfb`
14
15
## Core Imports
16
17
```python
18
from xvfbwrapper import Xvfb
19
```
20
21
## Basic Usage
22
23
```python
24
from xvfbwrapper import Xvfb
25
26
# Basic usage with manual start/stop
27
xvfb = Xvfb()
28
xvfb.start()
29
try:
30
# Launch applications that require X11 display here
31
# The DISPLAY environment variable is automatically set
32
pass
33
finally:
34
# Always stop to clean up resources
35
xvfb.stop()
36
37
# Context manager usage (recommended)
38
with Xvfb() as xvfb:
39
# Applications run inside virtual display
40
# Automatic cleanup when context exits
41
print(f"Virtual display running on :{xvfb.new_display}")
42
43
# Custom display geometry
44
with Xvfb(width=1280, height=720, colordepth=24) as xvfb:
45
# High-resolution virtual display
46
pass
47
```
48
49
## Architecture
50
51
The package provides a simple wrapper around the Xvfb X11 server:
52
53
- **Xvfb Process Management**: Spawns and manages Xvfb subprocess with proper cleanup
54
- **Display Allocation**: Automatically finds unused display numbers with file-based locking
55
- **Environment Integration**: Manages DISPLAY environment variable for seamless X11 application integration
56
- **Context Manager Protocol**: Provides Python context manager support for automatic resource management
57
58
The design ensures thread-safe multi-display support and robust cleanup even when applications terminate unexpectedly.
59
60
## Capabilities
61
62
### Virtual Display Management
63
64
Creates and manages X11 virtual framebuffer displays for headless applications. Provides automatic display number allocation, environment variable management, and resource cleanup.
65
66
```python { .api }
67
class Xvfb:
68
def __init__(
69
self,
70
width: int = 800,
71
height: int = 680,
72
colordepth: int = 24,
73
tempdir: str | None = None,
74
display: int | None = None,
75
environ: dict | None = None,
76
timeout: int = 10,
77
**kwargs
78
):
79
"""
80
Initialize Xvfb virtual display manager.
81
82
Parameters:
83
- width: Display width in pixels (default: 800)
84
- height: Display height in pixels (default: 680)
85
- colordepth: Color depth in bits (default: 24)
86
- tempdir: Directory for lock files (default: system temp)
87
- display: Specific display number to use (default: auto-allocate)
88
- environ: Environment dict for isolation (default: os.environ)
89
- timeout: Startup timeout in seconds (default: 10)
90
- **kwargs: Additional Xvfb command-line arguments
91
"""
92
```
93
94
### Context Manager Support
95
96
Supports Python context manager protocol for automatic resource management and cleanup.
97
98
```python { .api }
99
def __enter__(self) -> "Xvfb":
100
"""Enter context manager, starts the virtual display."""
101
102
def __exit__(self, exc_type, exc_val, exc_tb):
103
"""Exit context manager, stops the virtual display and cleans up."""
104
```
105
106
### Display Control
107
108
Manual control methods for starting and stopping virtual displays with comprehensive error handling.
109
110
```python { .api }
111
def start(self) -> None:
112
"""
113
Start the virtual display.
114
115
Sets DISPLAY environment variable and spawns Xvfb process.
116
117
Raises:
118
- ValueError: If specified display cannot be locked
119
- RuntimeError: If Xvfb fails to start or display doesn't open within timeout
120
"""
121
122
def stop(self) -> None:
123
"""
124
Stop the virtual display and restore original environment.
125
126
Terminates Xvfb process, restores original DISPLAY variable,
127
and cleans up lock files.
128
"""
129
```
130
131
### Display Properties
132
133
Runtime properties providing information about the virtual display state.
134
135
```python { .api }
136
# Instance Properties
137
width: int # Display width in pixels
138
height: int # Display height in pixels
139
colordepth: int # Color depth in bits
140
new_display: int | None # Assigned display number (available after start())
141
environ: dict # Environment dictionary used
142
proc: subprocess.Popen | None # Xvfb process object (None when stopped)
143
orig_display_var: str | None # Original DISPLAY value (None if unset)
144
145
# Class Constants
146
MAX_DISPLAY: int = 2147483647 # Maximum display number value
147
```
148
149
## Advanced Usage Examples
150
151
### Multithreaded Execution
152
153
For concurrent virtual displays, use isolated environments to prevent interference between threads:
154
155
```python
156
import os
157
from xvfbwrapper import Xvfb
158
159
# Create isolated environments for each display
160
env1 = os.environ.copy()
161
env2 = os.environ.copy()
162
163
xvfb1 = Xvfb(environ=env1)
164
xvfb2 = Xvfb(environ=env2)
165
166
xvfb1.start()
167
xvfb2.start()
168
169
try:
170
# Each display runs in isolation
171
# Use env1 and env2 in your subprocess calls
172
pass
173
finally:
174
xvfb1.stop()
175
xvfb2.stop()
176
```
177
178
### Custom Xvfb Arguments
179
180
Pass additional Xvfb command-line options through keyword arguments:
181
182
```python
183
# Disable TCP listening for security
184
with Xvfb(nolisten="tcp") as xvfb:
185
pass
186
187
# Multiple custom arguments
188
with Xvfb(nolisten="tcp", dpi="96", noreset=None) as xvfb:
189
pass
190
```
191
192
### Selenium WebDriver Integration
193
194
Common pattern for headless browser testing:
195
196
```python
197
import os
198
import unittest
199
from selenium import webdriver
200
from xvfbwrapper import Xvfb
201
202
# Force X11 on Wayland systems
203
os.environ["XDG_SESSION_TYPE"] = "x11"
204
205
class TestWebPages(unittest.TestCase):
206
def setUp(self):
207
self.xvfb = Xvfb()
208
self.addCleanup(self.xvfb.stop)
209
self.xvfb.start()
210
211
self.driver = webdriver.Chrome()
212
self.addCleanup(self.driver.quit)
213
214
def test_page_title(self):
215
self.driver.get("https://example.com")
216
self.assertIn("Example", self.driver.title)
217
```
218
219
## Error Handling
220
221
```python { .api }
222
# Exceptions raised by xvfbwrapper
223
OSError # Xvfb binary not found or unsupported platform
224
ValueError # Specified display number cannot be locked
225
RuntimeError # Xvfb startup failure or timeout
226
```
227
228
### Common Error Scenarios
229
230
- **Missing Xvfb**: Install with `sudo apt-get install xvfb`
231
- **Display locked**: Another process is using the specified display number
232
- **Startup timeout**: Increase timeout parameter or check system resources
233
- **Permission errors**: Ensure write access to temp directory for lock files
234
235
## Platform Support
236
237
- **Supported**: Unix/Linux systems with X11 and Xvfb installed
238
- **Not supported**: Windows, platforms without fcntl module
239
- **Dependencies**: Standard library only (fcntl, subprocess, tempfile, etc.)