Files
C.E.L_Slide_test2/tests/test_imp49_partial_figma_provenance.py
kyeongmin 79f9ea5c92 feat(#78): IMP-49 dx_sw_necessity partial Figma provenance fix (u1~u3)
Replace eyeballed PROMOTED green hex (#296B55, #123328) with verbatim
upstream values from figma_to_html_agent/blocks/1171281198/index.html:
- border + check mark: #1d4d3e (upstream :208 -webkit-text-stroke)
- header gradient: rgb(15, 50, 30) / rgb(60, 52, 34) (upstream :54, :64)

Document .f20b__* as authoring-ordinal namespace (NOT Figma frame_id
1171281198); structural link via data-frame-id attribute. No selector
rename, no catalog edit.

Add focused regression test (tests/test_imp49_partial_figma_provenance.py)
extracting <style>-block hex/rgb/rgba literals and asserting non-whitelisted
literals exist byte-identically in upstream source. Whitelist limited to
neutrals (#fff, #1a1a1a) + shared zone-title token (#000, #883700,
rgba(50,44,30,0.4)).

Scope: dx_sw_necessity_three_perspectives.html only. 19 missing partials,
.fNb__ rename, full 32-contract audit deferred to follow-up axes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 02:49:43 +09:00

65 lines
2.4 KiB
Python

"""IMP-49 #78 — partial Figma provenance regression test.
For `templates/phase_z2/families/dx_sw_necessity_three_perspectives.html`,
extract color literals (hex + rgb/rgba, whitespace-preserving) from the
<style> block, then assert each non-whitelisted literal exists byte-identically
in `figma_to_html_agent/blocks/1171281198/index.html`.
Whitelist composition (per Stage 2 EXIT REPORT, IMP-49 #78):
- Neutrals: #fff, #1a1a1a (page-default text / surface)
- Shared zone-title token: #000, #883700, rgba(50,44,30,0.4)
(F13/F14/F12/F11/F18 zone-title family — not sourced from frame 20)
Guardrails:
- rgb()/rgba() literals matched as substrings, so whitespace (single space
after comma) is preserved byte-for-byte against upstream.
- Failure message surfaces the offending literal and the whitelist.
"""
from __future__ import annotations
import re
from pathlib import Path
PROJECT_ROOT = Path(__file__).parent.parent
PARTIAL_PATH = (
PROJECT_ROOT / "templates" / "phase_z2" / "families"
/ "dx_sw_necessity_three_perspectives.html"
)
UPSTREAM_PATH = (
PROJECT_ROOT / "figma_to_html_agent" / "blocks" / "1171281198" / "index.html"
)
COLOR_WHITELIST = frozenset({
"#fff",
"#1a1a1a",
"#000",
"#883700",
"rgba(50,44,30,0.4)",
})
HEX_RE = re.compile(r"#(?:[0-9a-fA-F]{8}|[0-9a-fA-F]{6}|[0-9a-fA-F]{4}|[0-9a-fA-F]{3})\b")
RGB_RE = re.compile(r"rgba?\([^)]*\)")
STYLE_RE = re.compile(r"<style>(.*?)</style>", re.DOTALL)
def _extract_style_block(html_text: str) -> str:
match = STYLE_RE.search(html_text)
assert match, f"partial {PARTIAL_PATH} must contain a <style> block"
return match.group(1)
def test_partial_color_literals_byte_identical_to_upstream() -> None:
partial_text = PARTIAL_PATH.read_text(encoding="utf-8")
upstream_text = UPSTREAM_PATH.read_text(encoding="utf-8")
css_text = _extract_style_block(partial_text)
literals = HEX_RE.findall(css_text) + RGB_RE.findall(css_text)
assert literals, "partial <style> must contain at least one color literal"
missing = sorted(
{lit for lit in literals if lit not in COLOR_WHITELIST and lit not in upstream_text}
)
assert not missing, (
"Non-whitelisted color literals in partial must be byte-identical to "
f"upstream {UPSTREAM_PATH.relative_to(PROJECT_ROOT)}. "
f"Missing: {missing}. Whitelist: {sorted(COLOR_WHITELIST)}."
)