From f5e8d74d06a2a5cd2cfff084466cdc695e718202 Mon Sep 17 00:00:00 2001 From: Mouna Cheikho Date: Tue, 1 Sep 2026 15:53:22 +0400 Subject: [PATCH 1/2] Upgraded Streamlit to 1.62 --- .streamlit/config.dark.toml | 3 +- .streamlit/config.toml | 3 +- pyproject.toml | 2 +- requirements.txt | 6 ++-- tests/test_settings_enterprise_mode.py | 19 +++++++---- .../test_streamlit_app_backend_integration.py | 32 ++++++++++-------- tests/test_streamlit_app_basic.py | 8 +++-- tests/test_streamlit_app_data_display.py | 33 +++++++++---------- tests/test_streamlit_app_file_selection.py | 24 +++++++------- tests/test_streamlit_app_processing_steps.py | 17 ++++------ tests/test_streamlit_app_questions.py | 10 ++++-- tests/test_streamlit_app_tabs.py | 33 ++++++++----------- tests/test_streamlit_app_upload.py | 8 +++-- 13 files changed, 105 insertions(+), 93 deletions(-) diff --git a/.streamlit/config.dark.toml b/.streamlit/config.dark.toml index 382a005bd..32120a557 100644 --- a/.streamlit/config.dark.toml +++ b/.streamlit/config.dark.toml @@ -1,6 +1,6 @@ [server] headless = true -enableCORS = false +enableCORS = true enableXsrfProtection = true [browser] @@ -13,4 +13,3 @@ backgroundColor = "#222222" secondaryBackgroundColor = "#1E1E1E" textColor = "#D0CDE8" font = "sans serif" - diff --git a/.streamlit/config.toml b/.streamlit/config.toml index 42561d49a..64b19ee71 100644 --- a/.streamlit/config.toml +++ b/.streamlit/config.toml @@ -1,6 +1,6 @@ [server] headless = true -enableCORS = false +enableCORS = true enableXsrfProtection = true [browser] @@ -14,4 +14,3 @@ secondaryBackgroundColor = "#FFFFFF" textColor = "#170843" font = "sans serif" - diff --git a/pyproject.toml b/pyproject.toml index bb849e582..b6828fab2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ name = "report-analyst" version = "0.8.0rc" description = "Open Sustainability Analyst - benchmark evaluation, error analysis, and dataset loading for retrieval evaluation" readme = "README.md" -requires-python = ">=3.8" +requires-python = ">=3.10" dependencies = [ "pandas", "numpy", diff --git a/requirements.txt b/requirements.txt index 7c996efc3..21ce5d981 100644 --- a/requirements.txt +++ b/requirements.txt @@ -66,6 +66,7 @@ importlib_metadata==7.2.1 importlib_resources==6.5.2 iniconfig==2.0.0 isort==6.0.1 +itsdangerous==2.2.0 Jinja2==3.1.6 jiter==0.8.2 joblib==1.4.2 @@ -183,7 +184,7 @@ sqlean.py==3.47.0 sqlite-vec==0.1.6 sqlite-vss==0.1.2 starlette==1.3.1 -streamlit==1.54.0 +streamlit==1.62.0 streamlit-card==1.0.2 streamlit-option-menu==0.4.0 striprtf==0.0.26 @@ -202,10 +203,11 @@ typing_extensions==4.12.2 tzdata==2025.1 tzlocal==5.2 urllib3==2.7.0 -uvicorn==0.27.1 +uvicorn==0.52.4 uvloop==0.21.0 validators==0.34.0 vectors==1.0.0 +watchdog==6.0.0 watchfiles==1.0.4 websocket-client==1.8.0 websockets==15.0.1 diff --git a/tests/test_settings_enterprise_mode.py b/tests/test_settings_enterprise_mode.py index b3bc74a1e..84a7d73fd 100644 --- a/tests/test_settings_enterprise_mode.py +++ b/tests/test_settings_enterprise_mode.py @@ -7,16 +7,19 @@ """ import os +from pathlib import Path from unittest.mock import patch from streamlit.testing.v1 import AppTest +APP_PATH = Path(__file__).resolve().parents[1] / "report_analyst" / "streamlit_app.py" + def test_enterprise_mode_message_only_when_checked(): """Test that enterprise mode message only shows when checkbox is checked""" # Run without USE_S3_UPLOAD env var to test checkbox behavior with patch.dict(os.environ, {"USE_S3_UPLOAD": "false"}, clear=False): - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.run(timeout=10) # Navigate to Settings page @@ -40,8 +43,9 @@ def test_enterprise_mode_message_only_when_checked(): # After unchecking, the message should NOT appear page_text = str(at) - if "Enterprise mode enabled" in page_text: - assert False, "Enterprise mode message should not appear when checkbox is unchecked" + assert ( + "Enterprise mode enabled" not in page_text + ), "Enterprise mode message should not appear when checkbox is unchecked" # Now check the checkbox checkbox.set_value(True) @@ -55,7 +59,7 @@ def test_enterprise_mode_checkbox_state_persistence(): """Test that checkbox state persists correctly across reruns""" # Run without USE_S3_UPLOAD env var to test checkbox behavior with patch.dict(os.environ, {"USE_S3_UPLOAD": "false"}, clear=False): - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.run(timeout=10) # Navigate to Settings @@ -79,8 +83,9 @@ def test_enterprise_mode_checkbox_state_persistence(): # Check that enterprise mode message is NOT shown when unchecked page_text = str(at) - if "Enterprise mode enabled" in page_text: - assert False, "Enterprise mode message should NOT appear when checkbox is unchecked" + assert ( + "Enterprise mode enabled" not in page_text + ), "Enterprise mode message should NOT appear when checkbox is unchecked" # Rerun - state should persist at.run(timeout=10) @@ -93,7 +98,7 @@ def test_enterprise_mode_env_var_detection(): # When USE_S3_UPLOAD=true is in env, session state should be True env_value = os.getenv("USE_S3_UPLOAD", "false").lower() == "true" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.run(timeout=10) # Navigate to Settings diff --git a/tests/test_streamlit_app_backend_integration.py b/tests/test_streamlit_app_backend_integration.py index 1ebbfdde9..6ca6079ea 100644 --- a/tests/test_streamlit_app_backend_integration.py +++ b/tests/test_streamlit_app_backend_integration.py @@ -3,12 +3,16 @@ Tests backend integration availability and functionality. """ +from pathlib import Path + from streamlit.testing.v1 import AppTest +APP_PATH = Path(__file__).resolve().parents[1] / "report_analyst" / "streamlit_app.py" + def test_backend_integration_availability(): """Test that backend integration features are available""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.run(timeout=10) # The app should load without errors, indicating backend integration is available @@ -20,7 +24,7 @@ def test_backend_integration_availability(): def test_backend_configuration_display(): """Test backend configuration display""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.run(timeout=10) # Check for backend configuration elements @@ -32,7 +36,7 @@ def test_backend_configuration_display(): def test_backend_flow_orchestrator(): """Test backend flow orchestrator functionality""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.run(timeout=10) # Check that backend flow orchestrator is properly integrated @@ -43,7 +47,7 @@ def test_backend_flow_orchestrator(): def test_backend_analysis_workflow(): """Test backend analysis workflow integration""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.run(timeout=10) # Check for backend analysis workflow elements @@ -55,7 +59,7 @@ def test_backend_analysis_workflow(): def test_backend_error_handling(): """Test backend integration error handling""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.run(timeout=10) # Backend integration should handle errors gracefully @@ -66,7 +70,7 @@ def test_backend_error_handling(): def test_backend_fallback_behavior(): """Test backend integration fallback behavior""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.run(timeout=10) # Backend integration should have proper fallback behavior @@ -78,7 +82,7 @@ def test_backend_fallback_behavior(): def test_backend_config_status(): """Test backend configuration status display""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.run(timeout=10) # Check for backend configuration status elements @@ -90,7 +94,7 @@ def test_backend_config_status(): def test_backend_processing_result(): """Test backend processing result handling""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.run(timeout=10) # Check that backend processing results are handled properly @@ -101,7 +105,7 @@ def test_backend_processing_result(): def test_backend_analysis_result(): """Test backend analysis result integration""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.run(timeout=10) # Check for backend analysis result handling @@ -112,7 +116,7 @@ def test_backend_analysis_result(): def test_backend_integration_imports(): """Test that backend integration imports work correctly""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.run(timeout=10) # Backend integration imports should work without errors @@ -123,7 +127,7 @@ def test_backend_integration_imports(): def test_backend_flow_selection(): """Test backend flow selection functionality""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.run(timeout=10) # Check for backend flow selection elements @@ -135,7 +139,7 @@ def test_backend_flow_selection(): def test_backend_local_analysis(): """Test backend local analysis functionality""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.run(timeout=10) # Check for backend local analysis capabilities @@ -146,7 +150,7 @@ def test_backend_local_analysis(): def test_backend_integration_compatibility(): """Test backend integration compatibility with main app""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.run(timeout=10) # Backend integration should be compatible with the main app @@ -168,7 +172,7 @@ def test_backend_resource_full_roundtrip(): """Test full roundtrip: list backend resources, select, retrieve chunks, analyze""" from unittest.mock import Mock, patch - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) # Mock backend configuration mock_backend_config = Mock() diff --git a/tests/test_streamlit_app_basic.py b/tests/test_streamlit_app_basic.py index 9bc615e6f..26687b936 100644 --- a/tests/test_streamlit_app_basic.py +++ b/tests/test_streamlit_app_basic.py @@ -3,19 +3,23 @@ Tests app loading, title, and layout elements. """ +from pathlib import Path + from streamlit.testing.v1 import AppTest +APP_PATH = Path(__file__).resolve().parents[1] / "report_analyst" / "streamlit_app.py" + def test_app_loads(): """Test that streamlit_app.py loads without errors""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.run(timeout=10) # Increase timeout assert not at.exception def test_app_title_and_layout(): """Test app displays correct title and basic layout""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) # Navigate to Report Analyst page where title is displayed at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) # Increase timeout diff --git a/tests/test_streamlit_app_data_display.py b/tests/test_streamlit_app_data_display.py index f13974d6d..296b2b971 100644 --- a/tests/test_streamlit_app_data_display.py +++ b/tests/test_streamlit_app_data_display.py @@ -3,12 +3,16 @@ Tests dataframes, charts, and result display functionality. """ +from pathlib import Path + from streamlit.testing.v1 import AppTest +APP_PATH = Path(__file__).resolve().parents[1] / "report_analyst" / "streamlit_app.py" + def test_dataframe_display_capability(): """Test that the app can display dataframes""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.run(timeout=10) # The app should load without errors, indicating dataframe display capability @@ -20,7 +24,7 @@ def test_dataframe_display_capability(): def test_analysis_results_structure(): """Test that analysis results structure is properly set up""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.run(timeout=10) # Check for placeholder elements that would be used for results @@ -35,16 +39,9 @@ def test_analysis_results_structure(): def test_file_history_functionality(): """Test file history and previous reports functionality""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.run(timeout=10) - # Check for file history selectbox - has_file_history = False - for sb in at.selectbox: - if "previously analyzed" in str(sb.label).lower() or "previous_file" in str(sb.key): - has_file_history = True - break - # File history might not be visible if no previous files exist # This is expected behavior, so we just verify the app loads correctly assert not at.exception @@ -52,7 +49,7 @@ def test_file_history_functionality(): def test_question_display_functionality(): """Test question display and selection functionality""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) # Navigate to Report Analyst page where questions are displayed at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -73,7 +70,7 @@ def test_question_display_functionality(): def test_model_selection_display(): """Test LLM model selection display""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) # Navigate to Report Analyst page where model selection is located at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -95,7 +92,7 @@ def test_model_selection_display(): def test_configuration_display(): """Test configuration parameter display""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) # Navigate to Report Analyst page where configuration widgets are located at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -118,7 +115,7 @@ def test_configuration_display(): def test_analysis_controls_display(): """Test analysis control options display""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) # Navigate to Report Analyst page where analysis controls are located at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -143,7 +140,7 @@ def test_analysis_controls_display(): def test_error_handling_display(): """Test error handling and display capabilities""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.run(timeout=10) # The app should handle errors gracefully and display them @@ -157,7 +154,7 @@ def test_error_handling_display(): def test_consolidated_results_display(): """Test All Results page display functionality (previously called Consolidated Results)""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) # Navigate to All Results page at.session_state["nav_page"] = "All Results" at.run(timeout=10) @@ -178,7 +175,7 @@ def test_consolidated_results_display(): def test_app_layout_and_structure(): """Test overall app layout and structure""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.run(timeout=10) # Check that navigation page is set in session state @@ -200,7 +197,7 @@ def test_app_layout_and_structure(): def test_dynamic_content_loading(): """Test dynamic content loading capabilities""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) # Navigate to Report Analyst page where question sets are displayed at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) diff --git a/tests/test_streamlit_app_file_selection.py b/tests/test_streamlit_app_file_selection.py index 4eb10ed13..fb63aeb22 100644 --- a/tests/test_streamlit_app_file_selection.py +++ b/tests/test_streamlit_app_file_selection.py @@ -8,15 +8,21 @@ from streamlit.testing.v1 import AppTest +APP_PATH = Path(__file__).resolve().parents[1] / "report_analyst" / "streamlit_app.py" +TEST_PDF = ( + b"%PDF-1.4\n%Test PDF\n1 0 obj\n<< /Type /Catalog /Pages 2 0 R >>\nendobj\n" + b"2 0 obj\n<< /Type /Pages /Kids [3 0 R] /Count 1 >>\nendobj\n" + b"3 0 obj\n<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] >>\nendobj\n" + b"xref\n0 4\ntrailer\n<< /Size 4 /Root 1 0 R >>\nstartxref\n100\n%%EOF" +) + def test_file_selection_with_file_uri(): """Test that file selection works correctly with file:// URIs""" # Create a temporary PDF file with tempfile.TemporaryDirectory() as temp_dir: test_pdf = Path(temp_dir) / "test_report.pdf" - test_pdf.write_bytes( - b"%PDF-1.4\n%Test PDF\n1 0 obj\n<< /Type /Catalog /Pages 2 0 R >>\nendobj\n2 0 obj\n<< /Type /Pages /Kids [3 0 R] /Count 1 >>\nendobj\n3 0 obj\n<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] >>\nendobj\nxref\n0 4\ntrailer\n<< /Size 4 /Root 1 0 R >>\nstartxref\n100\n%%EOF" - ) + test_pdf.write_bytes(TEST_PDF) # Set temp directory in environment import os @@ -25,7 +31,7 @@ def test_file_selection_with_file_uri(): os.environ["TEMP_DIR"] = str(temp_dir) try: - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -63,9 +69,7 @@ def test_file_path_resolution_from_uri(): # Create a temporary PDF file with tempfile.TemporaryDirectory() as temp_dir: test_pdf = Path(temp_dir) / "test_report.pdf" - test_pdf.write_bytes( - b"%PDF-1.4\n%Test PDF\n1 0 obj\n<< /Type /Catalog /Pages 2 0 R >>\nendobj\n2 0 obj\n<< /Type /Pages /Kids [3 0 R] /Count 1 >>\nendobj\n3 0 obj\n<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] >>\nendobj\nxref\n0 4\ntrailer\n<< /Size 4 /Root 1 0 R >>\nstartxref\n100\n%%EOF" - ) + test_pdf.write_bytes(TEST_PDF) # Set temp directory in environment import os @@ -109,9 +113,7 @@ def test_file_not_found_error_not_shown(): # Create a temporary PDF file with tempfile.TemporaryDirectory() as temp_dir: test_pdf = Path(temp_dir) / "test_report.pdf" - test_pdf.write_bytes( - b"%PDF-1.4\n%Test PDF\n1 0 obj\n<< /Type /Catalog /Pages 2 0 R >>\nendobj\n2 0 obj\n<< /Type /Pages /Kids [3 0 R] /Count 1 >>\nendobj\n3 0 obj\n<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] >>\nendobj\nxref\n0 4\ntrailer\n<< /Size 4 /Root 1 0 R >>\nstartxref\n100\n%%EOF" - ) + test_pdf.write_bytes(TEST_PDF) # Set temp directory in environment import os @@ -120,7 +122,7 @@ def test_file_not_found_error_not_shown(): os.environ["TEMP_DIR"] = str(temp_dir) try: - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) diff --git a/tests/test_streamlit_app_processing_steps.py b/tests/test_streamlit_app_processing_steps.py index 1bdf13e4b..b0ea8f4d2 100644 --- a/tests/test_streamlit_app_processing_steps.py +++ b/tests/test_streamlit_app_processing_steps.py @@ -3,12 +3,16 @@ Tests that the slider exists, is interactive, and controls step selection. """ +from pathlib import Path + from streamlit.testing.v1 import AppTest +APP_PATH = Path(__file__).resolve().parents[1] / "report_analyst" / "streamlit_app.py" + def test_processing_steps_slider_exists(): """Test that Processing Steps slider is present""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -30,7 +34,7 @@ def test_processing_steps_slider_exists(): def test_processing_steps_slider_interactive(): """Test that Processing Steps slider is interactive""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -52,7 +56,7 @@ def test_processing_steps_slider_interactive(): def test_processing_steps_displayed(): """Test that Processing Steps are displayed with correct labels""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -60,13 +64,6 @@ def test_processing_steps_displayed(): # This is verified by the app loading without errors assert not at.exception, "App should load without errors" - # Check for Processing Steps heading - has_processing_steps = False - for header in at.header: - if "Processing Steps" in str(header.value): - has_processing_steps = True - break - # Processing Steps might only show when a file is selected # So we just verify the app loads correctly assert not at.exception diff --git a/tests/test_streamlit_app_questions.py b/tests/test_streamlit_app_questions.py index dde571ece..8fc431eae 100644 --- a/tests/test_streamlit_app_questions.py +++ b/tests/test_streamlit_app_questions.py @@ -3,12 +3,16 @@ Tests dynamic question loading and selection. """ +from pathlib import Path + from streamlit.testing.v1 import AppTest +APP_PATH = Path(__file__).resolve().parents[1] / "report_analyst" / "streamlit_app.py" + def test_question_set_selectbox_exists(): """Test question set selectbox is present""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) # Navigate to Report Analyst page where question set selectbox is located at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -26,7 +30,7 @@ def test_question_set_selectbox_exists(): def test_question_sets_loaded_dynamically(): """Test question sets loaded from question_loader""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) # Navigate to Report Analyst page where question set selectbox is located at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -48,7 +52,7 @@ def test_question_sets_loaded_dynamically(): def test_question_set_selectbox_has_options(): """Test question set selectbox has multiple options available""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) # Navigate to Report Analyst page where question set selectbox is located at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) diff --git a/tests/test_streamlit_app_tabs.py b/tests/test_streamlit_app_tabs.py index cfbd0bb0e..bdddfec40 100644 --- a/tests/test_streamlit_app_tabs.py +++ b/tests/test_streamlit_app_tabs.py @@ -3,12 +3,16 @@ Tests Previous Reports, Upload New, and Consolidated Results tabs. """ +from pathlib import Path + from streamlit.testing.v1 import AppTest +APP_PATH = Path(__file__).resolve().parents[1] / "report_analyst" / "streamlit_app.py" + def test_tabs_exist(): """Test that all three main navigation pages are present""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.run(timeout=10) # Check that navigation page is set in session state @@ -29,7 +33,7 @@ def test_tabs_exist(): def test_previous_reports_tab(): """Test Report Analyst page functionality (previously called Previous Reports)""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) # Navigate to Report Analyst page at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -37,13 +41,6 @@ def test_previous_reports_tab(): # Check that we're on the Report Analyst page assert at.session_state["nav_page"] == "Report Analyst", "Not on Report Analyst page" - # Check if selectbox for previous files exists - has_file_selectbox = False - for sb in at.selectbox: - if "previously analyzed report" in str(sb.label).lower() or "previous_file" in str(sb.key): - has_file_selectbox = True - break - # The selectbox might not be visible if no previous files exist # This is expected behavior, so we just check the page exists assert not at.exception @@ -51,7 +48,7 @@ def test_previous_reports_tab(): def test_upload_new_tab(): """Test Upload Report page functionality (previously called Upload New)""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) # Navigate to Upload Report page at.session_state["nav_page"] = "Upload Report" at.run(timeout=10) @@ -59,8 +56,6 @@ def test_upload_new_tab(): # Check that we're on the Upload Report page assert at.session_state["nav_page"] == "Upload Report", "Not on Upload Report page" - # Check for file uploader in the app (should be present) - has_file_uploader = hasattr(at, "file_uploader") and len(at.file_uploader) > 0 # File uploader might not be visible initially in AppTest, so this is optional # The important thing is that the page exists and the app loads without errors assert not at.exception @@ -68,7 +63,7 @@ def test_upload_new_tab(): def test_consolidated_results_tab(): """Test All Results page functionality (previously called Consolidated Results)""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) # Navigate to All Results page at.session_state["nav_page"] = "All Results" at.run(timeout=10) @@ -90,7 +85,7 @@ def test_consolidated_results_tab(): def test_configuration_expander(): """Test Analysis Configuration expander""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) # Navigate to Report Analyst page where the expander is located at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -108,7 +103,7 @@ def test_configuration_expander(): def test_configuration_widgets(): """Test configuration widgets (chunk size, overlap, top_k, model)""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) # Navigate to Report Analyst page where configuration widgets are located at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -130,7 +125,7 @@ def test_configuration_widgets(): def test_question_set_selection(): """Test question set selection functionality""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) # Navigate to Report Analyst page where question set selectbox is located at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -159,7 +154,7 @@ def test_question_set_selection(): def test_analysis_controls(): """Test analysis control checkboxes and buttons""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) # Navigate to Report Analyst page where analysis controls are located at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -182,7 +177,7 @@ def test_analysis_controls(): def test_footer_display(): """Test that footer with Climate+Tech branding is displayed""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.run(timeout=10) # Check for footer content in markdown @@ -193,7 +188,7 @@ def test_footer_display(): def test_session_state_initialization(): """Test that session state variables are properly initialized""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) at.run(timeout=10) # The app should initialize without errors, which means session state is set up correctly diff --git a/tests/test_streamlit_app_upload.py b/tests/test_streamlit_app_upload.py index 60f3bd3c1..dd9a03a66 100644 --- a/tests/test_streamlit_app_upload.py +++ b/tests/test_streamlit_app_upload.py @@ -3,12 +3,16 @@ Tests that the app loads correctly with file upload capabilities. """ +from pathlib import Path + from streamlit.testing.v1 import AppTest +APP_PATH = Path(__file__).resolve().parents[1] / "report_analyst" / "streamlit_app.py" + def test_app_loads_with_upload_capability(): """Test that app loads without errors and has upload functionality""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) # Navigate to Report Analyst page to check for title at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -23,7 +27,7 @@ def test_app_loads_with_upload_capability(): def test_app_has_file_related_ui(): """Test that app has file-related UI elements""" - at = AppTest.from_file("report_analyst/streamlit_app.py") + at = AppTest.from_file(APP_PATH) # Navigate to Report Analyst page where file selectbox might be located at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) From 618b9e5ac5235af09c7b7b559c5dc041d74af9d2 Mon Sep 17 00:00:00 2001 From: Mouna Cheikho Date: Thu, 3 Sep 2026 15:54:42 +0400 Subject: [PATCH 2/2] Centralized Streamlit test path --- tests/conftest.py | 7 +++ tests/test_settings_enterprise_mode.py | 15 ++--- tests/test_streamlit_app_analyze.py | 10 ++-- .../test_streamlit_app_backend_integration.py | 60 +++++++++---------- tests/test_streamlit_app_basic.py | 12 ++-- tests/test_streamlit_app_data_display.py | 48 +++++++-------- tests/test_streamlit_app_file_selection.py | 9 ++- tests/test_streamlit_app_processing_steps.py | 16 ++--- tests/test_streamlit_app_questions.py | 16 ++--- tests/test_streamlit_app_tabs.py | 44 +++++++------- tests/test_streamlit_app_upload.py | 12 ++-- 11 files changed, 113 insertions(+), 136 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index c8cc79890..80a95ab5b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -33,6 +33,13 @@ if path not in sys.path: sys.path.insert(0, path) + +@pytest.fixture(scope="session") +def streamlit_app_path(): + """Return the Streamlit app path used by AppTest.""" + return project_root / "report_analyst" / "streamlit_app.py" + + # Make report_analyst_jobs import optional (ImportError or transitive env/deps failures) try: from report_analyst_jobs.event_router import EventRouter diff --git a/tests/test_settings_enterprise_mode.py b/tests/test_settings_enterprise_mode.py index 84a7d73fd..e60ed202a 100644 --- a/tests/test_settings_enterprise_mode.py +++ b/tests/test_settings_enterprise_mode.py @@ -7,19 +7,16 @@ """ import os -from pathlib import Path from unittest.mock import patch from streamlit.testing.v1 import AppTest -APP_PATH = Path(__file__).resolve().parents[1] / "report_analyst" / "streamlit_app.py" - -def test_enterprise_mode_message_only_when_checked(): +def test_enterprise_mode_message_only_when_checked(streamlit_app_path): """Test that enterprise mode message only shows when checkbox is checked""" # Run without USE_S3_UPLOAD env var to test checkbox behavior with patch.dict(os.environ, {"USE_S3_UPLOAD": "false"}, clear=False): - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.run(timeout=10) # Navigate to Settings page @@ -55,11 +52,11 @@ def test_enterprise_mode_message_only_when_checked(): assert checkbox.value is True, "Checkbox should be checked" -def test_enterprise_mode_checkbox_state_persistence(): +def test_enterprise_mode_checkbox_state_persistence(streamlit_app_path): """Test that checkbox state persists correctly across reruns""" # Run without USE_S3_UPLOAD env var to test checkbox behavior with patch.dict(os.environ, {"USE_S3_UPLOAD": "false"}, clear=False): - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.run(timeout=10) # Navigate to Settings @@ -92,13 +89,13 @@ def test_enterprise_mode_checkbox_state_persistence(): assert checkbox.value is False, "Checkbox should remain False after rerun" -def test_enterprise_mode_env_var_detection(): +def test_enterprise_mode_env_var_detection(streamlit_app_path): """Test that the app correctly detects USE_S3_UPLOAD env var""" # This test verifies the env var detection logic works # When USE_S3_UPLOAD=true is in env, session state should be True env_value = os.getenv("USE_S3_UPLOAD", "false").lower() == "true" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.run(timeout=10) # Navigate to Settings diff --git a/tests/test_streamlit_app_analyze.py b/tests/test_streamlit_app_analyze.py index f95ca4a0f..e72bd1111 100644 --- a/tests/test_streamlit_app_analyze.py +++ b/tests/test_streamlit_app_analyze.py @@ -74,12 +74,12 @@ def test_process_document_with_all_keywords(): # os.environ["TEMP_DIR"] = str(temp_dir) -def test_analyze_button_without_openai_call(mocked_report_analyzer, test_pdf_in_app_temp): +def test_analyze_button_without_openai_call(mocked_report_analyzer, test_pdf_in_app_temp, streamlit_app_path): report_analyzer, calls = mocked_report_analyzer assert test_pdf_in_app_temp.exists() - at = AppTest.from_file(str(PROJECT_ROOT / "report_analyst/streamlit_app.py")) + at = AppTest.from_file(streamlit_app_path) at.session_state["nav_page"] = "Report Analyst" at.session_state["analyzer"] = report_analyzer @@ -107,12 +107,14 @@ def test_analyze_button_without_openai_call(mocked_report_analyzer, test_pdf_in_ assert any(expander.label == "PDF Viewer with Chunks" for expander in at.expander) -def test_reanalyze_button_forces_recompute_without_cache_lookup(mocked_report_analyzer, test_pdf_in_app_temp): +def test_reanalyze_button_forces_recompute_without_cache_lookup( + mocked_report_analyzer, test_pdf_in_app_temp, streamlit_app_path +): report_analyzer, calls = mocked_report_analyzer assert test_pdf_in_app_temp.exists() - at = AppTest.from_file(str(PROJECT_ROOT / "report_analyst/streamlit_app.py")) + at = AppTest.from_file(streamlit_app_path) at.session_state["nav_page"] = "Report Analyst" at.session_state["analyzer"] = report_analyzer diff --git a/tests/test_streamlit_app_backend_integration.py b/tests/test_streamlit_app_backend_integration.py index 6ca6079ea..180c382b3 100644 --- a/tests/test_streamlit_app_backend_integration.py +++ b/tests/test_streamlit_app_backend_integration.py @@ -3,16 +3,12 @@ Tests backend integration availability and functionality. """ -from pathlib import Path - from streamlit.testing.v1 import AppTest -APP_PATH = Path(__file__).resolve().parents[1] / "report_analyst" / "streamlit_app.py" - -def test_backend_integration_availability(): +def test_backend_integration_availability(streamlit_app_path): """Test that backend integration features are available""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.run(timeout=10) # The app should load without errors, indicating backend integration is available @@ -22,9 +18,9 @@ def test_backend_integration_availability(): # This is verified by the app loading successfully with backend integration -def test_backend_configuration_display(): +def test_backend_configuration_display(streamlit_app_path): """Test backend configuration display""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.run(timeout=10) # Check for backend configuration elements @@ -34,9 +30,9 @@ def test_backend_configuration_display(): assert not at.exception -def test_backend_flow_orchestrator(): +def test_backend_flow_orchestrator(streamlit_app_path): """Test backend flow orchestrator functionality""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.run(timeout=10) # Check that backend flow orchestrator is properly integrated @@ -45,9 +41,9 @@ def test_backend_flow_orchestrator(): assert not at.exception -def test_backend_analysis_workflow(): +def test_backend_analysis_workflow(streamlit_app_path): """Test backend analysis workflow integration""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.run(timeout=10) # Check for backend analysis workflow elements @@ -57,9 +53,9 @@ def test_backend_analysis_workflow(): assert not at.exception -def test_backend_error_handling(): +def test_backend_error_handling(streamlit_app_path): """Test backend integration error handling""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.run(timeout=10) # Backend integration should handle errors gracefully @@ -68,9 +64,9 @@ def test_backend_error_handling(): assert not at.exception -def test_backend_fallback_behavior(): +def test_backend_fallback_behavior(streamlit_app_path): """Test backend integration fallback behavior""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.run(timeout=10) # Backend integration should have proper fallback behavior @@ -80,9 +76,9 @@ def test_backend_fallback_behavior(): assert not at.exception -def test_backend_config_status(): +def test_backend_config_status(streamlit_app_path): """Test backend configuration status display""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.run(timeout=10) # Check for backend configuration status elements @@ -92,9 +88,9 @@ def test_backend_config_status(): assert not at.exception -def test_backend_processing_result(): +def test_backend_processing_result(streamlit_app_path): """Test backend processing result handling""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.run(timeout=10) # Check that backend processing results are handled properly @@ -103,9 +99,9 @@ def test_backend_processing_result(): assert not at.exception -def test_backend_analysis_result(): +def test_backend_analysis_result(streamlit_app_path): """Test backend analysis result integration""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.run(timeout=10) # Check for backend analysis result handling @@ -114,9 +110,9 @@ def test_backend_analysis_result(): assert not at.exception -def test_backend_integration_imports(): +def test_backend_integration_imports(streamlit_app_path): """Test that backend integration imports work correctly""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.run(timeout=10) # Backend integration imports should work without errors @@ -125,9 +121,9 @@ def test_backend_integration_imports(): assert not at.exception -def test_backend_flow_selection(): +def test_backend_flow_selection(streamlit_app_path): """Test backend flow selection functionality""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.run(timeout=10) # Check for backend flow selection elements @@ -137,9 +133,9 @@ def test_backend_flow_selection(): assert not at.exception -def test_backend_local_analysis(): +def test_backend_local_analysis(streamlit_app_path): """Test backend local analysis functionality""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.run(timeout=10) # Check for backend local analysis capabilities @@ -148,9 +144,9 @@ def test_backend_local_analysis(): assert not at.exception -def test_backend_integration_compatibility(): +def test_backend_integration_compatibility(streamlit_app_path): """Test backend integration compatibility with main app""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.run(timeout=10) # Backend integration should be compatible with the main app @@ -168,11 +164,11 @@ def test_backend_integration_compatibility(): assert not at.exception -def test_backend_resource_full_roundtrip(): +def test_backend_resource_full_roundtrip(streamlit_app_path): """Test full roundtrip: list backend resources, select, retrieve chunks, analyze""" from unittest.mock import Mock, patch - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) # Mock backend configuration mock_backend_config = Mock() diff --git a/tests/test_streamlit_app_basic.py b/tests/test_streamlit_app_basic.py index 26687b936..23c3c6791 100644 --- a/tests/test_streamlit_app_basic.py +++ b/tests/test_streamlit_app_basic.py @@ -3,23 +3,19 @@ Tests app loading, title, and layout elements. """ -from pathlib import Path - from streamlit.testing.v1 import AppTest -APP_PATH = Path(__file__).resolve().parents[1] / "report_analyst" / "streamlit_app.py" - -def test_app_loads(): +def test_app_loads(streamlit_app_path): """Test that streamlit_app.py loads without errors""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.run(timeout=10) # Increase timeout assert not at.exception -def test_app_title_and_layout(): +def test_app_title_and_layout(streamlit_app_path): """Test app displays correct title and basic layout""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) # Navigate to Report Analyst page where title is displayed at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) # Increase timeout diff --git a/tests/test_streamlit_app_data_display.py b/tests/test_streamlit_app_data_display.py index 296b2b971..e7bd33267 100644 --- a/tests/test_streamlit_app_data_display.py +++ b/tests/test_streamlit_app_data_display.py @@ -3,16 +3,12 @@ Tests dataframes, charts, and result display functionality. """ -from pathlib import Path - from streamlit.testing.v1 import AppTest -APP_PATH = Path(__file__).resolve().parents[1] / "report_analyst" / "streamlit_app.py" - -def test_dataframe_display_capability(): +def test_dataframe_display_capability(streamlit_app_path): """Test that the app can display dataframes""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.run(timeout=10) # The app should load without errors, indicating dataframe display capability @@ -22,9 +18,9 @@ def test_dataframe_display_capability(): # This is verified by the app loading successfully with dataframe_manager imports -def test_analysis_results_structure(): +def test_analysis_results_structure(streamlit_app_path): """Test that analysis results structure is properly set up""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.run(timeout=10) # Check for placeholder elements that would be used for results @@ -37,9 +33,9 @@ def test_analysis_results_structure(): assert not at.exception -def test_file_history_functionality(): +def test_file_history_functionality(streamlit_app_path): """Test file history and previous reports functionality""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.run(timeout=10) # File history might not be visible if no previous files exist @@ -47,9 +43,9 @@ def test_file_history_functionality(): assert not at.exception -def test_question_display_functionality(): +def test_question_display_functionality(streamlit_app_path): """Test question display and selection functionality""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) # Navigate to Report Analyst page where questions are displayed at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -68,9 +64,9 @@ def test_question_display_functionality(): assert not at.exception -def test_model_selection_display(): +def test_model_selection_display(streamlit_app_path): """Test LLM model selection display""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) # Navigate to Report Analyst page where model selection is located at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -90,9 +86,9 @@ def test_model_selection_display(): assert not at.exception -def test_configuration_display(): +def test_configuration_display(streamlit_app_path): """Test configuration parameter display""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) # Navigate to Report Analyst page where configuration widgets are located at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -113,9 +109,9 @@ def test_configuration_display(): assert not at.exception -def test_analysis_controls_display(): +def test_analysis_controls_display(streamlit_app_path): """Test analysis control options display""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) # Navigate to Report Analyst page where analysis controls are located at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -138,9 +134,9 @@ def test_analysis_controls_display(): # and may not appear until a file is selected. This is expected behavior. -def test_error_handling_display(): +def test_error_handling_display(streamlit_app_path): """Test error handling and display capabilities""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.run(timeout=10) # The app should handle errors gracefully and display them @@ -152,9 +148,9 @@ def test_error_handling_display(): # The app should handle errors gracefully, which is verified by loading without exceptions -def test_consolidated_results_display(): +def test_consolidated_results_display(streamlit_app_path): """Test All Results page display functionality (previously called Consolidated Results)""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) # Navigate to All Results page at.session_state["nav_page"] = "All Results" at.run(timeout=10) @@ -173,9 +169,9 @@ def test_consolidated_results_display(): assert not at.exception -def test_app_layout_and_structure(): +def test_app_layout_and_structure(streamlit_app_path): """Test overall app layout and structure""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.run(timeout=10) # Check that navigation page is set in session state @@ -195,9 +191,9 @@ def test_app_layout_and_structure(): assert not at.exception -def test_dynamic_content_loading(): +def test_dynamic_content_loading(streamlit_app_path): """Test dynamic content loading capabilities""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) # Navigate to Report Analyst page where question sets are displayed at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) diff --git a/tests/test_streamlit_app_file_selection.py b/tests/test_streamlit_app_file_selection.py index fb63aeb22..c62442e74 100644 --- a/tests/test_streamlit_app_file_selection.py +++ b/tests/test_streamlit_app_file_selection.py @@ -8,7 +8,6 @@ from streamlit.testing.v1 import AppTest -APP_PATH = Path(__file__).resolve().parents[1] / "report_analyst" / "streamlit_app.py" TEST_PDF = ( b"%PDF-1.4\n%Test PDF\n1 0 obj\n<< /Type /Catalog /Pages 2 0 R >>\nendobj\n" b"2 0 obj\n<< /Type /Pages /Kids [3 0 R] /Count 1 >>\nendobj\n" @@ -17,7 +16,7 @@ ) -def test_file_selection_with_file_uri(): +def test_file_selection_with_file_uri(streamlit_app_path): """Test that file selection works correctly with file:// URIs""" # Create a temporary PDF file with tempfile.TemporaryDirectory() as temp_dir: @@ -31,7 +30,7 @@ def test_file_selection_with_file_uri(): os.environ["TEMP_DIR"] = str(temp_dir) try: - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -108,7 +107,7 @@ def test_file_path_resolution_from_uri(): del os.environ["TEMP_DIR"] -def test_file_not_found_error_not_shown(): +def test_file_not_found_error_not_shown(streamlit_app_path): """Test that 'File not found: None' error is not shown when file is selected""" # Create a temporary PDF file with tempfile.TemporaryDirectory() as temp_dir: @@ -122,7 +121,7 @@ def test_file_not_found_error_not_shown(): os.environ["TEMP_DIR"] = str(temp_dir) try: - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) diff --git a/tests/test_streamlit_app_processing_steps.py b/tests/test_streamlit_app_processing_steps.py index b0ea8f4d2..175cf1eea 100644 --- a/tests/test_streamlit_app_processing_steps.py +++ b/tests/test_streamlit_app_processing_steps.py @@ -3,16 +3,12 @@ Tests that the slider exists, is interactive, and controls step selection. """ -from pathlib import Path - from streamlit.testing.v1 import AppTest -APP_PATH = Path(__file__).resolve().parents[1] / "report_analyst" / "streamlit_app.py" - -def test_processing_steps_slider_exists(): +def test_processing_steps_slider_exists(streamlit_app_path): """Test that Processing Steps slider is present""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -32,9 +28,9 @@ def test_processing_steps_slider_exists(): # without causing format_func issues. The important thing is the app loads correctly. -def test_processing_steps_slider_interactive(): +def test_processing_steps_slider_interactive(streamlit_app_path): """Test that Processing Steps slider is interactive""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -54,9 +50,9 @@ def test_processing_steps_slider_interactive(): # in AppTest. The important thing is the app loads correctly and the page structure is there. -def test_processing_steps_displayed(): +def test_processing_steps_displayed(streamlit_app_path): """Test that Processing Steps are displayed with correct labels""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) diff --git a/tests/test_streamlit_app_questions.py b/tests/test_streamlit_app_questions.py index 8fc431eae..8ef668a54 100644 --- a/tests/test_streamlit_app_questions.py +++ b/tests/test_streamlit_app_questions.py @@ -3,16 +3,12 @@ Tests dynamic question loading and selection. """ -from pathlib import Path - from streamlit.testing.v1 import AppTest -APP_PATH = Path(__file__).resolve().parents[1] / "report_analyst" / "streamlit_app.py" - -def test_question_set_selectbox_exists(): +def test_question_set_selectbox_exists(streamlit_app_path): """Test question set selectbox is present""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) # Navigate to Report Analyst page where question set selectbox is located at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -28,9 +24,9 @@ def test_question_set_selectbox_exists(): assert not at.exception -def test_question_sets_loaded_dynamically(): +def test_question_sets_loaded_dynamically(streamlit_app_path): """Test question sets loaded from question_loader""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) # Navigate to Report Analyst page where question set selectbox is located at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -50,9 +46,9 @@ def test_question_sets_loaded_dynamically(): assert not at.exception -def test_question_set_selectbox_has_options(): +def test_question_set_selectbox_has_options(streamlit_app_path): """Test question set selectbox has multiple options available""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) # Navigate to Report Analyst page where question set selectbox is located at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) diff --git a/tests/test_streamlit_app_tabs.py b/tests/test_streamlit_app_tabs.py index bdddfec40..f81388178 100644 --- a/tests/test_streamlit_app_tabs.py +++ b/tests/test_streamlit_app_tabs.py @@ -3,16 +3,12 @@ Tests Previous Reports, Upload New, and Consolidated Results tabs. """ -from pathlib import Path - from streamlit.testing.v1 import AppTest -APP_PATH = Path(__file__).resolve().parents[1] / "report_analyst" / "streamlit_app.py" - -def test_tabs_exist(): +def test_tabs_exist(streamlit_app_path): """Test that all three main navigation pages are present""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.run(timeout=10) # Check that navigation page is set in session state @@ -31,9 +27,9 @@ def test_tabs_exist(): assert not at.exception -def test_previous_reports_tab(): +def test_previous_reports_tab(streamlit_app_path): """Test Report Analyst page functionality (previously called Previous Reports)""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) # Navigate to Report Analyst page at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -46,9 +42,9 @@ def test_previous_reports_tab(): assert not at.exception -def test_upload_new_tab(): +def test_upload_new_tab(streamlit_app_path): """Test Upload Report page functionality (previously called Upload New)""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) # Navigate to Upload Report page at.session_state["nav_page"] = "Upload Report" at.run(timeout=10) @@ -61,9 +57,9 @@ def test_upload_new_tab(): assert not at.exception -def test_consolidated_results_tab(): +def test_consolidated_results_tab(streamlit_app_path): """Test All Results page functionality (previously called Consolidated Results)""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) # Navigate to All Results page at.session_state["nav_page"] = "All Results" at.run(timeout=10) @@ -83,9 +79,9 @@ def test_consolidated_results_tab(): assert not at.exception -def test_configuration_expander(): +def test_configuration_expander(streamlit_app_path): """Test Analysis Configuration expander""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) # Navigate to Report Analyst page where the expander is located at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -101,9 +97,9 @@ def test_configuration_expander(): assert not at.exception -def test_configuration_widgets(): +def test_configuration_widgets(streamlit_app_path): """Test configuration widgets (chunk size, overlap, top_k, model)""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) # Navigate to Report Analyst page where configuration widgets are located at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -123,9 +119,9 @@ def test_configuration_widgets(): assert not at.exception -def test_question_set_selection(): +def test_question_set_selection(streamlit_app_path): """Test question set selection functionality""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) # Navigate to Report Analyst page where question set selectbox is located at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -152,9 +148,9 @@ def test_question_set_selection(): assert not at.exception -def test_analysis_controls(): +def test_analysis_controls(streamlit_app_path): """Test analysis control checkboxes and buttons""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) # Navigate to Report Analyst page where analysis controls are located at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -175,9 +171,9 @@ def test_analysis_controls(): # The important thing is that the app loads correctly and handles the page navigation. -def test_footer_display(): +def test_footer_display(streamlit_app_path): """Test that footer with Climate+Tech branding is displayed""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.run(timeout=10) # Check for footer content in markdown @@ -186,9 +182,9 @@ def test_footer_display(): assert not at.exception -def test_session_state_initialization(): +def test_session_state_initialization(streamlit_app_path): """Test that session state variables are properly initialized""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) at.run(timeout=10) # The app should initialize without errors, which means session state is set up correctly diff --git a/tests/test_streamlit_app_upload.py b/tests/test_streamlit_app_upload.py index dd9a03a66..9d2c06732 100644 --- a/tests/test_streamlit_app_upload.py +++ b/tests/test_streamlit_app_upload.py @@ -3,16 +3,12 @@ Tests that the app loads correctly with file upload capabilities. """ -from pathlib import Path - from streamlit.testing.v1 import AppTest -APP_PATH = Path(__file__).resolve().parents[1] / "report_analyst" / "streamlit_app.py" - -def test_app_loads_with_upload_capability(): +def test_app_loads_with_upload_capability(streamlit_app_path): """Test that app loads without errors and has upload functionality""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) # Navigate to Report Analyst page to check for title at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10) @@ -25,9 +21,9 @@ def test_app_loads_with_upload_capability(): assert len(at.expander) > 0, "App should have expanders" -def test_app_has_file_related_ui(): +def test_app_has_file_related_ui(streamlit_app_path): """Test that app has file-related UI elements""" - at = AppTest.from_file(APP_PATH) + at = AppTest.from_file(streamlit_app_path) # Navigate to Report Analyst page where file selectbox might be located at.session_state["nav_page"] = "Report Analyst" at.run(timeout=10)