sphinxcontrib-screenshot 0.2.0__tar.gz → 0.2.2__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.
- {sphinxcontrib_screenshot-0.2.0/sphinxcontrib_screenshot.egg-info → sphinxcontrib_screenshot-0.2.2}/PKG-INFO +1 -1
- {sphinxcontrib_screenshot-0.2.0 → sphinxcontrib_screenshot-0.2.2}/pyproject.toml +2 -1
- {sphinxcontrib_screenshot-0.2.0 → sphinxcontrib_screenshot-0.2.2}/sphinxcontrib/screenshot.py +97 -24
- {sphinxcontrib_screenshot-0.2.0 → sphinxcontrib_screenshot-0.2.2/sphinxcontrib_screenshot.egg-info}/PKG-INFO +1 -1
- {sphinxcontrib_screenshot-0.2.0 → sphinxcontrib_screenshot-0.2.2}/sphinxcontrib_screenshot.egg-info/SOURCES.txt +2 -0
- sphinxcontrib_screenshot-0.2.2/tests/test_locale.py +48 -0
- sphinxcontrib_screenshot-0.2.2/tests/test_root.py +92 -0
- sphinxcontrib_screenshot-0.2.2/tests/test_timezone.py +48 -0
- sphinxcontrib_screenshot-0.2.0/tests/test_root.py +0 -61
- {sphinxcontrib_screenshot-0.2.0 → sphinxcontrib_screenshot-0.2.2}/LICENSE +0 -0
- {sphinxcontrib_screenshot-0.2.0 → sphinxcontrib_screenshot-0.2.2}/README.md +0 -0
- {sphinxcontrib_screenshot-0.2.0 → sphinxcontrib_screenshot-0.2.2}/setup.cfg +0 -0
- {sphinxcontrib_screenshot-0.2.0 → sphinxcontrib_screenshot-0.2.2}/sphinxcontrib_screenshot.egg-info/dependency_links.txt +0 -0
- {sphinxcontrib_screenshot-0.2.0 → sphinxcontrib_screenshot-0.2.2}/sphinxcontrib_screenshot.egg-info/requires.txt +0 -0
- {sphinxcontrib_screenshot-0.2.0 → sphinxcontrib_screenshot-0.2.2}/sphinxcontrib_screenshot.egg-info/top_level.txt +0 -0
- {sphinxcontrib_screenshot-0.2.0 → sphinxcontrib_screenshot-0.2.2}/tests/test_browsers.py +0 -0
- {sphinxcontrib_screenshot-0.2.0 → sphinxcontrib_screenshot-0.2.2}/tests/test_color_scheme.py +0 -0
- {sphinxcontrib_screenshot-0.2.0 → sphinxcontrib_screenshot-0.2.2}/tests/test_contexts.py +0 -0
- {sphinxcontrib_screenshot-0.2.0 → sphinxcontrib_screenshot-0.2.2}/tests/test_full_page.py +0 -0
- {sphinxcontrib_screenshot-0.2.0 → sphinxcontrib_screenshot-0.2.2}/tests/test_headers.py +0 -0
- {sphinxcontrib_screenshot-0.2.0 → sphinxcontrib_screenshot-0.2.2}/tests/test_pdf.py +0 -0
- {sphinxcontrib_screenshot-0.2.0 → sphinxcontrib_screenshot-0.2.2}/tests/test_wsgi_apps.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "sphinxcontrib-screenshot"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.2"
|
|
8
8
|
description = "A Sphinx extension to embed webpage screenshots."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "Apache-2.0" }
|
|
@@ -69,6 +69,7 @@ include-package-data = true
|
|
|
69
69
|
|
|
70
70
|
[tool.yapf]
|
|
71
71
|
based_on_style = "yapf"
|
|
72
|
+
column_limit = 79
|
|
72
73
|
|
|
73
74
|
[tool.flake8]
|
|
74
75
|
indent-size = 2
|
{sphinxcontrib_screenshot-0.2.0 → sphinxcontrib_screenshot-0.2.2}/sphinxcontrib/screenshot.py
RENAMED
|
@@ -40,6 +40,9 @@ Meta = typing.TypedDict('Meta', {
|
|
|
40
40
|
'parallel_write_safe': bool
|
|
41
41
|
})
|
|
42
42
|
|
|
43
|
+
ContextBuilder = typing.Optional[typing.Callable[[Browser, str, str],
|
|
44
|
+
BrowserContext]]
|
|
45
|
+
|
|
43
46
|
|
|
44
47
|
class ScreenshotDirective(SphinxDirective, Figure):
|
|
45
48
|
"""Sphinx Screenshot Dirctive.
|
|
@@ -79,6 +82,24 @@ class ScreenshotDirective(SphinxDirective, Figure):
|
|
|
79
82
|
.. screenshot:: http://www.example.com
|
|
80
83
|
:pdf:
|
|
81
84
|
```
|
|
85
|
+
|
|
86
|
+
You can take a screenshot of a local file using a root-relative path.
|
|
87
|
+
|
|
88
|
+
```rst
|
|
89
|
+
.. screenshot:: /static/example.html
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Or you can use a document-relative path.
|
|
93
|
+
|
|
94
|
+
```rst
|
|
95
|
+
.. screenshot:: ./example.html
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The `file://` protocol is also supported.
|
|
99
|
+
|
|
100
|
+
```rst
|
|
101
|
+
.. screenshot:: file:///path/to/your/file.html
|
|
102
|
+
```
|
|
82
103
|
"""
|
|
83
104
|
|
|
84
105
|
required_arguments = 1 # URL
|
|
@@ -93,21 +114,25 @@ class ScreenshotDirective(SphinxDirective, Figure):
|
|
|
93
114
|
'full-page': directives.flag,
|
|
94
115
|
'context': str,
|
|
95
116
|
'headers': directives.unchanged,
|
|
117
|
+
'locale': str,
|
|
118
|
+
'timezone': str,
|
|
119
|
+
'device-scale-factor': directives.positive_int,
|
|
96
120
|
}
|
|
97
121
|
pool = ThreadPoolExecutor()
|
|
98
122
|
|
|
99
123
|
@staticmethod
|
|
100
|
-
def take_screenshot(
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
124
|
+
def take_screenshot(url: str, browser_name: str, viewport_width: int,
|
|
125
|
+
viewport_height: int, filepath: str, init_script: str,
|
|
126
|
+
interactions: str, generate_pdf: bool,
|
|
127
|
+
color_scheme: ColorScheme, full_page: bool,
|
|
128
|
+
context_builder: ContextBuilder, headers: dict,
|
|
129
|
+
device_scale_factor: int, locale: typing.Optional[str],
|
|
130
|
+
timezone: typing.Optional[str]):
|
|
107
131
|
"""Takes a screenshot with Playwright's Chromium browser.
|
|
108
132
|
|
|
109
133
|
Args:
|
|
110
134
|
url (str): The HTTP/HTTPS URL of the webpage to screenshot.
|
|
135
|
+
browser_name (str): Browser to use ('chromium', 'firefox' or 'webkit').
|
|
111
136
|
viewport_width (int): The width of the screenshot in pixels.
|
|
112
137
|
viewport_height (int): The height of the screenshot in pixels.
|
|
113
138
|
filepath (str): The path to save the screenshot to.
|
|
@@ -118,10 +143,16 @@ class ScreenshotDirective(SphinxDirective, Figure):
|
|
|
118
143
|
after the page was loaded.
|
|
119
144
|
generate_pdf (bool): Generate a PDF file along with the screenshot.
|
|
120
145
|
color_scheme (str): The preferred color scheme. Can be 'light' or 'dark'.
|
|
146
|
+
full_page (bool): Take a full page screenshot.
|
|
121
147
|
context: A method to build the Playwright context.
|
|
148
|
+
headers (dict): Custom request header.
|
|
149
|
+
device_scale_factor (int): The device scale factor for the screenshot.
|
|
150
|
+
This can be thought of as DPR (device pixel ratio).
|
|
151
|
+
locale (str, optional): User locale for the request.
|
|
152
|
+
timezone (str, optional): User timezone for the request.
|
|
122
153
|
"""
|
|
123
154
|
with sync_playwright() as playwright:
|
|
124
|
-
browser = getattr(playwright, browser_name).launch()
|
|
155
|
+
browser: Browser = getattr(playwright, browser_name).launch()
|
|
125
156
|
|
|
126
157
|
if context_builder:
|
|
127
158
|
try:
|
|
@@ -131,7 +162,11 @@ class ScreenshotDirective(SphinxDirective, Figure):
|
|
|
131
162
|
'Timeout error occured at %s in executing py init script %s' %
|
|
132
163
|
(url, context_builder.__name__))
|
|
133
164
|
else:
|
|
134
|
-
context = browser.new_context(
|
|
165
|
+
context = browser.new_context(
|
|
166
|
+
color_scheme=color_scheme,
|
|
167
|
+
locale=locale,
|
|
168
|
+
timezone_id=timezone,
|
|
169
|
+
device_scale_factor=device_scale_factor)
|
|
135
170
|
|
|
136
171
|
page = context.new_page()
|
|
137
172
|
page.set_default_timeout(10000)
|
|
@@ -173,14 +208,33 @@ class ScreenshotDirective(SphinxDirective, Figure):
|
|
|
173
208
|
|
|
174
209
|
def run(self) -> typing.Sequence[nodes.Node]:
|
|
175
210
|
screenshot_init_script: str = self.env.config.screenshot_init_script or ''
|
|
211
|
+
docdir = os.path.dirname(self.env.doc2path(self.env.docname))
|
|
176
212
|
|
|
177
213
|
# Ensure the screenshots directory exists
|
|
178
214
|
ss_dirpath = os.path.join(self.env.app.outdir, '_static', 'screenshots')
|
|
179
215
|
os.makedirs(ss_dirpath, exist_ok=True)
|
|
180
216
|
|
|
181
217
|
# Parse parameters
|
|
182
|
-
|
|
183
|
-
|
|
218
|
+
raw_path = self.arguments[0]
|
|
219
|
+
url_or_filepath = self.evaluate_substitutions(raw_path)
|
|
220
|
+
|
|
221
|
+
# Check if the path is a local file path.
|
|
222
|
+
if urlparse(url_or_filepath).scheme == '':
|
|
223
|
+
# root-relative path
|
|
224
|
+
if url_or_filepath.startswith('/'):
|
|
225
|
+
url_or_filepath = os.path.join(self.env.srcdir,
|
|
226
|
+
url_or_filepath.lstrip('/'))
|
|
227
|
+
# document-relative path
|
|
228
|
+
else:
|
|
229
|
+
url_or_filepath = os.path.join(docdir, url_or_filepath)
|
|
230
|
+
url_or_filepath = "file://" + os.path.normpath(url_or_filepath)
|
|
231
|
+
|
|
232
|
+
if urlparse(url_or_filepath).scheme not in {'http', 'https', 'file'}:
|
|
233
|
+
raise RuntimeError(
|
|
234
|
+
f'Invalid URL: {url_or_filepath}. ' +
|
|
235
|
+
'Only HTTP/HTTPS/FILE URLs or root/document-relative file paths ' +
|
|
236
|
+
'are supported.')
|
|
237
|
+
|
|
184
238
|
interactions = self.options.get('interactions', '')
|
|
185
239
|
browser = self.options.get('browser',
|
|
186
240
|
self.env.config.screenshot_default_browser)
|
|
@@ -193,25 +247,28 @@ class ScreenshotDirective(SphinxDirective, Figure):
|
|
|
193
247
|
pdf = 'pdf' in self.options
|
|
194
248
|
full_page = ('full-page' in self.options or
|
|
195
249
|
self.env.config.screenshot_default_full_page)
|
|
250
|
+
locale = self.options.get('locale',
|
|
251
|
+
self.env.config.screenshot_default_locale)
|
|
252
|
+
timezone = self.options.get('timezone',
|
|
253
|
+
self.env.config.screenshot_default_timezone)
|
|
196
254
|
context = self.options.get('context', '')
|
|
197
255
|
headers = self.options.get('headers', '')
|
|
198
|
-
|
|
256
|
+
device_scale_factor = self.options.get(
|
|
257
|
+
'device-scale-factor',
|
|
258
|
+
self.env.config.screenshot_default_device_scale_factor)
|
|
199
259
|
request_headers = {**self.env.config.screenshot_default_headers}
|
|
200
260
|
if headers:
|
|
201
261
|
for header in headers.strip().split("\n"):
|
|
202
262
|
name, value = header.split(" ", 1)
|
|
203
263
|
request_headers[name] = value
|
|
204
264
|
|
|
205
|
-
if urlparse(url).scheme not in {'http', 'https'}:
|
|
206
|
-
raise RuntimeError(
|
|
207
|
-
f'Invalid URL: {url}. Only HTTP/HTTPS URLs are supported.')
|
|
208
|
-
|
|
209
265
|
# Generate filename based on hash of parameters
|
|
210
266
|
hash_input = "_".join([
|
|
211
|
-
|
|
267
|
+
raw_path, browser,
|
|
212
268
|
str(viewport_height),
|
|
213
269
|
str(viewport_width), color_scheme, context, interactions,
|
|
214
|
-
str(full_page)
|
|
270
|
+
str(full_page),
|
|
271
|
+
str(device_scale_factor)
|
|
215
272
|
])
|
|
216
273
|
filename = hashlib.md5(hash_input.encode()).hexdigest() + '.png'
|
|
217
274
|
filepath = os.path.join(ss_dirpath, filename)
|
|
@@ -224,15 +281,15 @@ class ScreenshotDirective(SphinxDirective, Figure):
|
|
|
224
281
|
|
|
225
282
|
# Check if the file already exists. If not, take a screenshot
|
|
226
283
|
if not os.path.exists(filepath):
|
|
227
|
-
fut = self.pool.submit(ScreenshotDirective.take_screenshot,
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
color_scheme, full_page,
|
|
231
|
-
request_headers
|
|
284
|
+
fut = self.pool.submit(ScreenshotDirective.take_screenshot,
|
|
285
|
+
url_or_filepath, browser, viewport_width,
|
|
286
|
+
viewport_height, filepath, screenshot_init_script,
|
|
287
|
+
interactions, pdf, color_scheme, full_page,
|
|
288
|
+
context_builder, request_headers,
|
|
289
|
+
device_scale_factor, locale, timezone)
|
|
232
290
|
fut.result()
|
|
233
291
|
|
|
234
292
|
# Create image and figure nodes
|
|
235
|
-
docdir = os.path.dirname(self.env.doc2path(self.env.docname))
|
|
236
293
|
rel_ss_dirpath = os.path.relpath(ss_dirpath, start=docdir)
|
|
237
294
|
rel_filepath = os.path.join(rel_ss_dirpath, filename).replace(os.sep, '/')
|
|
238
295
|
|
|
@@ -311,6 +368,22 @@ def setup(app: Sphinx) -> Meta:
|
|
|
311
368
|
'screenshot_default_headers', {},
|
|
312
369
|
'env',
|
|
313
370
|
description="The default headers to pass in requests")
|
|
371
|
+
app.add_config_value(
|
|
372
|
+
'screenshot_default_device_scale_factor',
|
|
373
|
+
1,
|
|
374
|
+
'env',
|
|
375
|
+
description="The default device scale factor " +
|
|
376
|
+
"a.k.a. DPR (device pixel ratio)")
|
|
377
|
+
app.add_config_value(
|
|
378
|
+
'screenshot_default_locale',
|
|
379
|
+
None,
|
|
380
|
+
'env',
|
|
381
|
+
description="The default locale in requests")
|
|
382
|
+
app.add_config_value(
|
|
383
|
+
'screenshot_default_timezone',
|
|
384
|
+
None,
|
|
385
|
+
'env',
|
|
386
|
+
description="The default timezone in requests")
|
|
314
387
|
app.add_config_value(
|
|
315
388
|
'screenshot_apps', {},
|
|
316
389
|
'env',
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Copyright 2025 Google LLC
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
from io import StringIO
|
|
15
|
+
|
|
16
|
+
import pytest
|
|
17
|
+
from bs4 import BeautifulSoup
|
|
18
|
+
from sphinx.testing.util import SphinxTestApp
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@pytest.mark.sphinx('html', testroot="locale")
|
|
22
|
+
def test_locale(app: SphinxTestApp, status: StringIO, warning: StringIO,
|
|
23
|
+
image_regression) -> None:
|
|
24
|
+
app.build()
|
|
25
|
+
out_html = app.outdir / "index.html"
|
|
26
|
+
|
|
27
|
+
soup = BeautifulSoup(out_html.read_text(), "html.parser")
|
|
28
|
+
imgs = soup.find_all('img')
|
|
29
|
+
|
|
30
|
+
img_path = app.outdir / imgs[0]['src']
|
|
31
|
+
with open(img_path, "rb") as fd:
|
|
32
|
+
# Tolerance of 0.5%
|
|
33
|
+
image_regression.check(fd.read(), diff_threshold=0.5)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@pytest.mark.sphinx('html', testroot="default-locale")
|
|
37
|
+
def test_default_locale(app: SphinxTestApp, status: StringIO,
|
|
38
|
+
warning: StringIO, image_regression) -> None:
|
|
39
|
+
app.build()
|
|
40
|
+
out_html = app.outdir / "index.html"
|
|
41
|
+
|
|
42
|
+
soup = BeautifulSoup(out_html.read_text(), "html.parser")
|
|
43
|
+
imgs = soup.find_all('img')
|
|
44
|
+
|
|
45
|
+
img_path = app.outdir / imgs[0]['src']
|
|
46
|
+
with open(img_path, "rb") as fd:
|
|
47
|
+
# Tolerance of 0.5%
|
|
48
|
+
image_regression.check(fd.read(), diff_threshold=0.5)
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Copyright 2023 Google LLC
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from io import StringIO
|
|
16
|
+
|
|
17
|
+
import pytest
|
|
18
|
+
from bs4 import BeautifulSoup
|
|
19
|
+
from PIL import Image
|
|
20
|
+
from sphinx.testing.util import SphinxTestApp
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@pytest.mark.sphinx('html', testroot='root')
|
|
24
|
+
def test_default(app: SphinxTestApp) -> None:
|
|
25
|
+
app.build()
|
|
26
|
+
|
|
27
|
+
def test_index():
|
|
28
|
+
soup = BeautifulSoup((app.outdir / "index.html").read_text(),
|
|
29
|
+
"html.parser")
|
|
30
|
+
|
|
31
|
+
# Every screenshot directive should become an image.
|
|
32
|
+
imgs = soup.find_all('img')
|
|
33
|
+
assert len(list(imgs)) == 4
|
|
34
|
+
|
|
35
|
+
# The image size should be set as specified.
|
|
36
|
+
img_obj = Image.open(app.outdir / imgs[0]['src'])
|
|
37
|
+
width, height = img_obj.size
|
|
38
|
+
assert width == 480
|
|
39
|
+
assert height == 320
|
|
40
|
+
|
|
41
|
+
# The images should be the same if the difference is only the caption.
|
|
42
|
+
img_with_caption_a = imgs[0]
|
|
43
|
+
img_with_caption_b = imgs[1]
|
|
44
|
+
assert img_with_caption_a['src'] == img_with_caption_b['src']
|
|
45
|
+
|
|
46
|
+
# The images should be different after the specified user interaction.
|
|
47
|
+
imgsrc_before_interaction = app.outdir / imgs[1]['src']
|
|
48
|
+
imgsrc_after_interaction = app.outdir / imgs[2]['src']
|
|
49
|
+
assert imgsrc_before_interaction != imgsrc_after_interaction
|
|
50
|
+
assert list(Image.open(imgsrc_before_interaction).getdata()) != list(
|
|
51
|
+
Image.open(imgsrc_after_interaction).getdata())
|
|
52
|
+
|
|
53
|
+
# High reso image should have a larger size.
|
|
54
|
+
imgsrc_standard = app.outdir / imgs[0]['src']
|
|
55
|
+
imgsrc_highreso = app.outdir / imgs[3]['src']
|
|
56
|
+
assert (Image.open(imgsrc_highreso).width ==
|
|
57
|
+
Image.open(imgsrc_standard).width * 2)
|
|
58
|
+
|
|
59
|
+
def test_sections_index():
|
|
60
|
+
soup = BeautifulSoup((app.outdir / "sections" / "index.html").read_text(),
|
|
61
|
+
"html.parser")
|
|
62
|
+
|
|
63
|
+
# Every screenshot directive should become an image.
|
|
64
|
+
imgs = soup.find_all('img')
|
|
65
|
+
assert len(list(imgs)) == 2
|
|
66
|
+
|
|
67
|
+
# The images should be the same.
|
|
68
|
+
imgsrc_relative = app.outdir / "sections" / imgs[0]['src']
|
|
69
|
+
imgsrc_absolute = app.outdir / "sections" / imgs[1]['src']
|
|
70
|
+
assert imgsrc_relative != imgsrc_absolute
|
|
71
|
+
assert list(Image.open(imgsrc_relative).getdata()) == list(
|
|
72
|
+
Image.open(imgsrc_absolute).getdata())
|
|
73
|
+
|
|
74
|
+
test_index()
|
|
75
|
+
test_sections_index()
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@pytest.mark.sphinx('html', testroot="default-size")
|
|
79
|
+
def test_default_size(app: SphinxTestApp, status: StringIO, warning: StringIO,
|
|
80
|
+
image_regression) -> None:
|
|
81
|
+
"""Test the 'screenshot_default_viewport_width' and
|
|
82
|
+
'screenshot_default_viewport_height' configuration parameters."""
|
|
83
|
+
app.build()
|
|
84
|
+
out_html = app.outdir / "index.html"
|
|
85
|
+
|
|
86
|
+
soup = BeautifulSoup(out_html.read_text(), "html.parser")
|
|
87
|
+
imgs = soup.find_all('img')
|
|
88
|
+
|
|
89
|
+
img_obj = Image.open(app.outdir / imgs[0]['src'])
|
|
90
|
+
width, height = img_obj.size
|
|
91
|
+
assert width == 1920
|
|
92
|
+
assert height == 1200
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Copyright 2025 Google LLC
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
from io import StringIO
|
|
15
|
+
|
|
16
|
+
import pytest
|
|
17
|
+
from bs4 import BeautifulSoup
|
|
18
|
+
from sphinx.testing.util import SphinxTestApp
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@pytest.mark.sphinx('html', testroot="timezone")
|
|
22
|
+
def test_timezone(app: SphinxTestApp, status: StringIO, warning: StringIO,
|
|
23
|
+
image_regression) -> None:
|
|
24
|
+
app.build()
|
|
25
|
+
out_html = app.outdir / "index.html"
|
|
26
|
+
|
|
27
|
+
soup = BeautifulSoup(out_html.read_text(), "html.parser")
|
|
28
|
+
imgs = soup.find_all('img')
|
|
29
|
+
|
|
30
|
+
img_path = app.outdir / imgs[0]['src']
|
|
31
|
+
with open(img_path, "rb") as fd:
|
|
32
|
+
# Tolerance of 0.5%
|
|
33
|
+
image_regression.check(fd.read(), diff_threshold=0.5)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@pytest.mark.sphinx('html', testroot="default-timezone")
|
|
37
|
+
def test_default_timezone(app: SphinxTestApp, status: StringIO,
|
|
38
|
+
warning: StringIO, image_regression) -> None:
|
|
39
|
+
app.build()
|
|
40
|
+
out_html = app.outdir / "index.html"
|
|
41
|
+
|
|
42
|
+
soup = BeautifulSoup(out_html.read_text(), "html.parser")
|
|
43
|
+
imgs = soup.find_all('img')
|
|
44
|
+
|
|
45
|
+
img_path = app.outdir / imgs[0]['src']
|
|
46
|
+
with open(img_path, "rb") as fd:
|
|
47
|
+
# Tolerance of 0.5%
|
|
48
|
+
image_regression.check(fd.read(), diff_threshold=0.5)
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
# Copyright 2023 Google LLC
|
|
2
|
-
#
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
# you may not use this file except in compliance with the License.
|
|
5
|
-
# You may obtain a copy of the License at
|
|
6
|
-
#
|
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
#
|
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
# See the License for the specific language governing permissions and
|
|
13
|
-
# limitations under the License.
|
|
14
|
-
|
|
15
|
-
from io import StringIO
|
|
16
|
-
|
|
17
|
-
import pytest
|
|
18
|
-
from bs4 import BeautifulSoup
|
|
19
|
-
from PIL import Image
|
|
20
|
-
from sphinx.testing.util import SphinxTestApp
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
@pytest.mark.sphinx('html', testroot='root')
|
|
24
|
-
def test_default(app: SphinxTestApp) -> None:
|
|
25
|
-
app.build()
|
|
26
|
-
out_html = app.outdir / "index.html"
|
|
27
|
-
soup = BeautifulSoup(out_html.read_text(), "html.parser")
|
|
28
|
-
|
|
29
|
-
# Every screenshot directive should become an image.
|
|
30
|
-
imgs = soup.find_all('img')
|
|
31
|
-
assert len(list(imgs)) == 3
|
|
32
|
-
|
|
33
|
-
# The image size should be set as specified.
|
|
34
|
-
img_obj = Image.open(app.outdir / imgs[0]['src'])
|
|
35
|
-
width, height = img_obj.size
|
|
36
|
-
assert width == 480
|
|
37
|
-
assert height == 320
|
|
38
|
-
|
|
39
|
-
# The images should be different after the specified user interaction.
|
|
40
|
-
imgsrc_before_interaction = app.outdir / imgs[1]['src']
|
|
41
|
-
imgsrc_after_interaction = app.outdir / imgs[2]['src']
|
|
42
|
-
assert imgsrc_before_interaction != imgsrc_after_interaction
|
|
43
|
-
assert list(Image.open(imgsrc_before_interaction).getdata()) != list(
|
|
44
|
-
Image.open(imgsrc_after_interaction).getdata())
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
@pytest.mark.sphinx('html', testroot="default-size")
|
|
48
|
-
def test_default_size(app: SphinxTestApp, status: StringIO, warning: StringIO,
|
|
49
|
-
image_regression) -> None:
|
|
50
|
-
"""Test the 'screenshot_default_viewport_width' and
|
|
51
|
-
'screenshot_default_viewport_height' configuration parameters."""
|
|
52
|
-
app.build()
|
|
53
|
-
out_html = app.outdir / "index.html"
|
|
54
|
-
|
|
55
|
-
soup = BeautifulSoup(out_html.read_text(), "html.parser")
|
|
56
|
-
imgs = soup.find_all('img')
|
|
57
|
-
|
|
58
|
-
img_obj = Image.open(app.outdir / imgs[0]['src'])
|
|
59
|
-
width, height = img_obj.size
|
|
60
|
-
assert width == 1920
|
|
61
|
-
assert height == 1200
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sphinxcontrib_screenshot-0.2.0 → sphinxcontrib_screenshot-0.2.2}/tests/test_color_scheme.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|