sphinxcontrib-screenshot 0.1.3__tar.gz → 0.1.4__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.

Potentially problematic release.


This version of sphinxcontrib-screenshot might be problematic. Click here for more details.

Files changed (22) hide show
  1. {sphinxcontrib_screenshot-0.1.3/sphinxcontrib_screenshot.egg-info → sphinxcontrib_screenshot-0.1.4}/PKG-INFO +21 -60
  2. sphinxcontrib_screenshot-0.1.4/README.md +33 -0
  3. sphinxcontrib_screenshot-0.1.4/pyproject.toml +109 -0
  4. sphinxcontrib_screenshot-0.1.4/setup.cfg +4 -0
  5. {sphinxcontrib_screenshot-0.1.3 → sphinxcontrib_screenshot-0.1.4}/sphinxcontrib/screenshot.py +155 -15
  6. {sphinxcontrib_screenshot-0.1.3 → sphinxcontrib_screenshot-0.1.4/sphinxcontrib_screenshot.egg-info}/PKG-INFO +21 -60
  7. {sphinxcontrib_screenshot-0.1.3 → sphinxcontrib_screenshot-0.1.4}/sphinxcontrib_screenshot.egg-info/SOURCES.txt +10 -3
  8. {sphinxcontrib_screenshot-0.1.3 → sphinxcontrib_screenshot-0.1.4}/sphinxcontrib_screenshot.egg-info/requires.txt +12 -0
  9. sphinxcontrib_screenshot-0.1.4/tests/test_browsers.py +49 -0
  10. sphinxcontrib_screenshot-0.1.4/tests/test_color_scheme.py +48 -0
  11. sphinxcontrib_screenshot-0.1.4/tests/test_contexts.py +32 -0
  12. sphinxcontrib_screenshot-0.1.3/setup.py → sphinxcontrib_screenshot-0.1.4/tests/test_figclass.py +13 -2
  13. sphinxcontrib_screenshot-0.1.4/tests/test_full_page.py +46 -0
  14. sphinxcontrib_screenshot-0.1.4/tests/test_headers.py +33 -0
  15. sphinxcontrib_screenshot-0.1.4/tests/test_pdf.py +34 -0
  16. sphinxcontrib_screenshot-0.1.3/tests/test_it.py → sphinxcontrib_screenshot-0.1.4/tests/test_root.py +32 -26
  17. sphinxcontrib_screenshot-0.1.4/tests/test_wsgi_apps.py +32 -0
  18. sphinxcontrib_screenshot-0.1.3/README.md +0 -84
  19. sphinxcontrib_screenshot-0.1.3/setup.cfg +0 -60
  20. {sphinxcontrib_screenshot-0.1.3 → sphinxcontrib_screenshot-0.1.4}/LICENSE +0 -0
  21. {sphinxcontrib_screenshot-0.1.3 → sphinxcontrib_screenshot-0.1.4}/sphinxcontrib_screenshot.egg-info/dependency_links.txt +0 -0
  22. {sphinxcontrib_screenshot-0.1.3 → sphinxcontrib_screenshot-0.1.4}/sphinxcontrib_screenshot.egg-info/top_level.txt +0 -0
@@ -1,103 +1,64 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: sphinxcontrib-screenshot
3
- Version: 0.1.3
4
- Summary: A Shpinx extension to embed webpage screenshots.
5
- Home-page: https://github.com/tushuhei/sphinxcontrib-screenshot/
6
- Author: Shuhei Iitsuka
7
- Author-email: tushuhei@gmail.com
3
+ Version: 0.1.4
4
+ Summary: A Sphinx extension to embed webpage screenshots.
5
+ Author-email: Shuhei Iitsuka <tushuhei@gmail.com>
8
6
  License: Apache-2.0
7
+ Project-URL: repository, https://github.com/tushuhei/sphinxcontrib-screenshot/
9
8
  Classifier: Development Status :: 3 - Alpha
10
9
  Classifier: Operating System :: OS Independent
11
10
  Classifier: License :: OSI Approved :: Apache Software License
12
11
  Classifier: Programming Language :: Python :: 3.9
13
12
  Classifier: Programming Language :: Python :: 3.10
14
13
  Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
15
16
  Requires-Python: >=3.9
16
17
  Description-Content-Type: text/markdown
17
18
  License-File: LICENSE
18
19
  Requires-Dist: playwright
19
20
  Requires-Dist: sphinx
21
+ Requires-Dist: portpicker
20
22
  Provides-Extra: dev
21
23
  Requires-Dist: beautifulsoup4; extra == "dev"
22
24
  Requires-Dist: build; extra == "dev"
23
25
  Requires-Dist: flake8; extra == "dev"
26
+ Requires-Dist: flake8-pyproject; extra == "dev"
24
27
  Requires-Dist: isort; extra == "dev"
25
28
  Requires-Dist: mypy; extra == "dev"
26
29
  Requires-Dist: Pillow; extra == "dev"
30
+ Requires-Dist: pre-commit; extra == "dev"
27
31
  Requires-Dist: pytest; extra == "dev"
32
+ Requires-Dist: pytest-regressions[image]; extra == "dev"
28
33
  Requires-Dist: sphinx[test]; extra == "dev"
29
34
  Requires-Dist: toml; extra == "dev"
35
+ Requires-Dist: tox; extra == "dev"
30
36
  Requires-Dist: twine; extra == "dev"
31
37
  Requires-Dist: types-beautifulsoup4; extra == "dev"
32
38
  Requires-Dist: types-docutils; extra == "dev"
39
+ Requires-Dist: types-portpicker; extra == "dev"
33
40
  Requires-Dist: types-Pillow; extra == "dev"
34
41
  Requires-Dist: types-setuptools; extra == "dev"
