Files
hermes-webui/tests/test_issue4325_virtualization_toggle.py
T
nesquena-hermes 1fc24ddf68 feat(#4241): add Vietnamese (vi) as 14th UI locale + wire parity
Maintainer-completed @thanhtantran's #4241 (Nathan approved bringing it in):
- vi locale block in static/i18n.js (contributor's 1615-line translation) rebased onto master.
- Added vi to _LOGIN_LOCALE in api/routes.py (login-page localization, issue #1442 parity).
- Bumped the per-locale hardcoded-count assertions 13->14 across the locale-parity
  tests (rtl, quota_chip, hide_suggestions, virtualize_transcript, no_git, help_tab,
  verdigris/zeus skins, auxiliary_models) and added 'vi' to the composer-voice-buttons
  LOCALES tuples. vi already carries all current English keys (verified 14x per key).
All 497 locale/parity tests pass. Co-authored-by: thanhtantran
2026-06-24 08:39:14 +00:00

135 lines
5.7 KiB
Python

"""Regression coverage for transcript virtualization preference (#4325 + #4343).
The stream-end freeze/jump fix (#4328, semantic viewport anchoring) is covered by
test_issue500_message_list_virtualization.py. This file covers the Preferences
toggle and its #4343 contract change:
- #4325 added an opt-OUT toggle (default ON).
- #4343 flipped it to EXPERIMENTAL / opt-IN (default OFF) because virtualization
caused a scroll-up flicker on long sessions, with a force-off-for-everyone
migration: a stored virtualize_transcript=True from the #4325 window is reset
to off unless an explicit post-flip opt-in marker (virtualize_transcript_optin)
is present.
"""
import json
from pathlib import Path
import pytest
REPO_ROOT = Path(__file__).resolve().parent.parent
INDEX = REPO_ROOT / "static" / "index.html"
PANELS = REPO_ROOT / "static" / "panels.js"
BOOT = REPO_ROOT / "static" / "boot.js"
UI = REPO_ROOT / "static" / "ui.js"
I18N = REPO_ROOT / "static" / "i18n.js"
CONFIG = REPO_ROOT / "api" / "config.py"
def test_virtualize_transcript_setting_is_default_off_and_allowed():
"""#4343 opt-IN model: default False (virtualization off), bool-allowlisted,
plus the opt-in migration marker."""
src = CONFIG.read_text(encoding="utf-8")
assert '"virtualize_transcript": False' in src, "must default OFF (experimental/opt-in)"
assert '"virtualize_transcript",' in src, "must be in _SETTINGS_BOOL_KEYS"
assert '"virtualize_transcript_optin": False' in src, "opt-in migration marker must exist + default False"
assert '"virtualize_transcript_optin",' in src, "opt-in marker must be in _SETTINGS_BOOL_KEYS"
def test_settings_preferences_expose_virtualize_toggle_experimental():
html = INDEX.read_text(encoding="utf-8")
assert 'id="settingsVirtualizeTranscript"' in html
assert 'data-i18n="settings_label_virtualize_transcript"' in html
assert 'data-i18n="settings_desc_virtualize_transcript"' in html
# #4343: checkbox must NOT render checked by default (opt-in, default off).
cb_line = next(l for l in html.splitlines() if 'id="settingsVirtualizeTranscript"' in l)
assert "checked" not in cb_line, "opt-in toggle must not be pre-checked"
def test_boot_applies_saved_virtualize_preference_default_off():
js = BOOT.read_text(encoding="utf-8")
# #4343 default-off semantics: ===true (only an explicit true enables it).
assert "window._virtualizeTranscript=s.virtualize_transcript===true" in js
# Settings-load-failed fallback also defaults OFF.
assert "window._virtualizeTranscript=false" in js
def test_ui_gate_forces_full_render_when_disabled():
js = UI.read_text(encoding="utf-8")
start = js.index("function _currentMessageVirtualWindow(")
body = js[start:start + 900]
assert "_virtualizeTranscript===false" in body
assert "virtualized:false" in body
def test_panels_round_trip_and_hot_apply_virtualize_toggle():
js = PANELS.read_text(encoding="utf-8")
assert "const virtualizeTranscriptCb=$('settingsVirtualizeTranscript');" in js
assert "payload.virtualize_transcript=virtualizeTranscriptCb.checked;" in js
# #4343: enabling records the explicit post-flip opt-in marker.
assert "payload.virtualize_transcript_optin=virtualizeTranscriptCb.checked;" in js
# #4343: checkbox load honors only an explicit opt-in (===true), not !==false.
assert "virtualizeTranscriptCb.checked=settings.virtualize_transcript===true;" in js
assert "window._virtualizeTranscript=virtualizeTranscriptCb.checked;" in js
# Hot-apply: toggling re-renders the open transcript immediately.
assert "renderMessages({preserveScroll:true})" in js
def test_virtualize_toggle_i18n_all_locales():
js = I18N.read_text(encoding="utf-8")
assert js.count("settings_label_virtualize_transcript:") == 14
assert js.count("settings_desc_virtualize_transcript:") == 14
# ── #4343 force-off-for-everyone migration (load_settings behavior) ──────────
@pytest.fixture
def _settings_env(tmp_path, monkeypatch):
"""Point load_settings at an isolated settings.json under tmp."""
import api.config as config
sf = tmp_path / "settings.json"
monkeypatch.setattr(config, "SETTINGS_FILE", sf)
return config, sf
def _write(sf, payload):
sf.write_text(json.dumps(payload), encoding="utf-8")
def test_migration_unset_defaults_off(_settings_env):
"""No stored value (fresh / pre-#4325 install) → off."""
config, sf = _settings_env
_write(sf, {"onboarding_completed": True})
assert config.load_settings()["virtualize_transcript"] is False
def test_migration_stale_pre_flip_true_is_reset_off(_settings_env):
"""A stored virtualize_transcript=True from the #4325 window WITHOUT the
opt-in marker is stale → force-reset to off for everyone."""
config, sf = _settings_env
_write(sf, {"onboarding_completed": True, "virtualize_transcript": True})
assert config.load_settings()["virtualize_transcript"] is False
def test_migration_explicit_post_flip_optin_is_honored(_settings_env):
"""An explicit post-flip opt-in (marker present) keeps virtualization on."""
config, sf = _settings_env
_write(sf, {
"onboarding_completed": True,
"virtualize_transcript": True,
"virtualize_transcript_optin": True,
})
assert config.load_settings()["virtualize_transcript"] is True
def test_migration_optin_marker_without_true_stays_off(_settings_env):
"""Marker present but value false (user opted in then back out) → off."""
config, sf = _settings_env
_write(sf, {
"onboarding_completed": True,
"virtualize_transcript": False,
"virtualize_transcript_optin": True,
})
assert config.load_settings()["virtualize_transcript"] is False