forked from BoboTiG/python-mss
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_gnu_linux.py
More file actions
179 lines (130 loc) · 5.57 KB
/
test_gnu_linux.py
File metadata and controls
179 lines (130 loc) · 5.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
"""This is part of the MSS Python's module.
Source: https://github.com/BoboTiG/python-mss.
"""
import platform
from collections.abc import Generator
from unittest.mock import Mock, patch
import mss
import mss.linux
import pytest
from mss.base import MSSBase
from mss.exception import ScreenShotError
pyvirtualdisplay = pytest.importorskip("pyvirtualdisplay")
PYPY = platform.python_implementation() == "PyPy"
WIDTH = 200
HEIGHT = 200
DEPTH = 24
@pytest.fixture()
def display() -> Generator:
with pyvirtualdisplay.Display(size=(WIDTH, HEIGHT), color_depth=DEPTH) as vdisplay:
yield vdisplay.new_display_var
@pytest.mark.skipif(PYPY, reason="Failure on PyPy")
def test_factory_systems(monkeypatch: pytest.MonkeyPatch) -> None:
"""Here, we are testing all systems.
Too hard to maintain the test for all platforms,
so test only on GNU/Linux.
"""
# GNU/Linux
monkeypatch.setattr(platform, "system", lambda: "LINUX")
with mss.mss() as sct:
assert isinstance(sct, MSSBase)
monkeypatch.undo()
# macOS
monkeypatch.setattr(platform, "system", lambda: "Darwin")
# ValueError on macOS Big Sur
with pytest.raises((ScreenShotError, ValueError)), mss.mss():
pass
monkeypatch.undo()
# Windows
monkeypatch.setattr(platform, "system", lambda: "wInDoWs")
with pytest.raises(ImportError, match="cannot import name 'WINFUNCTYPE'"), mss.mss():
pass
def test_arg_display(display: str, monkeypatch: pytest.MonkeyPatch) -> None:
# Good value
with mss.mss(display=display):
pass
# Bad `display` (missing ":" in front of the number)
with pytest.raises(ScreenShotError), mss.mss(display="0"):
pass
# Invalid `display` that is not trivially distinguishable.
with pytest.raises(ScreenShotError), mss.mss(display=":INVALID"):
pass
# No `DISPLAY` in envars
monkeypatch.delenv("DISPLAY")
with pytest.raises(ScreenShotError), mss.mss():
pass
@pytest.mark.skipif(PYPY, reason="Failure on PyPy")
def test_bad_display_structure(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr(mss.linux, "Display", lambda: None)
with pytest.raises(TypeError), mss.mss():
pass
@patch("mss.linux._X11", new=None)
def test_no_xlib_library() -> None:
with pytest.raises(ScreenShotError), mss.mss():
pass
@patch("mss.linux._XRANDR", new=None)
def test_no_xrandr_extension() -> None:
with pytest.raises(ScreenShotError), mss.mss():
pass
@patch("mss.linux.MSS._is_extension_enabled", new=Mock(return_value=False))
def test_xrandr_extension_exists_but_is_not_enabled(display: str) -> None:
with pytest.raises(ScreenShotError), mss.mss(display=display):
pass
def test_unsupported_depth() -> None:
with pyvirtualdisplay.Display(size=(WIDTH, HEIGHT), color_depth=8) as vdisplay:
with pytest.raises(ScreenShotError):
with mss.mss(display=vdisplay.new_display_var) as sct:
sct.grab(sct.monitors[1])
def test_region_out_of_monitor_bounds(display: str) -> None:
monitor = {"left": -30, "top": 0, "width": WIDTH, "height": HEIGHT}
assert not mss.linux._ERROR
with mss.mss(display=display) as sct:
with pytest.raises(ScreenShotError) as exc:
sct.grab(monitor)
assert str(exc.value)
details = exc.value.details
assert details
assert isinstance(details, dict)
assert isinstance(details["error"], str)
assert not mss.linux._ERROR
assert not mss.linux._ERROR
def test__is_extension_enabled_unknown_name(display: str) -> None:
with mss.mss(display=display) as sct:
assert isinstance(sct, mss.linux.MSS) # For Mypy
assert not sct._is_extension_enabled("NOEXT")
def test_missing_fast_function_for_monitor_details_retrieval(display: str) -> None:
with mss.mss(display=display) as sct:
assert isinstance(sct, mss.linux.MSS) # For Mypy
assert hasattr(sct.xrandr, "XRRGetScreenResourcesCurrent")
screenshot_with_fast_fn = sct.grab(sct.monitors[1])
assert set(screenshot_with_fast_fn.rgb) == {0}
with mss.mss(display=display) as sct:
assert isinstance(sct, mss.linux.MSS) # For Mypy
assert hasattr(sct.xrandr, "XRRGetScreenResourcesCurrent")
del sct.xrandr.XRRGetScreenResourcesCurrent
screenshot_with_slow_fn = sct.grab(sct.monitors[1])
assert set(screenshot_with_slow_fn.rgb) == {0}
def test_with_cursor(display: str) -> None:
with mss.mss(display=display) as sct:
assert not hasattr(sct, "xfixes")
assert not sct.with_cursor
screenshot_without_cursor = sct.grab(sct.monitors[1])
# 1 color: black
assert set(screenshot_without_cursor.rgb) == {0}
with mss.mss(display=display, with_cursor=True) as sct:
assert hasattr(sct, "xfixes")
assert sct.with_cursor
screenshot_with_cursor = sct.grab(sct.monitors[1])
# 2 colors: black & white (default cursor is a white cross)
assert set(screenshot_with_cursor.rgb) == {0, 255}
@patch("mss.linux._XFIXES", new=None)
def test_with_cursor_but_not_xfixes_extension_found(display: str) -> None:
with mss.mss(display=display, with_cursor=True) as sct:
assert not hasattr(sct, "xfixes")
assert not sct.with_cursor
def test_with_cursor_failure(display: str) -> None:
with mss.mss(display=display, with_cursor=True) as sct:
assert isinstance(sct, mss.linux.MSS) # For Mypy
with patch.object(sct.xfixes, "XFixesGetCursorImage", return_value=None):
with pytest.raises(ScreenShotError):
sct.grab(sct.monitors[1])