Files
Rpa_Skills/tests/test_palette.py
T

46 lines
2.1 KiB
Python

"""Custom palette: one brand hex in, light + dark accent tokens out, readable in both modes."""
import importlib.util
import subprocess
import sys
from pathlib import Path
PALETTE = Path(__file__).resolve().parents[1] / "skills" / "rpa-dashboard-no-ai" / "templates" / "palette.py"
spec = importlib.util.spec_from_file_location("palette", PALETTE)
palette = importlib.util.module_from_spec(spec)
spec.loader.exec_module(palette)
# Fixed Tebra Sky base colours the derived accents sit on (from dashboard.html).
LIGHT_BG, DARK_BG = "#eaf6fb", "#182a38"
LIGHT_INK, DARK_INK = "#1c2b33", "#e6eef4"
LOG_ERROR = "#f68c82" # dimmest log text colour
def contrast(a, b):
def lum(h):
c = [int(h[i:i + 2], 16) / 255 for i in (1, 3, 5)]
c = [x / 12.92 if x <= 0.03928 else ((x + 0.055) / 1.055) ** 2.4 for x in c]
return 0.2126 * c[0] + 0.7152 * c[1] + 0.0722 * c[2]
hi, lo = sorted([lum(a), lum(b)], reverse=True)
return (hi + 0.05) / (lo + 0.05)
def test_derived_palette_is_readable_in_light_and_dark():
for brand in ["#3d9bd0", "#ffd400", "#0b1f4d", "#7a3cff", "#e4002b", "#00a651", "#ffffff", "#000000"]:
t = palette.derive(brand)
for mode, bg, ink in [("light", LIGHT_BG, LIGHT_INK), ("dark", DARK_BG, DARK_INK)]:
m = t[mode]
assert contrast("#ffffff", m["--accent"]) >= 3, (brand, mode, "button text")
assert contrast("#ffffff", m["--accent-2"]) >= 3, (brand, mode, "button text, light end")
assert contrast(m["--accent"], bg) >= 3, (brand, mode, "accent text")
assert contrast(ink, m["--accent-soft"]) >= 4.5, (brand, mode, "secondary button text")
assert contrast(LOG_ERROR, m["--accent-dark"]) >= 4.5, (brand, mode, "log text")
def test_brand_kept_when_it_already_passes():
assert palette.derive("#1f6fb2")["light"]["--accent"] == "#1f6fb2"
def test_cli_prints_both_token_blocks_and_contrast_table():
out = subprocess.run([sys.executable, str(PALETTE), "#7a3cff"], capture_output=True, text=True, check=True).stdout
assert "body{" in out and "body.dark{" in out and "PASS" in out and "FAIL" not in out