import json import os import shutil import subprocess import sys import time import unittest sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "files")) import claude_agents as ca # noqa: E402 class Page(unittest.TestCase): def test_page_applies_saved_bg_before_body(self): html = ca.render_page() body = html.index("") self.assertLess(html.index("claude-panel-bg"), body) self.assertIn(ca.CLIENT_COLORS_JS, html) self.assertIn("try {", html[:body]) def test_page_has_bg_controls(self): html = ca.render_page() for marker in ('id="bgctl"', 'id="gear"', 'id="bgrow"', 'type="color"', 'id="bg-reset"'): self.assertIn(marker, html) self.assertEqual(ca.BG_PRESETS, ("#002b36", "#1e1e1e", "#000000", "#2b2b3a", "#fdf6e3")) for hex_ in ca.BG_PRESETS: self.assertIn(f'data-bg="{hex_}"', html) limits_end = html.index('
') + len('
') + len(ca.render_limits()) self.assertGreater(html.index('id="bgctl"'), limits_end) def test_reload_skipped_while_colour_row_open(self): html = ca.render_page() self.assertIn("if (!cur && !bgrow.classList.contains('open')) location.reload()", html) self.assertLess(html.index("const gear = document.getElementById('gear'), bgrow"), html.index("location.reload()")) def test_limits_refresh_reads_body_before_moving_gear(self): html = ca.render_page() start = html.index("async function refreshLimits") body = html[start:html.index("setInterval(refreshLimits")] self.assertLess(body.index("await r.text()"), body.index("appendChild(gear)")) class Limits(unittest.TestCase): def setUp(self): self.saved = dict(ca.state) def tearDown(self): ca.state.clear() ca.state.update(self.saved) def test_limits_foot_has_gear_slot(self): ca.state["usage_updated"], ca.state["usage_error"] = time.time(), None self.assertIn('class="gear-slot"', ca.render_limits()) @unittest.skipUnless(shutil.which("node"), "нет node") class ClientColors(unittest.TestCase): def test_panel_colors_js(self): js = ca.CLIENT_COLORS_JS + ( "\nconsole.log(JSON.stringify([panelColors('#fdf6e3'), panelColors('#000000')," " panelColors('nope'), panelColors('#002b36')]))") out = subprocess.run(["node", "-e", js], capture_output=True, text=True, check=True).stdout self.assertEqual(json.loads(out), [ {"bg": "#fdf6e3", "fg": "#3b4a50", "dim": "#898f8b"}, {"bg": "#000000", "fg": "#aacace", "dim": "#66797c"}, None, {"bg": "#002b36", "fg": "#aacace", "dim": "#668a91"}, ]) def test_text_colour_by_contrast(self): cases = {"#a0a0a0": "#3b4a50", "#999999": "#3b4a50", "#6699cc": "#3b4a50", "#333333": "#aacace"} js = ca.CLIENT_COLORS_JS + ( "\nconsole.log(JSON.stringify(%s.map(c => panelColors(c).fg)))" % json.dumps(list(cases))) out = subprocess.run(["node", "-e", js], capture_output=True, text=True, check=True).stdout self.assertEqual(json.loads(out), list(cases.values())) if __name__ == "__main__": unittest.main()