Files
notplanned/ventures/preview-sidecar/test_sidecar.py
T
claudeandClaude Sonnet 5 029323fe97 Build standalone preview-sidecar tool and receipt-styled landing page
Localhost port watcher: detects a newly bound dev-server port via
bounded TCP probing, opens an iframe preview pane, and captures a
one-click timestamped screenshot receipt via headless Chrome. No
Claude Code changes, stdlib-only, 16 passing tests plus a real
end-to-end dogfood (demo.py) with a genuine recorded screenshot.

Landing page at ventures/preview-sidecar/site/index.html uses a
receipt/ticket visual identity (narrow thermal-paper column, dotted
rules, wax stamp, monospace totals) distinct from the finishline
venture, with one above-the-fold signup CTA and an honest free/paid
pricing section.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-10 10:36:31 -07:00

114 lines
4.1 KiB
Python

#!/usr/bin/env python3
import socket
import tempfile
import unittest
from pathlib import Path
from unittest import mock
import sidecar
class ParsePorts(unittest.TestCase):
def test_default_when_nothing_given(self):
self.assertEqual(sidecar.parse_ports(None, None), sorted(sidecar.DEFAULT_PORTS))
def test_explicit_list(self):
self.assertEqual(sidecar.parse_ports("3000,3000,5173", None), [3000, 5173])
def test_range(self):
self.assertEqual(sidecar.parse_ports(None, "3000-3003"), [3000, 3001, 3002, 3003])
def test_range_too_wide_rejected(self):
with self.assertRaises(ValueError):
sidecar.parse_ports(None, f"1-{sidecar.MAX_PORTS + 50}")
def test_bad_port_rejected(self):
with self.assertRaises(ValueError):
sidecar.parse_ports("70000", None)
class ProbeAndDiff(unittest.TestCase):
def test_probe_detects_a_real_listener(self):
srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
srv.bind(("127.0.0.1", 0))
srv.listen(1)
port = srv.getsockname()[1]
try:
self.assertTrue(sidecar.probe_port("127.0.0.1", port))
finally:
srv.close()
def test_probe_false_for_closed_port(self):
srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
srv.bind(("127.0.0.1", 0))
port = srv.getsockname()[1]
srv.close()
self.assertFalse(sidecar.probe_port("127.0.0.1", port, timeout=0.2))
def test_diff_new_only_reports_additions(self):
self.assertEqual(sidecar.diff_new({3000}, {3000, 5173}), {5173})
self.assertEqual(sidecar.diff_new({3000, 5173}, {5173}), set())
class PreviewHtml(unittest.TestCase):
def test_render_contains_iframe_and_url(self):
html = sidecar.render_preview_html("127.0.0.1", 5173, "2026-01-01T00:00:00Z")
self.assertIn("http://127.0.0.1:5173", html)
self.assertIn("<iframe", html)
self.assertIn("open in new tab", html)
def test_write_preview_creates_file(self):
with tempfile.TemporaryDirectory() as tmp:
path, detected_at = sidecar.write_preview(tmp, "127.0.0.1", 4200)
self.assertTrue(path.exists())
self.assertIn("4200", path.name)
self.assertIn("http://127.0.0.1:4200", path.read_text())
self.assertRegex(detected_at, r"^\d{4}-\d{2}-\d{2}T")
class FindChrome(unittest.TestCase):
def test_explicit_path_wins_when_present(self):
with tempfile.TemporaryDirectory() as tmp:
fake = Path(tmp) / "chrome-bin"
fake.write_text("")
self.assertEqual(sidecar.find_chrome(str(fake)), str(fake))
def test_explicit_missing_path_returns_none(self):
self.assertIsNone(sidecar.find_chrome("/definitely/not/a/real/chrome/binary"))
def test_env_var_used_when_set(self):
with tempfile.TemporaryDirectory() as tmp:
fake = Path(tmp) / "chrome-env"
fake.write_text("")
with mock.patch.dict("os.environ", {"CHROME_PATH": str(fake)}):
self.assertEqual(sidecar.find_chrome(), str(fake))
def test_none_when_nothing_found(self):
with mock.patch.object(sidecar, "CHROME_CANDIDATES", ["/nope/not/here"]), \
mock.patch.dict("os.environ", {}, clear=True):
self.assertIsNone(sidecar.find_chrome())
class MakeReceiptErrors(unittest.TestCase):
def test_raises_when_port_not_open(self):
with tempfile.TemporaryDirectory() as tmp:
with self.assertRaises(RuntimeError):
sidecar.make_receipt("127.0.0.1", 1, tmp, None, 5)
def test_raises_when_no_chrome_found(self):
srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
srv.bind(("127.0.0.1", 0))
srv.listen(1)
port = srv.getsockname()[1]
try:
with tempfile.TemporaryDirectory() as tmp:
with mock.patch.object(sidecar, "find_chrome", return_value=None):
with self.assertRaises(RuntimeError):
sidecar.make_receipt("127.0.0.1", port, tmp, None, 5)
finally:
srv.close()
if __name__ == "__main__":
unittest.main()