Support multiple CSS files (#1079)

* Support multiple CSS paths

* Update a type to match docstring

* Ensure the demo app still works

* Use absolute paths in tests to (hopefully) appease Windows

* Notes about CSS changes in guide/docstrings, small grammar/typos fixes

* Move snapshot apps into snapshot_tests dir, improve messaging in snapshot output, add test for multiple css files interacting with classvar CSS

* Ensure consistent snapshot naming cross-platform

* Use rpartition instead of partition in import_app

* Fix handling of import_app when colon in arg

* Support paths containing Windows drive names in import_app

* Add note on new relative paths in snap_compare

* Update docs/guide/CSS.md

Co-authored-by: Will McGugan <willmcgugan@gmail.com>

* Fix formatting

* Update CHANGELOG to mention CSS_PATH supporting a list

Co-authored-by: Will McGugan <willmcgugan@gmail.com>
This commit is contained in:
darrenburns
2022-11-01 17:13:25 +00:00
committed by GitHub
parent 0403cfdc98
commit bbd811d671
19 changed files with 425 additions and 130 deletions

View File

@@ -6,7 +6,7 @@ from dataclasses import dataclass
from datetime import datetime
from operator import attrgetter
from os import PathLike
from pathlib import Path
from pathlib import Path, PurePath
from typing import Union, List, Optional, Callable, Iterable
import pytest
@@ -31,7 +31,7 @@ TEXTUAL_APP_KEY = pytest.StashKey[App]()
@pytest.fixture
def snap_compare(
snapshot: SnapshotAssertion, request: FixtureRequest
) -> Callable[[str], bool]:
) -> Callable[[str | PurePath], bool]:
"""
This fixture returns a function which can be used to compare the output of a Textual
app with the output of the same app in the past. This is snapshot testing, and it
@@ -39,7 +39,7 @@ def snap_compare(
"""
def compare(
app_path: str,
app_path: str | PurePath,
press: Iterable[str] = ("_",),
terminal_size: tuple[int, int] = (80, 24),
) -> bool:
@@ -50,7 +50,8 @@ def snap_compare(
the snapshot on disk will be updated to match the current screenshot.
Args:
app_path (str): The path of the app.
app_path (str): The path of the app. Relative paths are relative to the location of the
test this function is called from.
press (Iterable[str]): Key presses to run before taking screenshot. "_" is a short pause.
terminal_size (tuple[int, int]): A pair of integers (WIDTH, HEIGHT), representing terminal size.
@@ -58,7 +59,17 @@ def snap_compare(
bool: True if the screenshot matches the snapshot.
"""
node = request.node
app = import_app(app_path)
path = Path(app_path)
if path.is_absolute():
# If the user supplies an absolute path, just use it directly.
app = import_app(str(path.resolve()))
else:
# If a relative path is supplied by the user, it's relative to the location of the pytest node,
# NOT the location that `pytest` was invoked from.
node_path = node.path.parent
resolved = (node_path / app_path).resolve()
app = import_app(str(resolved))
actual_screenshot = take_svg_screenshot(
app=app,
press=press,
@@ -114,16 +125,19 @@ def pytest_sessionfinish(
actual_svg = item.stash.get(TEXTUAL_ACTUAL_SVG_KEY, None)
app = item.stash.get(TEXTUAL_APP_KEY, None)
if snapshot_svg and actual_svg and app:
if app:
path, line_index, name = item.reportinfo()
similarity = (
100
* difflib.SequenceMatcher(
a=str(snapshot_svg), b=str(actual_svg)
).ratio()
)
diffs.append(
SvgSnapshotDiff(
snapshot=str(snapshot_svg),
actual=str(actual_svg),
file_similarity=100
* difflib.SequenceMatcher(
a=str(snapshot_svg), b=str(actual_svg)
).ratio(),
file_similarity=similarity,
test_name=name,
path=path,
line_number=line_index + 1,