fix: the favicon and nav brand mark rendered blank — "--" inside an XML comment
CI / lint (push) Successful in 2s
CI / extension-version (push) Successful in 2s
Build images / sign-extension (push) Successful in 4s
Build images / build-agent (push) Successful in 5s
Build images / build-ml (push) Successful in 7s
CI / frontend-build (push) Successful in 21s
CI / backend-lint-and-test (push) Successful in 32s
Build images / build-web (push) Successful in 1m8s
Build images / smoke-web (push) Skipped
Build images / promote (push) Skipped
CI / integration (push) Successful in 2m36s
CI / lint (push) Successful in 2s
CI / extension-version (push) Successful in 2s
Build images / sign-extension (push) Successful in 4s
Build images / build-agent (push) Successful in 5s
Build images / build-ml (push) Successful in 7s
CI / frontend-build (push) Successful in 21s
CI / backend-lint-and-test (push) Successful in 32s
Build images / build-web (push) Successful in 1m8s
Build images / smoke-web (push) Skipped
Build images / promote (push) Skipped
CI / integration (push) Successful in 2m36s
7ca6ee0's favicon.svg had a comment naming the `--fc-chrome-rgb` custom property. `--` is illegal inside an XML comment, so the file is not well-formed XML, and a browser renders an SVG-as-image only if it parses. It fails without any error, just a blank image. Because TopNav's brand glyph is the same file, the tab icon and the nav mark both went missing on the #251 deploy. logo.svg parses and was unaffected. The comment now names the property without the hyphens, and says why it has to. tests/test_public_svgs.py parses every SVG under frontend/public. It includes a vacuity guard (the directory really contains the two known files) and a positive control (the exact defect raises ParseError), so the check can actually fail. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SHQB1YukL3VyvMK8rcbmV9
This commit is contained in:
@@ -15,7 +15,10 @@
|
|||||||
Colours are theme tokens (frontend/src/theme/fabled-tokens.js): obsidian
|
Colours are theme tokens (frontend/src/theme/fabled-tokens.js): obsidian
|
||||||
plate, accent gold. The plate is kept here (unlike logo.svg) so the tab
|
plate, accent gold. The plate is kept here (unlike logo.svg) so the tab
|
||||||
icon is self-contained against any browser chrome; on the nav it is
|
icon is self-contained against any browser chrome; on the nav it is
|
||||||
invisible because it matches --fc-chrome-rgb exactly. -->
|
invisible because it matches the fc-chrome-rgb custom property exactly.
|
||||||
|
No double hyphen may appear inside this comment: XML forbids it, and a
|
||||||
|
browser refuses to render an SVG that does not parse (it happened once —
|
||||||
|
tests/test_public_svgs.py). -->
|
||||||
<rect width="32" height="32" rx="6" fill="#14171A"/>
|
<rect width="32" height="32" rx="6" fill="#14171A"/>
|
||||||
<rect x="6.2" y="4.2" width="19.6" height="23.6" rx="1.4"
|
<rect x="6.2" y="4.2" width="19.6" height="23.6" rx="1.4"
|
||||||
fill="none" stroke="#A87338" stroke-width="2.4"/>
|
fill="none" stroke="#A87338" stroke-width="2.4"/>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1,40 @@
|
|||||||
|
"""Every SVG the browser loads from `frontend/public/` must parse as XML.
|
||||||
|
|
||||||
|
A browser renders an SVG used as an image only if it is well-formed XML, and
|
||||||
|
when it is not, nothing reports it: no console error in most browsers, no
|
||||||
|
failed build, no failed request — the icon is simply blank. `favicon.svg`
|
||||||
|
shipped that way (merge #251) because its comment contained a CSS custom
|
||||||
|
property name, and `--` is illegal inside an XML comment. Both the tab icon and
|
||||||
|
the nav brand mark went missing, and only a person looking at the page noticed.
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
PUBLIC = Path(__file__).resolve().parent.parent / "frontend" / "public"
|
||||||
|
SVGS = sorted(PUBLIC.rglob("*.svg"))
|
||||||
|
|
||||||
|
|
||||||
|
def test_the_public_dir_has_svgs_to_check():
|
||||||
|
"""Guards the guard: a moved directory would otherwise pass vacuously."""
|
||||||
|
assert {p.name for p in SVGS} >= {"favicon.svg", "logo.svg"}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("svg", SVGS, ids=lambda p: p.name)
|
||||||
|
def test_svg_is_well_formed_xml(svg):
|
||||||
|
root = ET.parse(svg).getroot()
|
||||||
|
assert root.tag == "{http://www.w3.org/2000/svg}svg"
|
||||||
|
|
||||||
|
|
||||||
|
def test_the_parser_rejects_the_shape_that_broke_the_favicon():
|
||||||
|
"""Positive control: the exact defect must fail this parser, or the
|
||||||
|
parametrized test above proves nothing."""
|
||||||
|
broken = (
|
||||||
|
'<svg xmlns="http://www.w3.org/2000/svg">'
|
||||||
|
"<!-- matches --fc-chrome-rgb exactly --></svg>"
|
||||||
|
)
|
||||||
|
with pytest.raises(ET.ParseError):
|
||||||
|
ET.fromstring(broken)
|
||||||
Reference in New Issue
Block a user