42
+ Requires-Dist: user-agents; extra == "dev"
35
43
  Requires-Dist: yapf; extra == "dev"
44
+ Provides-Extra: doc
45
+ Requires-Dist: myst-parser; extra == "doc"
46
+ Requires-Dist: shibuya; extra == "doc"
47
+ Requires-Dist: sphinx; extra == "doc"
36
48
 
37
49
  # sphinxcontrib-screenshot
38
50
 
39
51
  A Sphinx extension to embed website screenshots.
40
52
 
41
- ![Example screenshot](https://raw.githubusercontent.com/tushuhei/sphinxcontrib-screenshot/main/example.png)
42
-
43
- ## Install
44
-
45
- ```bash
46
- pip install sphinxcontrib-screenshot
47
- playwright install
48
- ```
49
-
50
- ## Usage
51
-
52
- Add `sphinxcontrib.screenshot` to your `conf.py`.
53
-
54
- ```py
55
- extensions = ["sphinxcontrib.screenshot"]
56
- ```
57
-
58
- Then use the `screenshot` directive in your Sphinx source file.
59
-
60
- ```rst
61
- .. screenshot:: http://www.example.com
62
- ```
63
-
64
- You can also specify the screen size for the screenshot with `width` and `height` parameters.
65
-
66
53
  ```rst
67
54
  .. screenshot:: http://www.example.com
55
+ :browser: chromium
68
56
  :width: 1280
69
57
  :height: 960
58
+ :color-scheme: dark
70
59
  ```
71
60
 
72
- You can include a caption for the screenshot's `figure` directive.
73
-
74
- ```rst
75
- .. screenshot:: http://www.example.com
76
- :caption: This is a screenshot for www.example.com
77
- ```
78
-
79
- You can describe the interaction that you want to have with the webpage before taking a screenshot in JavaScript.
80
-
81
- ```rst
82
- .. screenshot:: http://www.example.com
83
-
84
- document.querySelector('button').click();
85
- ```
86
-
87
- ## Pro tips
88
- `sphinxcontrib-screenshot` supports URLs with the HTTP and HTTPS protocols.
89
- To take screenshots of local files and build the document while running a local server for them, you can use the NPM library [concurrently](https://www.npmjs.com/package/concurrently) in the following way:
90
-
91
- ### Build the document
92
- ```bash
93
- npx --yes concurrently -k --success=first "make html" "python3 -m http.server 3000 --directory=examples"
94
- ```
95
-
96
- ### Watch and build the document
97
- ```bash
98
- npx --yes concurrently -k "make livehtml" "python3 -m http.server 3000 --directory=examples"
99
- ```
100
-
61
+ Read more in the [documentation](https://sphinxcontrib-screenshot.readthedocs.io).
101
62
 
102
63
  ## Notes
103
64
 
@@ -0,0 +1,33 @@
1
+ # sphinxcontrib-screenshot
2
+
3
+ A Sphinx extension to embed website screenshots.
4
+
5
+ ```rst
6
+ .. screenshot:: http://www.example.com
7
+ :browser: chromium
8
+ :width: 1280
9
+ :height: 960
10
+ :color-scheme: dark
11
+ ```
12
+
13
+ Read more in the [documentation](https://sphinxcontrib-screenshot.readthedocs.io).
14
+
15
+ ## Notes
16
+
17
+ This extension uses [Playwright](https://playwright.dev) to capture a screenshot of the specified website only.
18
+ No data is sent to any other external server; the request is limited to the specified website.
19
+ Be cautious: avoid including sensitive information (such as authentication data) in the directive content.
20
+
21
+ ## Contributing
22
+
23
+ See [`CONTRIBUTING.md`](CONTRIBUTING.md) for details.
24
+
25
+ ## License
26
+
27
+ Apache 2.0; see [`LICENSE`](LICENSE) for details.
28
+
29
+ ## Disclaimer
30
+
31
+ This project is not an official Google project. It is not supported by
32
+ Google and Google specifically disclaims all warranties as to its quality,
33
+ merchantability, or fitness for a particular purpose.
@@ -0,0 +1,109 @@
1
+ [build-system]
2
+ requires = ["setuptools>=42", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "sphinxcontrib-screenshot"
7
+ version = "0.1.4"
8
+ description = "A Sphinx extension to embed webpage screenshots."
9
+ readme = "README.md"
10
+ license = { text = "Apache-2.0" }
11
+ authors = [
12
+ { name = "Shuhei Iitsuka", email = "tushuhei@gmail.com" }
13
+ ]
14
+ urls = { repository = "https://github.com/tushuhei/sphinxcontrib-screenshot/" }
15
+ classifiers = [
16
+ "Development Status :: 3 - Alpha",
17
+ "Operating System :: OS Independent",
18
+ "License :: OSI Approved :: Apache Software License",
19
+ "Programming Language :: Python :: 3.9",
20
+ "Programming Language :: Python :: 3.10",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Programming Language :: Python :: 3.13",
24
+ ]
25
+ requires-python = ">=3.9"
26
+ dependencies = [
27
+ "playwright",
28
+ "sphinx",
29
+ "portpicker",
30
+ ]
31
+
32
+ [project.optional-dependencies]
33
+ dev = [
34
+ "beautifulsoup4",
35
+ "build",
36
+ "flake8",
37
+ "flake8-pyproject",
38
+ "isort",
39
+ "mypy",
40
+ "Pillow",
41
+ "pre-commit",
42
+ "pytest",
43
+ "pytest-regressions[image]",
44
+ "sphinx[test]",
45
+ "toml",
46
+ "tox",
47
+ "twine",
48
+ "types-beautifulsoup4",
49
+ "types-docutils",
50
+ "types-portpicker",
51
+ "types-Pillow",
52
+ "types-setuptools",
53
+ "user-agents",
54
+ "yapf",
55
+ ]
56
+
57
+ doc = [
58
+ "myst-parser",
59
+ "shibuya",
60
+ "sphinx",
61
+ ]
62
+
63
+ [tool.setuptools]
64
+ packages = ["sphinxcontrib"]
65
+ include-package-data = true
66
+
67
+ [tool.setuptools.package-data]
68
+ "sphinxcontrib" = ["*"]
69
+
70
+ [tool.yapf]
71
+ based_on_style = "yapf"
72
+
73
+ [tool.flake8]
74
+ indent-size = 2
75
+
76
+ [tool.mypy]
77
+ python_version = 3.9
78
+ pretty = true
79
+ packages = ["sphinxcontrib"]
80
+
81
+ [tool.tox]
82
+ requires = ["tox>=4.19"]
83
+ env_list = [
84
+ "py39",
85
+ "py310",
86
+ "py311",
87
+ "py312",
88
+ "py313",
89
+ "style",
90
+ ]
91
+
92
+ [tool.tox.env_run_base]
93
+ deps = ["-e .[dev]"]
94
+ commands = [
95
+ ["pytest", "--showlocals", "--full-trace", "{posargs}"],
96
+ ]
97
+
98
+ [tool.tox.env.style]
99
+ skip_install = true
100
+ commands = [
101
+ ["pre-commit", "run", "--all-files", "--show-diff-on-failure"],
102
+ ]
103
+
104
+ [tool.tox.env.doc]
105
+ skip_install = true
106
+ deps = ["-e .[doc]"]
107
+ commands = [
108
+ ["sphinx-build", "--builder", "html", "doc", "build/sphinx/html"],
109
+ ]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -13,17 +13,25 @@
13
13
  # limitations under the License.
14
14
 
15
15
  import hashlib
16
+ import importlib
17
+ import importlib.metadata
16
18
  import os
19
+ import threading
17
20
  import typing
21
+ import wsgiref.simple_server
18
22
  from concurrent.futures import ThreadPoolExecutor
19
23
  from urllib.parse import urlparse
20
24
 
21
25
  from docutils import nodes
22
26
  from docutils.parsers.rst import directives
23
27
  from docutils.statemachine import ViewList
28
+ from playwright._impl._helper import ColorScheme
29
+ from playwright.sync_api import Browser, BrowserContext
24
30
  from playwright.sync_api import TimeoutError as PlaywrightTimeoutError
25
31
  from playwright.sync_api import sync_playwright
32
+ from portpicker import pick_unused_port
26
33
  from sphinx.application import Sphinx
34
+ from sphinx.config import Config
27
35
  from sphinx.util.docutils import SphinxDirective
28
36
 
29
37
  Meta = typing.TypedDict('Meta', {
@@ -32,8 +40,6 @@ Meta = typing.TypedDict('Meta', {
32
40
  'parallel_write_safe': bool
33
41
  })
34
42
 
35
- __version__ = '0.1.3'
36
-
37
43
 
38
44
  class ScreenshotDirective(SphinxDirective):
39
45
  """Sphinx Screenshot Dirctive.
@@ -92,17 +98,27 @@ class ScreenshotDirective(SphinxDirective):
92
98
  required_arguments = 1 # URL
93
99
  has_content = True
94
100
  option_spec = {
101
+ 'browser': str,
95
102
  'height': directives.positive_int,
96
103
  'width': directives.positive_int,
97
104
  'caption': directives.unchanged,
98
105
  'figclass': directives.unchanged,
99
106
  'pdf': directives.flag,
107
+ 'color-scheme': str,
108
+ 'full-page': directives.flag,
109
+ 'context': str,
110
+ 'headers': directives.unchanged,
100
111
  }
101
112
  pool = ThreadPoolExecutor()
102
113
 
103
114
  @staticmethod
104
- def take_screenshot(url: str, width: int, height: int, filepath: str,
105
- init_script: str, interactions: str, generate_pdf: bool):
115
+ def take_screenshot(
116
+ url: str, browser_name: str, width: int, height: int, filepath: str,
117
+ init_script: str, interactions: str, generate_pdf: bool,
118
+ color_scheme: ColorScheme, full_page: bool,
119
+ context_builder: typing.Optional[typing.Callable[[Browser, str, str],
120
+ BrowserContext]],
121
+ headers: dict):
106
122
  """Takes a screenshot with Playwright's Chromium browser.
107
123
 
108
124
  Args:
@@ -116,15 +132,30 @@ class ScreenshotDirective(SphinxDirective):
116
132
  interactions (str): JavaScript code to run before taking the screenshot
117
133
  after the page was loaded.
118
134
  generate_pdf (bool): Generate a PDF file along with the screenshot.
135
+ color_scheme (str): The preferred color scheme. Can be 'light' or 'dark'.
136
+ context: A method to build the Playwright context.
119
137
  """
120
138
  with sync_playwright() as playwright:
121
- browser = playwright.chromium.launch()
122
- page = browser.new_page()
139
+ browser = getattr(playwright, browser_name).launch()
140
+
141
+ if context_builder:
142
+ try:
143
+ context = context_builder(browser, url, color_scheme)
144
+ except PlaywrightTimeoutError:
145
+ raise RuntimeError(
146
+ 'Timeout error occured at %s in executing py init script %s' %
147
+ (url, context_builder.__name__))
148
+ else:
149
+ context = browser.new_context(color_scheme=color_scheme)
150
+
151
+ page = context.new_page()
123
152
  page.set_default_timeout(10000)
124
153
  page.set_viewport_size({'width': width, 'height': height})
154
+
125
155
  try:
126
156
  if init_script:
127
157
  page.add_init_script(init_script)
158
+ page.set_extra_http_headers(headers)
128
159
  page.goto(url)
129
160
  page.wait_for_load_state('networkidle')
130
161
 
@@ -135,7 +166,7 @@ class ScreenshotDirective(SphinxDirective):
135
166
  except PlaywrightTimeoutError:
136
167
  raise RuntimeError('Timeout error occured at %s in executing\n%s' %
137
168
  (url, interactions))
138
- page.screenshot(path=filepath)
169
+ page.screenshot(path=filepath, full_page=full_page)
139
170
  if generate_pdf:
140
171
  page.emulate_media(media='screen')
141
172
  root, ext = os.path.splitext(filepath)
@@ -143,6 +174,12 @@ class ScreenshotDirective(SphinxDirective):
143
174
  page.close()
144
175
  browser.close()
145
176
 
177
+ def evaluate_substitutions(self, text: str) -> str:
178
+ substitutions = self.state.document.substitution_defs
179
+ for key, value in substitutions.items():
180
+ text = text.replace(f"|{key}|", value.astext())
181
+ return text
182
+
146
183
  def run(self) -> typing.List[nodes.Node]:
147
184
  screenshot_init_script: str = self.env.config.screenshot_init_script or ''
148
185
 
@@ -151,28 +188,56 @@ class ScreenshotDirective(SphinxDirective):
151
188
  os.makedirs(ss_dirpath, exist_ok=True)
152
189
 
153
190
  # Parse parameters
154
- url = self.arguments[0]
155
- height = self.options.get('height', 960)
156
- width = self.options.get('width', 1280)
191
+ raw_url = self.arguments[0]
192
+ url = self.evaluate_substitutions(raw_url)
193
+ browser = self.options.get('browser',
194
+ self.env.config.screenshot_default_browser)
195
+ height = self.options.get('height',
196
+ self.env.config.screenshot_default_height)
197
+ width = self.options.get('width', self.env.config.screenshot_default_width)
198
+ color_scheme = self.options.get(
199
+ 'color-scheme', self.env.config.screenshot_default_color_scheme)
157
200
  caption_text = self.options.get('caption', '')
158
201
  figclass = self.options.get('figclass', '')
159
202
  pdf = 'pdf' in self.options
203
+ full_page = ('full-page' in self.options or
204
+ self.env.config.screenshot_default_full_page)
205
+ context = self.options.get('context', '')
160
206
  interactions = '\n'.join(self.content)
207
+ headers = self.options.get('headers', '')
208
+
209
+ request_headers = {**self.env.config.screenshot_default_headers}
210
+ if headers:
211
+ for header in headers.strip().split("\n"):
212
+ name, value = header.split(" ", 1)
213
+ request_headers[name] = value
161
214
 
162
215
  if urlparse(url).scheme not in {'http', 'https'}:
163
216
  raise RuntimeError(
164
217
  f'Invalid URL: {url}. Only HTTP/HTTPS URLs are supported.')
165
218
 
166
219
  # Generate filename based on hash of parameters
167
- hash_input = f'{url}_{height}_{width}_{interactions}'
220
+ hash_input = "_".join([
221
+ raw_url, browser,
222
+ str(height),
223
+ str(width), color_scheme, context, interactions,
224
+ str(full_page)
225
+ ])
168
226
  filename = hashlib.md5(hash_input.encode()).hexdigest() + '.png'
169
227
  filepath = os.path.join(ss_dirpath, filename)
170
228
 
229
+ if context:
230
+ context_builder_path = self.config.screenshot_contexts[context]
231
+ context_builder = resolve_python_method(context_builder_path)
232
+ else:
233
+ context_builder = None
234
+
171
235
  # Check if the file already exists. If not, take a screenshot
172
236
  if not os.path.exists(filepath):
173
- fut = self.pool.submit(ScreenshotDirective.take_screenshot, url, width,
174
- height, filepath, screenshot_init_script,
175
- interactions, pdf)
237
+ fut = self.pool.submit(ScreenshotDirective.take_screenshot, url, browser,
238
+ width, height, filepath, screenshot_init_script,
239
+ interactions, pdf, color_scheme, full_page,
240
+ context_builder, request_headers)
176
241
  fut.result()
177
242
 
178
243
  # Create image and figure nodes
@@ -195,11 +260,86 @@ class ScreenshotDirective(SphinxDirective):
195
260
  return [figure_node]
196
261
 
197
262
 
263
+ app_threads = {}
264
+
265
+
266
+ def resolve_python_method(import_path: str):
267
+ module_path, method_name = import_path.split(":")
268
+ module = importlib.import_module(module_path)
269
+ method = getattr(module, method_name)
270
+ return method
271
+
272
+
273
+ def setup_apps(app: Sphinx, config: Config):
274
+ """Start the WSGI application threads.
275
+
276
+ A new replacement is created for each WSGI app."""
277
+ for wsgi_app_name, wsgi_app_path in config.screenshot_apps.items():
278
+ port = pick_unused_port()
279
+ config.rst_prolog = (
280
+ config.rst_prolog or
281
+ "") + f"\n.. |{wsgi_app_name}| replace:: http://localhost:{port}\n"
282
+ app_builder = resolve_python_method(wsgi_app_path)
283
+ wsgi_app = app_builder(app)
284
+ httpd = wsgiref.simple_server.make_server("localhost", port, wsgi_app)
285
+ thread = threading.Thread(target=httpd.serve_forever)
286
+ thread.start()
287
+ app_threads[wsgi_app_name] = (httpd, thread)
288
+
289
+
290
+ def teardown_apps(app: Sphinx, exception: typing.Optional[Exception]):
291
+ """Shut down the WSGI application threads."""
292
+ for httpd, thread in app_threads.values():
293
+ httpd.shutdown()
294
+ thread.join()
295
+
296
+
198
297
  def setup(app: Sphinx) -> Meta:
199
298
  app.add_directive('screenshot', ScreenshotDirective)
200
299
  app.add_config_value('screenshot_init_script', '', 'env')
300
+ app.add_config_value(
301
+ 'screenshot_default_width',
302
+ 1280,
303
+ 'env',
304
+ description="The default width for screenshots")
305
+ app.add_config_value(
306
+ 'screenshot_default_height',
307
+ 960,
308
+ 'env',
309
+ description="The default height for screenshots")
310
+ app.add_config_value(
311
+ 'screenshot_default_browser',
312
+ 'chromium',
313
+ 'env',
314
+ description="The default browser for screenshots")
315
+ app.add_config_value(
316
+ 'screenshot_default_full_page',
317
+ False,
318
+ 'env',
319
+ description="Whether to take full page screenshots")
320
+ app.add_config_value(
321
+ 'screenshot_default_color_scheme',
322
+ 'null',
323
+ 'env',
324
+ description="The default color scheme for screenshots")
325
+ app.add_config_value(
326
+ 'screenshot_contexts', {},
327
+ 'env',
328
+ types=[dict[str, str]],
329
+ description="A dict of paths to Playwright context build methods")
330
+ app.add_config_value(
331
+ 'screenshot_default_headers', {},
332
+ 'env',
333
+ description="The default headers to pass in requests")
334
+ app.add_config_value(
335
+ 'screenshot_apps', {},
336
+ 'env',
337
+ types=[dict[str, str]],
338
+ description="A dict of WSGI apps")
339
+ app.connect('config-inited', setup_apps)
340
+ app.connect('build-finished', teardown_apps)
201
341
  return {
202
- 'version': __version__,
342
+ 'version': importlib.metadata.version('sphinxcontrib-screenshot'),
203
343
  'parallel_read_safe': True,
204
344
  'parallel_write_safe': True,
205
345
  }
@@ -1,103 +1,64 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: sphinxcontrib-screenshot
3
- Version: 0.1.3
4
- Summary: A Shpinx extension to embed webpage screenshots.
5
- Home-page: https://github.com/tushuhei/sphinxcontrib-screenshot/
6
- Author: Shuhei Iitsuka
7
- Author-email: tushuhei@gmail.com
3
+ Version: 0.1.4
4
+ Summary: A Sphinx extension to embed webpage screenshots.
5
+ Author-email: Shuhei Iitsuka <tushuhei@gmail.com>
8
6
  License: Apache-2.0
7
+ Project-URL: repository, https://github.com/tushuhei/sphinxcontrib-screenshot/
9
8
  Classifier: Development Status :: 3 - Alpha
10
9
  Classifier: Operating System :: OS Independent
11
10
  Classifier: License :: OSI Approved :: Apache Software License
12
11
  Classifier: Programming Language :: Python :: 3.9
13
12
  Classifier: Programming Language :: Python :: 3.10
14
13
  Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
15
16
  Requires-Python: >=3.9
16
17
  Description-Content-Type: text/markdown
17
18
  License-File: LICENSE
18
19
  Requires-Dist: playwright
19
20
  Requires-Dist: sphinx
21
+ Requires-Dist: portpicker
20
22
  Provides-Extra: dev
21
23
  Requires-Dist: beautifulsoup4; extra == "dev"
22
24
  Requires-Dist: build; extra == "dev"
23
25
  Requires-Dist: flake8; extra == "dev"
26
+ Requires-Dist: flake8-pyproject; extra == "dev"
24
27
  Requires-Dist: isort; extra == "dev"
25
28
  Requires-Dist: mypy; extra == "dev"
26
29
  Requires-Dist: Pillow; extra == "dev"
30
+ Requires-Dist: pre-commit; extra == "dev"
27
31
  Requires-Dist: pytest; extra == "dev"
32
+ Requires-Dist: pytest-regressions[image]; extra == "dev"
28
33
  Requires-Dist: sphinx[test]; extra == "dev"
29
34
  Requires-Dist: toml; extra == "dev"
35
+ Requires-Dist: tox; extra == "dev"
30
36
  Requires-Dist: twine; extra == "dev"
31
37
  Requires-Dist: types-beautifulsoup4; extra == "dev"
32
38
  Requires-Dist: types-docutils; extra == "dev"
39
+ Requires-Dist: types-portpicker; extra == "dev"
33
40
  Requires-Dist: types-Pillow; extra == "dev"
34
41
  Requires-Dist: types-setuptools; extra == "dev"
42
+ Requires-Dist: user-agents; extra == "dev"
35
43
  Requires-Dist: yapf; extra == "dev"
44
+ Provides-Extra: doc
45
+ Requires-Dist: myst-parser; extra == "doc"
46
+ Requires-Dist: shibuya; extra == "doc"
47
+ Requires-Dist: sphinx; extra == "doc"
36
48
 
37
49
  # sphinxcontrib-screenshot
38
50
 
39
51
  A Sphinx extension to embed website screenshots.
40
52
 
41
- ![Example screenshot](https://raw.githubusercontent.com/tushuhei/sphinxcontrib-screenshot/main/example.png)
42
-
43
- ## Install
44
-
45
- ```bash
46
- pip install sphinxcontrib-screenshot
47
- playwright install
48
- ```
49
-
50
- ## Usage
51
-
52
- Add `sphinxcontrib.screenshot` to your `conf.py`.
53
-
54
- ```py
55
- extensions = ["sphinxcontrib.screenshot"]
56
- ```
57
-
58
- Then use the `screenshot` directive in your Sphinx source file.
59
-
60
- ```rst
61
- .. screenshot:: http://www.example.com
62
- ```
63
-
64
- You can also specify the screen size for the screenshot with `width` and `height` parameters.
65
-
66
53
  ```rst
67
54
  .. screenshot:: http://www.example.com
55
+ :browser: chromium
68
56
  :width: 1280
69
57
  :height: 960
58
+ :color-scheme: dark
70
59
  ```
71
60
 
72
- You can include a caption for the screenshot's `figure` directive.
73
-
74
- ```rst
75
- .. screenshot:: http://www.example.com
76
- :caption: This is a screenshot for www.example.com
77
- ```
78
-
79
- You can describe the interaction that you want to have with the webpage before taking a screenshot in JavaScript.
80
-
81
- ```rst
82
- .. screenshot:: http://www.example.com
83
-
84
- document.querySelector('button').click();
85
- ```
86
-
87
- ## Pro tips
88
- `sphinxcontrib-screenshot` supports URLs with the HTTP and HTTPS protocols.
89
- To take screenshots of local files and build the document while running a local server for them, you can use the NPM library [concurrently](https://www.npmjs.com/package/concurrently) in the following way:
90
-
91
- ### Build the document
92
- ```bash
93
- npx --yes concurrently -k --success=first "make html" "python3 -m http.server 3000 --directory=examples"
94
- ```
95
-
96
- ### Watch and build the document
97
- ```bash
98
- npx --yes concurrently -k "make livehtml" "python3 -m http.server 3000 --directory=examples"
99
- ```
100
-
61
+ Read more in the [documentation](https://sphinxcontrib-screenshot.readthedocs.io).
101
62
 
102
63
  ## Notes
103
64
 
@@ -1,11 +1,18 @@
1
1
  LICENSE
2
2
  README.md
3
- setup.cfg
4
- setup.py
3
+ pyproject.toml
5
4
  sphinxcontrib/screenshot.py
6
5
  sphinxcontrib_screenshot.egg-info/PKG-INFO
7
6
  sphinxcontrib_screenshot.egg-info/SOURCES.txt
8
7
  sphinxcontrib_screenshot.egg-info/dependency_links.txt
9
8
  sphinxcontrib_screenshot.egg-info/requires.txt
10
9
  sphinxcontrib_screenshot.egg-info/top_level.txt
11
- tests/test_it.py
10
+ tests/test_browsers.py
11
+ tests/test_color_scheme.py
12
+ tests/test_contexts.py
13
+ tests/test_figclass.py
14
+ tests/test_full_page.py
15
+ tests/test_headers.py
16
+ tests/test_pdf.py
17
+ tests/test_root.py
18
+ tests/test_wsgi_apps.py
@@ -1,19 +1,31 @@
1
1
  playwright
2
2
  sphinx
3
+ portpicker
3
4
 
4
5
  [dev]
5
6
  beautifulsoup4
6
7
  build
7
8
  flake8
9
+ flake8-pyproject
8
10
  isort
9
11
  mypy
10
12
  Pillow
13
+ pre-commit
11
14
  pytest
15
+ pytest-regressions[image]
12
16
  sphinx[test]
13
17
  toml
18
+ tox
14
19
  twine
15
20
  types-beautifulsoup4
16
21
  types-docutils
22
+ types-portpicker
17
23
  types-Pillow
18
24
  types-setuptools
25
+ user-agents
19
26
  yapf
27
+
28
+ [doc]
29
+ myst-parser
30
+ shibuya
31
+ sphinx
@@ -0,0 +1,49 @@
1
+ # Copyright 2024 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
+ browsers = ["chromium", "firefox"]
21
+
22
+
23
+ @pytest.mark.parametrize("browser", browsers)
24
+ @pytest.mark.sphinx('html', testroot="browsers")
25
+ def test_browser_option(browser, app: SphinxTestApp, status: StringIO,
26
+ warning: StringIO, image_regression) -> None:
27
+ app.build()
28
+ out_html = app.outdir / f"{browser}.html"
29
+
30
+ soup = BeautifulSoup(out_html.read_text(), "html.parser")
31
+ imgs = soup.find_all('img')
32
+
33
+ img_path = app.outdir / imgs[0]['src']
34
+ with open(img_path, "rb") as fd:
35
+ image_regression.check(fd.read())
36
+
37
+
38
+ @pytest.mark.sphinx('html', testroot="default-browser")
39
+ def test_default_browser(app: SphinxTestApp, status: StringIO,
40
+ warning: StringIO, image_regression) -> None:
41
+ app.build()
42
+ out_html = app.outdir / "index.html"
43
+
44
+ soup = BeautifulSoup(out_html.read_text(), "html.parser")
45
+ imgs = soup.find_all('img')
46
+
47
+ img_path = app.outdir / imgs[0]['src']
48
+ with open(img_path, "rb") as fd:
49
+ image_regression.check(fd.read())
@@ -0,0 +1,48 @@
1
+ # Copyright 2024 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="color-schemes")
22
+ def test_color_scheme_option(app: SphinxTestApp, status: StringIO,
23
+ warning: StringIO, 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
+ image_regression.check(fd.read())
33
+
34
+
35
+ @pytest.mark.sphinx('html', testroot="default-color-scheme")
36
+ def test_default_color_scheme_config_parameter(app: SphinxTestApp,
37
+ status: StringIO,
38
+ warning: StringIO,
39
+ image_regression) -> None:
40
+ app.build()
41
+ out_html = app.outdir / "index.html"
42
+
43
+ soup = BeautifulSoup(out_html.read_text(), "html.parser")
44
+ imgs = soup.find_all('img')
45
+
46
+ img_path = app.outdir / imgs[0]['src']
47
+ with open(img_path, "rb") as fd:
48
+ image_regression.check(fd.read())
@@ -0,0 +1,32 @@
1
+ # Copyright 2024 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="contexts")
22
+ def test_default(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
+ image_regression.check(fd.read())
@@ -12,6 +12,17 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from setuptools import setup
15
+ import pytest
16
+ from bs4 import BeautifulSoup
17
+ from sphinx.testing.util import SphinxTestApp
16
18
 
17
- setup()
19
+
20
+ @pytest.mark.sphinx('html', testroot='figclass')
21
+ def test_default(app: SphinxTestApp) -> None:
22
+ app.build()
23
+ out_html = app.outdir / "index.html"
24
+ soup = BeautifulSoup(out_html.read_text(), "html.parser")
25
+
26
+ # The figure node should have the class name specified.
27
+ figure = soup.select_one('figure.round')
28
+ assert figure is not None
@@ -0,0 +1,46 @@
1
+ # Copyright 2024 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="full-page")
22
+ def test_full_page_option(app: SphinxTestApp, status: StringIO,
23
+ warning: StringIO, 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
+ image_regression.check(fd.read())
33
+
34
+
35
+ @pytest.mark.sphinx('html', testroot="default-full-page")
36
+ def test_default_full_page(app: SphinxTestApp, status: StringIO,
37
+ warning: StringIO, image_regression) -> None:
38
+ app.build()
39
+ out_html = app.outdir / "index.html"
40
+
41
+ soup = BeautifulSoup(out_html.read_text(), "html.parser")
42
+ imgs = soup.find_all('img')
43
+
44
+ img_path = app.outdir / imgs[0]['src']
45
+ with open(img_path, "rb") as fd:
46
+ image_regression.check(fd.read())
@@ -0,0 +1,33 @@
1
+ # Copyright 2024 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="headers")
22
+ def test_headers(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)
@@ -0,0 +1,34 @@
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
+ import os
16
+
17
+ import pytest
18
+ from bs4 import BeautifulSoup
19
+ from sphinx.testing.util import SphinxTestApp
20
+
21
+
22
+ @pytest.mark.sphinx('html', testroot='pdf')
23
+ def test_default(app: SphinxTestApp) -> None:
24
+ app.build()
25
+ out_html = app.outdir / "index.html"
26
+ soup = BeautifulSoup(out_html.read_text(), "html.parser")
27
+ img = soup.select_one('img')
28
+ assert img
29
+
30
+ imgsrc = str(img['src'])
31
+ root, ext = os.path.splitext(os.path.basename(imgsrc))
32
+ pdf_filepath = app.outdir / '_static' / 'screenshots' / f'{root}.pdf'
33
+ # Should generate a screenshot PDF.
34
+ assert os.path.exists(pdf_filepath)
@@ -12,7 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- import os
16
15
  from io import StringIO
17
16
 
18
17
  import pytest
@@ -21,16 +20,15 @@ from PIL import Image
21
20
  from sphinx.testing.util import SphinxTestApp
22
21
 
23
22
 
24
- @pytest.mark.sphinx('html')
25
- def test_default(app: SphinxTestApp, status: StringIO,
26
- warning: StringIO) -> None:
23
+ @pytest.mark.sphinx('html', testroot='root')
24
+ def test_default(app: SphinxTestApp) -> None:
27
25
  app.build()
28
26
  out_html = app.outdir / "index.html"
29
27
  soup = BeautifulSoup(out_html.read_text(), "html.parser")
30
28
 
31
29
  # Every screenshot directive should become an image.
32
30
  imgs = soup.find_all('img')
33
- assert len(list(imgs)) == 5
31
+ assert len(list(imgs)) == 3
34
32
 
35
33
  # The image size should be set as specified.
36
34
  img_obj = Image.open(app.outdir / imgs[0]['src'])
@@ -39,32 +37,40 @@ def test_default(app: SphinxTestApp, status: StringIO,
39
37
  assert height == 320
40
38
 
41
39
  # The caption should be rendered.
42
- figcaption = soup.select_one('figcaption span')
43
- assert figcaption and (figcaption.get_text().strip()
44
- == 'This is a test screenshot')
45
-
46
- # The images should be different after the specified user interaction.
47
- img_before_interaction = Image.open(app.outdir / imgs[0]['src'])
48
- img_after_interaction = Image.open(app.outdir / imgs[2]['src'])
49
- assert list(img_before_interaction.getdata()) != list(
50
- img_after_interaction.getdata())
40
+ figcaptions = [
41
+ figcaption.get_text().strip()
42
+ for figcaption in soup.select('figcaption span')
43
+ ]
44
+ assert figcaptions == [
45
+ 'This is a test screenshot', 'This is another screenshot',
46
+ 'Changing the background.'
47
+ ]
51
48
 
52
49
  # The images should be the same if the difference is only the caption.
53
50
  img_with_caption_a = imgs[0]
54
51
  img_with_caption_b = imgs[1]
55
52
  assert img_with_caption_a['src'] == img_with_caption_b['src']
56
53
 
57
- # The figure node should have the class name specified.
58
- assert 'round' in soup.find_all('figure')[3]['class']
54
+ # The images should be different after the specified user interaction.
55
+ imgsrc_before_interaction = app.outdir / imgs[1]['src']
56
+ imgsrc_after_interaction = app.outdir / imgs[2]['src']
57
+ assert imgsrc_before_interaction != imgsrc_after_interaction
58
+ assert list(Image.open(imgsrc_before_interaction).getdata()) != list(
59
+ Image.open(imgsrc_after_interaction).getdata())
60
+
59
61
 
60
- # Should generate a PDF file if specified.
61
- img_with_pdf = imgs[4]['src']
62
- root, ext = os.path.splitext(os.path.basename(img_with_pdf))
63
- pdf_filepath = app.outdir / '_static' / 'screenshots' / f'{root}.pdf'
64
- assert os.path.exists(pdf_filepath)
62
+ @pytest.mark.sphinx('html', testroot="default-size")
63
+ def test_default_size(app: SphinxTestApp, status: StringIO, warning: StringIO,
64
+ image_regression) -> None:
65
+ """Test the 'screenshot_default_width' and
66
+ 'screenshot_default_height' configuration parameters."""
67
+ app.build()
68
+ out_html = app.outdir / "index.html"
65
69
 
66
- # Should not generate a PDF file if not specified.
67
- img_without_pdf = imgs[2]['src']
68
- root, ext = os.path.splitext(os.path.basename(img_without_pdf))
69
- pdf_filepath = app.outdir / '_static' / 'screenshots' / f'{root}.pdf'
70
- assert not os.path.exists(pdf_filepath)
70
+ soup = BeautifulSoup(out_html.read_text(), "html.parser")
71
+ imgs = soup.find_all('img')
72
+
73
+ img_obj = Image.open(app.outdir / imgs[0]['src'])
74
+ width, height = img_obj.size
75
+ assert width == 1920
76
+ assert height == 1200
@@ -0,0 +1,32 @@
1
+ # Copyright 2024 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="wsgi-apps")
22
+ def test_default(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
+ image_regression.check(fd.read())
@@ -1,84 +0,0 @@
1
- # sphinxcontrib-screenshot
2
-
3
- A Sphinx extension to embed website screenshots.
4
-
5
- ![Example screenshot](https://raw.githubusercontent.com/tushuhei/sphinxcontrib-screenshot/main/example.png)
6
-
7
- ## Install
8
-
9
- ```bash
10
- pip install sphinxcontrib-screenshot
11
- playwright install
12
- ```
13
-
14
- ## Usage
15
-
16
- Add `sphinxcontrib.screenshot` to your `conf.py`.
17
-
18
- ```py
19
- extensions = ["sphinxcontrib.screenshot"]
20
- ```
21
-
22
- Then use the `screenshot` directive in your Sphinx source file.
23
-
24
- ```rst
25
- .. screenshot:: http://www.example.com
26
- ```
27
-
28
- You can also specify the screen size for the screenshot with `width` and `height` parameters.
29
-
30
- ```rst
31
- .. screenshot:: http://www.example.com
32
- :width: 1280
33
- :height: 960
34
- ```
35
-
36
- You can include a caption for the screenshot's `figure` directive.
37
-
38
- ```rst
39
- .. screenshot:: http://www.example.com
40
- :caption: This is a screenshot for www.example.com
41
- ```
42
-
43
- You can describe the interaction that you want to have with the webpage before taking a screenshot in JavaScript.
44
-
45
- ```rst
46
- .. screenshot:: http://www.example.com
47
-
48
- document.querySelector('button').click();
49
- ```
50
-
51
- ## Pro tips
52
- `sphinxcontrib-screenshot` supports URLs with the HTTP and HTTPS protocols.
53
- To take screenshots of local files and build the document while running a local server for them, you can use the NPM library [concurrently](https://www.npmjs.com/package/concurrently) in the following way:
54
-
55
- ### Build the document
56
- ```bash
57
- npx --yes concurrently -k --success=first "make html" "python3 -m http.server 3000 --directory=examples"
58
- ```
59
-
60
- ### Watch and build the document
61
- ```bash
62
- npx --yes concurrently -k "make livehtml" "python3 -m http.server 3000 --directory=examples"
63
- ```
64
-
65
-
66
- ## Notes
67
-
68
- This extension uses [Playwright](https://playwright.dev) to capture a screenshot of the specified website only.
69
- No data is sent to any other external server; the request is limited to the specified website.
70
- Be cautious: avoid including sensitive information (such as authentication data) in the directive content.
71
-
72
- ## Contributing
73
-
74
- See [`CONTRIBUTING.md`](CONTRIBUTING.md) for details.
75
-
76
- ## License
77
-
78
- Apache 2.0; see [`LICENSE`](LICENSE) for details.
79
-
80
- ## Disclaimer
81
-
82
- This project is not an official Google project. It is not supported by
83
- Google and Google specifically disclaims all warranties as to its quality,
84
- merchantability, or fitness for a particular purpose.
@@ -1,60 +0,0 @@
1
- [metadata]
2
- name = sphinxcontrib-screenshot
3
- version = attr: sphinxcontrib.screenshot.__version__
4
- description = A Shpinx extension to embed webpage screenshots.
5
- long_description = file: README.md
6
- long_description_content_type = text/markdown
7
- license = Apache-2.0
8
- author = Shuhei Iitsuka
9
- author_email = tushuhei@gmail.com
10
- url = https://github.com/tushuhei/sphinxcontrib-screenshot/
11
- classifiers =
12
- Development Status :: 3 - Alpha
13
- Operating System :: OS Independent
14
- License :: OSI Approved :: Apache Software License
15
- Programming Language :: Python :: 3.9
16
- Programming Language :: Python :: 3.10
17
- Programming Language :: Python :: 3.11
18
-
19
- [options]
20
- python_requires = >= 3.9
21
- packages =
22
- sphinxcontrib
23
- include_package_data = True
24
- test_suite = tests
25
- install_requires =
26
- playwright
27
- sphinx
28
-
29
- [options.extras_require]
30
- dev =
31
- beautifulsoup4
32
- build
33
- flake8
34
- isort
35
- mypy
36
- Pillow
37
- pytest
38
- sphinx[test]
39
- toml
40
- twine
41
- types-beautifulsoup4
42
- types-docutils
43
- types-Pillow
44
- types-setuptools
45
- yapf
46
-
47
- [yapf]
48
- based_on_style = yapf
49
-
50
- [flake8]
51
- indent-size = 2
52
-
53
- [mypy]
54
- python_version = 3.9
55
- pretty = True
56
-
57
- [egg_info]
58
- tag_build =
59
- tag_date = 0
60
-