from pathlib import Path import unittest from streamlit.testing.v1 import AppTest APP_PATH = str(Path(__file__).resolve().parent.parent / "streamlit_app" / "app.py") class TestStreamlitNBAApp(unittest.TestCase): def test_entrypoint_and_all_pages_render(self): at = AppTest.from_file(APP_PATH, default_timeout=15).run() self.assertFalse(at.exception, f"Entrypoint failed: {at.exception}") self.assertIn("League Pulse", at.title[0].value) pages = [ ("app_pages/shot_charts.py", "Shot Studio"), ("app_pages/teams.py", "Team Intelligence"), ("app_pages/player_lab.py", "Player Lab"), ("app_pages/head_to_head.py", "Matchup Center"), ("app_pages/game_trends.py", "Era Trends"), ("app_pages/quarter_analysis.py", "Momentum"), ] for page_path, expected_title in pages: at.switch_page(page_path).run(timeout=15) self.assertFalse(at.exception, f"Page {page_path} failed: {at.exception}") self.assertIn(expected_title, at.title[0].value) def test_shot_studio_filters_and_metrics(self): at = AppTest.from_file(APP_PATH, default_timeout=15).run() at.switch_page("app_pages/shot_charts.py").run(timeout=15) self.assertFalse(at.exception) # Verify 4 summary KPI metrics are rendered on the Shot Chart tab metric_labels = [m.label for m in at.metric] self.assertIn("Field Goal Attempts", metric_labels) self.assertIn("FG% / eFG%", metric_labels) self.assertIn("3-Point Accuracy", metric_labels) self.assertIn("Points Per Shot", metric_labels) # Filter to Q4 shots and Made outcome via segmented_control at.button_group(key="shot_period_filter").select("Q4").run(timeout=15) self.assertFalse(at.exception) at.button_group(key="shot_outcome_filter").select("Made").run(timeout=15) self.assertFalse(at.exception) self.assertEqual(at.metric[1].value, "100.0%") if __name__ == "__main__": unittest.main()