xvfbwrapper 0.2.31__tar.gz → 0.2.33__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {xvfbwrapper-0.2.31/xvfbwrapper.egg-info → xvfbwrapper-0.2.33}/PKG-INFO +5 -6
- {xvfbwrapper-0.2.31 → xvfbwrapper-0.2.33}/README.md +4 -5
- {xvfbwrapper-0.2.31 → xvfbwrapper-0.2.33}/pyproject.toml +4 -1
- {xvfbwrapper-0.2.31 → xvfbwrapper-0.2.33}/test_xvfb.py +24 -12
- {xvfbwrapper-0.2.31 → xvfbwrapper-0.2.33}/tox.ini +19 -0
- {xvfbwrapper-0.2.31 → xvfbwrapper-0.2.33/xvfbwrapper.egg-info}/PKG-INFO +5 -6
- {xvfbwrapper-0.2.31 → xvfbwrapper-0.2.33}/xvfbwrapper.py +5 -6
- {xvfbwrapper-0.2.31 → xvfbwrapper-0.2.33}/LICENSE +0 -0
- {xvfbwrapper-0.2.31 → xvfbwrapper-0.2.33}/MANIFEST.in +0 -0
- {xvfbwrapper-0.2.31 → xvfbwrapper-0.2.33}/setup.cfg +0 -0
- {xvfbwrapper-0.2.31 → xvfbwrapper-0.2.33}/xvfbwrapper.egg-info/SOURCES.txt +0 -0
- {xvfbwrapper-0.2.31 → xvfbwrapper-0.2.33}/xvfbwrapper.egg-info/dependency_links.txt +0 -0
- {xvfbwrapper-0.2.31 → xvfbwrapper-0.2.33}/xvfbwrapper.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: xvfbwrapper
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.33
|
|
4
4
|
Summary: Manage headless displays with Xvfb (X virtual framebuffer)
|
|
5
5
|
Author: Corey Goldberg
|
|
6
6
|
Maintainer: Corey Goldberg
|
|
@@ -39,9 +39,8 @@ Dynamic: license-file
|
|
|
39
39
|
|
|
40
40
|
`xvfbwrapper` is a Python library for managing X11 virtual displays with
|
|
41
41
|
[Xvfb (X virtual framebuffer)](https://x.org/releases/X11R7.7/doc/man/man1/Xvfb.1.xhtml),
|
|
42
|
-
a virtual X server that runs without a physical display. It provides the
|
|
43
|
-
|
|
44
|
-
program.
|
|
42
|
+
a virtual X server that runs without a physical display. It provides the `Xvfb` class,
|
|
43
|
+
a Python interface for configuring and controlling the Xvfb program.
|
|
45
44
|
|
|
46
45
|
See the [module API documentation][api-docs] for more information.
|
|
47
46
|
|
|
@@ -245,10 +244,10 @@ finally:
|
|
|
245
244
|
xvfb2.stop()
|
|
246
245
|
```
|
|
247
246
|
|
|
248
|
-
####
|
|
247
|
+
#### Headless browser tests:
|
|
249
248
|
|
|
250
249
|
This uses [`selenium`][selenium-docs] and `xvfbwrapper` to run a test
|
|
251
|
-
on Chrome
|
|
250
|
+
on Chrome inside a headless display.
|
|
252
251
|
|
|
253
252
|
[selenium-docs]: https://www.selenium.dev/selenium/docs/api/py
|
|
254
253
|
|
|
@@ -8,9 +8,8 @@
|
|
|
8
8
|
|
|
9
9
|
`xvfbwrapper` is a Python library for managing X11 virtual displays with
|
|
10
10
|
[Xvfb (X virtual framebuffer)](https://x.org/releases/X11R7.7/doc/man/man1/Xvfb.1.xhtml),
|
|
11
|
-
a virtual X server that runs without a physical display. It provides the
|
|
12
|
-
|
|
13
|
-
program.
|
|
11
|
+
a virtual X server that runs without a physical display. It provides the `Xvfb` class,
|
|
12
|
+
a Python interface for configuring and controlling the Xvfb program.
|
|
14
13
|
|
|
15
14
|
See the [module API documentation][api-docs] for more information.
|
|
16
15
|
|
|
@@ -214,10 +213,10 @@ finally:
|
|
|
214
213
|
xvfb2.stop()
|
|
215
214
|
```
|
|
216
215
|
|
|
217
|
-
####
|
|
216
|
+
#### Headless browser tests:
|
|
218
217
|
|
|
219
218
|
This uses [`selenium`][selenium-docs] and `xvfbwrapper` to run a test
|
|
220
|
-
on Chrome
|
|
219
|
+
on Chrome inside a headless display.
|
|
221
220
|
|
|
222
221
|
[selenium-docs]: https://www.selenium.dev/selenium/docs/api/py
|
|
223
222
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "xvfbwrapper"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.33"
|
|
8
8
|
description = "Manage headless displays with Xvfb (X virtual framebuffer)"
|
|
9
9
|
license = "MIT"
|
|
10
10
|
license-files = ["LICENSE"]
|
|
@@ -40,6 +40,9 @@ download = "https://pypi.org/project/xvfbwrapper"
|
|
|
40
40
|
dev = [
|
|
41
41
|
"tox",
|
|
42
42
|
]
|
|
43
|
+
docs = [
|
|
44
|
+
"pdoc",
|
|
45
|
+
]
|
|
43
46
|
lint = [
|
|
44
47
|
"ruff",
|
|
45
48
|
]
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
"""Tests for xvfbwrapper."""
|
|
6
6
|
|
|
7
7
|
import os
|
|
8
|
+
import re
|
|
8
9
|
import sys
|
|
9
10
|
import tempfile
|
|
10
11
|
import unittest
|
|
@@ -167,17 +168,6 @@ class TestXvfb(XvfbCleanTestCase):
|
|
|
167
168
|
self.assertEqual(orig_display, os.environ["DISPLAY"])
|
|
168
169
|
self.assertIsNone(xvfb.proc)
|
|
169
170
|
|
|
170
|
-
def test_start_multiple_times(self):
|
|
171
|
-
xvfb = Xvfb()
|
|
172
|
-
xvfb.start()
|
|
173
|
-
self.addCleanup(xvfb.stop)
|
|
174
|
-
pid1 = xvfb.proc.pid
|
|
175
|
-
xvfb.stop()
|
|
176
|
-
xvfb.start()
|
|
177
|
-
pid2 = xvfb.proc.pid
|
|
178
|
-
self.assertIsNotNone(xvfb.proc)
|
|
179
|
-
self.assertNotEqual(pid1, pid2)
|
|
180
|
-
|
|
181
171
|
def test_stop_if_not_running_doesnt_raise_error(self):
|
|
182
172
|
xvfb = Xvfb()
|
|
183
173
|
xvfb.stop()
|
|
@@ -269,7 +259,7 @@ class TestXvfb(XvfbCleanTestCase):
|
|
|
269
259
|
self.assertIsNotNone(xvfb.proc)
|
|
270
260
|
with self.assertRaisesRegex(
|
|
271
261
|
RuntimeError,
|
|
272
|
-
f"Could not lock display
|
|
262
|
+
f"Could not lock display: {display_num}",
|
|
273
263
|
):
|
|
274
264
|
xvfb2.start()
|
|
275
265
|
|
|
@@ -319,6 +309,28 @@ class TestXvfb(XvfbCleanTestCase):
|
|
|
319
309
|
xvfb.start()
|
|
320
310
|
self.assertIsNone(xvfb.proc)
|
|
321
311
|
|
|
312
|
+
def test_start_already_running(self):
|
|
313
|
+
xvfb = Xvfb()
|
|
314
|
+
self.addCleanup(xvfb.stop)
|
|
315
|
+
xvfb.start()
|
|
316
|
+
with self.assertRaisesRegex(
|
|
317
|
+
RuntimeError,
|
|
318
|
+
re.escape(f"Xvfb is already running (PID: {xvfb.proc.pid})"),
|
|
319
|
+
):
|
|
320
|
+
xvfb.start()
|
|
321
|
+
self.assertIsNotNone(xvfb.proc)
|
|
322
|
+
|
|
323
|
+
def test_multiple_lifecycles(self):
|
|
324
|
+
xvfb = Xvfb()
|
|
325
|
+
self.addCleanup(xvfb.stop)
|
|
326
|
+
xvfb.start()
|
|
327
|
+
pid1 = xvfb.proc.pid
|
|
328
|
+
xvfb.stop()
|
|
329
|
+
xvfb.start()
|
|
330
|
+
pid2 = xvfb.proc.pid
|
|
331
|
+
self.assertIsNotNone(xvfb.proc)
|
|
332
|
+
self.assertNotEqual(pid1, pid2)
|
|
333
|
+
|
|
322
334
|
def test_get_next_unused_display_does_not_reuse_lock(self):
|
|
323
335
|
xvfb = Xvfb()
|
|
324
336
|
xvfb2 = Xvfb()
|
|
@@ -57,3 +57,22 @@ dependency_groups =
|
|
|
57
57
|
skip_install = true
|
|
58
58
|
commands =
|
|
59
59
|
mypy --install-types --non-interactive {posargs:.}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
[testenv:docs]
|
|
63
|
+
description = build docs
|
|
64
|
+
platform = .*
|
|
65
|
+
allowlist_externals =
|
|
66
|
+
echo
|
|
67
|
+
dependency_groups =
|
|
68
|
+
docs
|
|
69
|
+
commands =
|
|
70
|
+
echo "Cleaning {tox_root}/build/"
|
|
71
|
+
{envpython} -c "import shutil; shutil.rmtree('build', ignore_errors=True)"
|
|
72
|
+
echo "Building docs..."
|
|
73
|
+
{envpython} -m pdoc xvfbwrapper \
|
|
74
|
+
--output-dir build/docs \
|
|
75
|
+
--template-directory docs/pdoc \
|
|
76
|
+
--no-search \
|
|
77
|
+
--docformat markdown
|
|
78
|
+
echo "Docs successfully built: {tox_root}/build/docs/index.html"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: xvfbwrapper
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.33
|
|
4
4
|
Summary: Manage headless displays with Xvfb (X virtual framebuffer)
|
|
5
5
|
Author: Corey Goldberg
|
|
6
6
|
Maintainer: Corey Goldberg
|
|
@@ -39,9 +39,8 @@ Dynamic: license-file
|
|
|
39
39
|
|
|
40
40
|
`xvfbwrapper` is a Python library for managing X11 virtual displays with
|
|
41
41
|
[Xvfb (X virtual framebuffer)](https://x.org/releases/X11R7.7/doc/man/man1/Xvfb.1.xhtml),
|
|
42
|
-
a virtual X server that runs without a physical display. It provides the
|
|
43
|
-
|
|
44
|
-
program.
|
|
42
|
+
a virtual X server that runs without a physical display. It provides the `Xvfb` class,
|
|
43
|
+
a Python interface for configuring and controlling the Xvfb program.
|
|
45
44
|
|
|
46
45
|
See the [module API documentation][api-docs] for more information.
|
|
47
46
|
|
|
@@ -245,10 +244,10 @@ finally:
|
|
|
245
244
|
xvfb2.stop()
|
|
246
245
|
```
|
|
247
246
|
|
|
248
|
-
####
|
|
247
|
+
#### Headless browser tests:
|
|
249
248
|
|
|
250
249
|
This uses [`selenium`][selenium-docs] and `xvfbwrapper` to run a test
|
|
251
|
-
on Chrome
|
|
250
|
+
on Chrome inside a headless display.
|
|
252
251
|
|
|
253
252
|
[selenium-docs]: https://www.selenium.dev/selenium/docs/api/py
|
|
254
253
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# Copyright (c) 2012-2026 Corey Goldberg
|
|
2
2
|
# SPDX-License-Identifier: MIT
|
|
3
3
|
|
|
4
|
-
|
|
5
4
|
"""Manage headless displays with Xvfb (X virtual framebuffer)
|
|
6
5
|
|
|
7
6
|
This module provides a wrapper around Xvfb (X Virtual Framebuffer) for managing
|
|
@@ -102,13 +101,17 @@ class Xvfb:
|
|
|
102
101
|
def start(self) -> None:
|
|
103
102
|
"""Start Xvfb."""
|
|
104
103
|
|
|
104
|
+
if self.proc is not None:
|
|
105
|
+
raise RuntimeError(
|
|
106
|
+
f"Xvfb is already running (PID: {self.proc.pid})",
|
|
107
|
+
)
|
|
105
108
|
if not os.access(self._tempdir, os.W_OK):
|
|
106
109
|
raise RuntimeError(
|
|
107
110
|
f"Could not access writable temp directory: {self._tempdir}"
|
|
108
111
|
)
|
|
109
112
|
if self.new_display is not None:
|
|
110
113
|
if not self._get_lock_for_display(self.new_display):
|
|
111
|
-
raise RuntimeError(f"Could not lock display
|
|
114
|
+
raise RuntimeError(f"Could not lock display: {self.new_display}")
|
|
112
115
|
else:
|
|
113
116
|
self.new_display = self._get_next_unused_display()
|
|
114
117
|
display_var = f":{self.new_display}"
|
|
@@ -143,10 +146,6 @@ class Xvfb:
|
|
|
143
146
|
and, if necessary, an additional duration of the same length after killing the
|
|
144
147
|
process. If `self._timeout` is `None`, wait indefinitely for the process to
|
|
145
148
|
exit and be reaped.
|
|
146
|
-
|
|
147
|
-
This is a one-way lifecycle transition: once called, this object is considered
|
|
148
|
-
stopped and cannot be reused, regardless of whether the process exits
|
|
149
|
-
successfully.
|
|
150
149
|
"""
|
|
151
150
|
if self.proc is None:
|
|
152
151
|
return
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|