""" GUI smoke tests — headless PySide6 (QT_QPA_PLATFORM=offscreen). Verifies that all modules import and core widgets instantiate without crashing. No network calls, no DB, no real data. Run automatically via PostToolUse hook on every edit to screener_gui.py. """ import os import sys import subprocess from pathlib import Path PROJECT_ROOT = Path(__file__).parent.parent DIST_DIR = PROJECT_ROOT / "dist" PYTHON = sys.executable def _run(code: str) -> subprocess.CompletedProcess: """Run Python code in a subprocess with offscreen Qt platform.""" env = os.environ.copy() env["QT_QPA_PLATFORM"] = "offscreen" return subprocess.run( [PYTHON, "-c", code], capture_output=True, text=True, cwd=str(DIST_DIR), env=env, timeout=30, ) def test_stock_screener_imports(): """stock_screener.py imports and exposes expected symbols.""" result = _run(""" import stock_screener as ss required = [ 'compute_value_score', 'compute_quality_score', 'compute_growth_score', 'compute_profitability_score', 'compute_sentiment_score', 'score_stocks', 'STRATEGY_PRESETS', 'WEIGHTS', ] missing = [s for s in required if not hasattr(ss, s)] assert not missing, f"Missing symbols: {missing}" print("SCREENER_OK") """) assert "SCREENER_OK" in result.stdout, f"stock_screener import failed:\n{result.stderr}" def test_screener_gui_imports(): """screener_gui.py imports without error (PySide6, matplotlib, etc.).""" result = _run(""" from PySide6.QtWidgets import QApplication import sys app = QApplication(sys.argv) import screener_gui print("GUI_IMPORT_OK") """) assert "GUI_IMPORT_OK" in result.stdout, ( f"screener_gui import failed:\n{result.stderr[-2000:]}" ) def test_stock_table_model(): """StockTableModel can be created and populated via set_data.""" result = _run(""" import sys from PySide6.QtWidgets import QApplication app = QApplication(sys.argv) from screener_gui import StockTableModel model = StockTableModel() assert model.rowCount() == 0 model.set_data([("AAPL", "Apple Inc", 82.5, "Technology")]) assert model.rowCount() == 1 assert model.columnCount() == 5 print("TABLE_MODEL_OK") """) assert "TABLE_MODEL_OK" in result.stdout, ( f"StockTableModel test failed:\n{result.stderr[-2000:]}" ) def test_screener_app_instantiates(): """ScreenerApp (main window) instantiates without crashing.""" result = _run(""" import sys from PySide6.QtWidgets import QApplication app = QApplication(sys.argv) from screener_gui import ScreenerApp win = ScreenerApp() # Verify expected attributes exist assert hasattr(win, '_screener_page') assert hasattr(win, '_search_page') assert hasattr(win, '_sidebar') print("APP_OK") """) assert "APP_OK" in result.stdout, ( f"ScreenerApp instantiation failed:\n{result.stderr[-2000:]}" )