common: add context class to handle error summary

This commit is contained in:
Corentin Sechet 2022-04-11 13:56:57 +02:00
parent 936248c3ce
commit bb5b21d145
3 changed files with 103 additions and 31 deletions

View File

@ -9,7 +9,7 @@ from click import Path as PathArgument
from click import argument, group, option, pass_context, pass_obj
from frontools.cache import Cache
from frontools.config import Config
from frontools.context import Context
from frontools.css import css_diff
from frontools.screenshot import screenshot_diff
@ -62,11 +62,15 @@ async def main(
exclude_urls: list[str],
) -> None:
"""Utilities for EO frontend development."""
ctx.obj = await Config.load(
ctx.obj = await Context.load(
config_file, source, not no_cache, include_urls, exclude_urls
)
def _on_close():
ctx.obj.print_error_summary()
ctx.call_on_close(_on_close)
@main.command(name="prune-caches")
@argument("cache_names", nargs=-1)
@ -79,12 +83,14 @@ def prune_caches(cache_names: list[str]) -> None:
@argument("right_source", type=str)
@pass_obj
@_async_command
async def css_diff_cli(config: Config, right_source: str) -> None:
async def css_diff_cli(context: Context, right_source: str) -> None:
"""Diff CSS"""
for _, site in config.sites:
for _, site in context.config.sites:
for site_url in site.urls:
await css_diff(
site_url, config.default_source, config.get_source(right_source)
site_url,
context.config.default_source,
context.config.get_source(right_source),
)
@ -95,13 +101,13 @@ async def css_diff_cli(config: Config, right_source: str) -> None:
@_async_command
@pass_obj
async def screenshot_diff_cli(
config: Config,
context: Context,
source: str,
output_directory: Optional[str],
resolution: Optional[str],
) -> None:
"""Generate screenshot diffs"""
await screenshot_diff(config, source, output_directory, resolution=resolution)
await screenshot_diff(context, source, output_directory, resolution=resolution)
if __name__ == "__main__":

43
frontools/context.py Normal file
View File

@ -0,0 +1,43 @@
"""Global context object"""
from pathlib import Path
from typing import Optional
from click import echo
from frontools.config import Config
class Context:
"""Configuration object"""
def __init__(self, config: Config) -> None:
"""Load config from the given path"""
self._config = config
self._errors: list[str] = []
@staticmethod
async def load(
config_path: Optional[Path],
default_source_name: Optional[str],
use_cache: bool,
include_urls: list[str],
exclude_urls: list[str],
) -> "Context":
config = await Config.load(
config_path, default_source_name, use_cache, include_urls, exclude_urls
)
return Context(config)
def add_error(self, message: str) -> None:
self._errors.append(message)
def print_error_summary(self) -> None:
echo("***** Error summary :")
for error in self._errors:
echo(error, err=True)
@property
def config(self) -> Config:
"""Get configuration object for this run"""
return self._config

View File

@ -3,9 +3,10 @@ from pathlib import Path
from tempfile import NamedTemporaryFile
from typing import Optional
from aiohttp import ClientConnectionError
from PIL import Image, ImageChops
from frontools import Config
from frontools.context import Context
from frontools.sources import Browser
from frontools.utils import (
get_default_screenshot_directory,
@ -15,12 +16,13 @@ from frontools.utils import (
async def screenshot_diff(
config: Config,
context: Context,
right_source_name: str,
output_directory: Optional[str],
resolution: Optional[str] = None,
) -> None:
"""Compare pages with or without local css"""
config = context.config
if output_directory is None:
output_path = get_default_screenshot_directory()
@ -42,7 +44,11 @@ async def screenshot_diff(
async with right_source.get_browser(
width=width, height=height
) as right_browser:
urls = [(site_name, url) for (site_name, site) in config.sites for url in site.urls]
urls = [
(site_name, url)
for (site_name, site) in config.sites
for url in site.urls
]
await report_progress(
"Screenshoting",
@ -50,7 +56,12 @@ async def screenshot_diff(
(
url,
_diff_url(
left_browser, right_browser, url, output_path, site_name
context,
left_browser,
right_browser,
url,
output_path,
site_name,
),
)
for (site_name, url) in urls
@ -59,35 +70,47 @@ async def screenshot_diff(
)
async def _diff_url(left: Browser, right: Browser, url: str, output_path: Path, site_name: str) -> None:
async def _diff_url(
context: Context,
left: Browser,
right: Browser,
url: str,
output_path: Path,
site_name: str,
) -> None:
try:
left_bytes = await _screenshot_url(left, url)
right_bytes = await _screenshot_url(right, url)
except ClientConnectionError as exception:
context.add_error(f'{site_name} : error while loading {url} : {exception}')
return
with NamedTemporaryFile(mode="wb") as left_file:
left_file.write(left_bytes)
left_image = Image.open(left_file.name).convert('RGB')
with NamedTemporaryFile(mode="wb") as left_file:
left_file.write(left_bytes)
left_image = Image.open(left_file.name).convert("RGB")
with NamedTemporaryFile(mode="wb") as right_file:
right_file.write(right_bytes)
right_image = Image.open(right_file.name).convert('RGB')
with NamedTemporaryFile(mode="wb") as right_file:
right_file.write(right_bytes)
right_image = Image.open(right_file.name).convert("RGB")
diff = ImageChops.difference(left_image, right_image)
diff = ImageChops.difference(left_image, right_image)
if not diff.getbbox():
return
if not diff.getbbox():
return
url_slug = get_url_slug(url)
if not output_path.is_dir():
output_path.mkdir()
url_slug = get_url_slug(url)
if not output_path.is_dir():
output_path.mkdir()
with open(output_path / f"{site_name}_{url_slug}_left", "wb") as screenshot_file:
screenshot_file.write(left_bytes)
with open(
output_path / f"{site_name}_{url_slug}_left", "wb"
) as screenshot_file:
screenshot_file.write(left_bytes)
with open(output_path / f"{site_name}_{url_slug}_right", "wb") as screenshot_file:
screenshot_file.write(right_bytes)
except Exception as ex:
print(f"Error while diffing {url} : {ex}")
with open(
output_path / f"{site_name}_{url_slug}_right", "wb"
) as screenshot_file:
screenshot_file.write(right_bytes)
async def _screenshot_url(browser: Browser, url: str) -> bytes: