misc-csechet/frontools/screenshot.py

94 lines
2.9 KiB
Python

"""Pages screenshots"""
from pathlib import Path
from tempfile import NamedTemporaryFile
from typing import Optional
from PIL import Image, ImageChops
from playwright.async_api import BrowserContext
from frontools import Config
from frontools.sources import Browser
from frontools.utils import (
get_default_screenshot_directory,
get_url_slug,
report_progress,
)
async def screenshot_diff(
config: Config,
right_source_name: str,
output_directory: Optional[str],
resolution: Optional[str] = None,
) -> None:
"""Compare pages with or without local css"""
if output_directory is None:
output_path = get_default_screenshot_directory()
else:
output_path = Path(output_directory)
output_path.mkdir(parents=True)
left_source = config.default_source
right_source = config.get_source(right_source_name)
width: Optional[int] = None
height: Optional[int] = None
if resolution is not None:
[width_str, height_str] = resolution.split("x")
width = int(width_str)
height = int(height_str)
async with left_source.get_browser(width=width, height=height) as left_browser:
async with right_source.get_browser(
width=width, height=height
) as right_browser:
urls = [(theme, url) for (theme, site) in config.sites for url in site.urls]
await report_progress(
"Screenshoting",
[
(
url,
_diff_url(
left_browser, right_browser, url, output_path / theme
),
)
for (theme, url) in urls
],
nb_workers=3,
)
async def _diff_url(left: Browser, right: Browser, url: str, output_path: Path) -> None:
try:
left_bytes = await _screenshot_url(left, url)
right_bytes = await _screenshot_url(right, url)
with NamedTemporaryFile(mode="wb") as left_file:
left_file.write(left_bytes)
left_image = Image.open(left_file.name)
with NamedTemporaryFile(mode="wb") as right_file:
right_file.write(right_bytes)
right_image = Image.open(right_file.name)
diff = ImageChops.difference(left_image, right_image)
url_slug = get_url_slug(url)
if not output_path.is_dir():
output_path.mkdir()
with open(output_path / f"{url_slug}_left", "wb") as screenshot_file:
screenshot_file.write(left_bytes)
with open(output_path / f"{url_slug}_right", "wb") as screenshot_file:
screenshot_file.write(right_bytes)
except Exception as ex:
print(f"Error while diffing {url} : {ex}")
async def _screenshot_url(browser: Browser, url: str) -> bytes:
async with browser.load_page(url) as page:
return await page.screenshot(full_page=True)