Files
liaohch3--claude-tap/tests/test_viewer_i18n_source.py
wehub-resource-sync f3d80b4628
Auto Release / auto-release (push) Failing after 1s
CI / lint (push) Failing after 0s
CI / screenshot-quality (push) Failing after 3s
CI / pr-policy (push) Has been skipped
CI / test (3.11) (push) Failing after 0s
CI / test (3.12) (push) Failing after 0s
CI / test (3.13) (push) Failing after 3s
CI / coverage (push) Failing after 1s
Legibility / legibility (push) Failing after 3s
chore: import upstream snapshot with attribution
2026-07-13 12:31:48 +08:00

105 lines
3.1 KiB
Python

from __future__ import annotations
from pathlib import Path
from claude_tap.viewer import VIEWER_JS_PATHS, _generate_html_viewer, _load_viewer_i18n, _read_viewer_template
EXPECTED_LANGUAGES = ["en", "zh-CN", "ja", "ko", "fr", "ar", "de", "ru"]
CRITICAL_KEYS = [
"title",
"section_system",
"section_messages",
"section_tools",
"section_response",
"section_sse",
"section_json",
"empty_trace_title",
"diff_select_target",
]
def test_viewer_i18n_json_has_complete_language_key_sets() -> None:
entries = _load_viewer_i18n()
assert list(entries) == EXPECTED_LANGUAGES
source_keys = set(entries["en"])
assert len(source_keys) >= 40
for lang in EXPECTED_LANGUAGES:
assert set(entries[lang]) == source_keys
for key in CRITICAL_KEYS:
assert entries[lang][key]
def test_viewer_session_sort_label_uses_query_language() -> None:
entries = _load_viewer_i18n()
assert entries["en"]["sort_session"] == "Query"
assert entries["zh-CN"]["sort_session"] == "用户输入"
def test_read_viewer_template_embeds_i18n_before_main_script() -> None:
html = _read_viewer_template()
assert "const __CLAUDE_TAP_I18N__ =" in html
assert "const I18N = typeof __CLAUDE_TAP_I18N__" in html
assert '"section_system":"System Prompt"' in html
assert '"section_tools":"工具"' in html
assert html.index("const __CLAUDE_TAP_I18N__ =") < html.index("const $ = s =>")
assert "CLAUDE_TAP_VIEWER_STYLE" not in html
assert "CLAUDE_TAP_VIEWER_SCRIPT" not in html
assert "viewer_assets" not in html
def test_read_viewer_template_embeds_split_js_assets_in_order() -> None:
html = _read_viewer_template()
markers = [
"const $ = s =>",
"function expandWebSocketResponseEntries",
"function renderApp",
"function renderSidebar",
"function renderDetail",
"function renderContent",
"function renderJSONTree",
"function lineDiff",
"function mobileNext",
]
positions = [html.index(marker) for marker in markers]
assert positions == sorted(positions)
def test_split_viewer_js_assets_use_semantic_filenames() -> None:
names = [path.name for path in VIEWER_JS_PATHS]
assert names == [
"state.js",
"responses.js",
"lazy_loading.js",
"i18n_ui.js",
"live_bootstrap.js",
"filters_search.js",
"sidebar.js",
"detail_trace.js",
"renderers.js",
"sections_json.js",
"diff.js",
"utilities_mobile.js",
]
assert all(path.exists() for path in VIEWER_JS_PATHS)
assert all(not name[0].isdigit() for name in names)
def test_generate_html_viewer_remains_self_contained_after_i18n_split(tmp_path: Path) -> None:
trace_path = tmp_path / "empty.jsonl"
html_path = tmp_path / "empty.html"
trace_path.write_text("", encoding="utf-8")
_generate_html_viewer(trace_path, html_path)
html = html_path.read_text(encoding="utf-8")
assert "const __CLAUDE_TAP_I18N__ =" in html
assert "viewer_i18n.json" not in html
assert "No API calls captured" in html
assert "EMBEDDED_TRACE_COMPACT_DATA" in html