from __future__ import annotations import time from pathlib import Path from PIL import Image from tmux_shot import TmuxApp def test_session_is_created_and_idempotent_on_reattach(session_name: str, demo_app: TmuxApp) -> None: again = TmuxApp(session_name) # should attach, not recreate assert again.session.session_name == demo_app.session.session_name def test_capture_text_shows_initial_frame(demo_app: TmuxApp) -> None: time.sleep(0.3) text = demo_app.capture_text() assert "tmux-shot demo TUI" in text assert "@" in text def test_send_keys_multi_token_string_moves_cursor(demo_app: TmuxApp) -> None: """Regression test: a single send_keys("Down Down Right") call must be split into separate tmux key-name arguments, not sent as one literal string (which tmux would silently mis-send as garbage keystrokes that don't move anything).""" time.sleep(0.3) before = demo_app.capture_text() demo_app.send_keys("Down Down Right Right Right", enter=False) time.sleep(0.3) after = demo_app.capture_text() assert before != after after_lines = [l for l in after.splitlines() if "@" in l] assert after_lines, "cursor marker should still be present somewhere" def test_send_keys_literal_types_text_verbatim(demo_app: TmuxApp) -> None: # 'q' quits the demo curses app back to the underlying shell. time.sleep(0.3) assert "tmux-shot demo TUI" in demo_app.capture_text() demo_app.send_keys("q", literal=True, enter=False) time.sleep(0.5) assert "tmux-shot demo TUI" not in demo_app.capture_text() def test_screenshot_produces_a_valid_sized_png(demo_app: TmuxApp, out_dir: Path) -> None: time.sleep(0.3) path = demo_app.screenshot(out_dir / "shot.png") img = Image.open(path) assert img.width > 0 and img.height > 0 # 80 cols x 24 rows pane assert img.width % 80 == 0 assert img.height % 24 == 0 def test_capture_ansi_includes_escape_codes(demo_app: TmuxApp) -> None: time.sleep(0.3) ansi = demo_app.capture_ansi() assert "\x1b[" in ansi