"""Chrome tests — language selector, hide_streamlit_chrome, quit flow. These verify the GUI plumbing that every page depends on. Failures here cascade into every other page, so they run cheap and run first (alphabetical name ordering after smoke). """ from __future__ import annotations import pytest from .conftest import collected_text, with_language # --------------------------------------------------------------------------- # hide_streamlit_chrome mounts the selector # --------------------------------------------------------------------------- class TestHideChromeMountsSelector: """``hide_streamlit_chrome()`` is the one place the language selector is mounted. Every page that hides chrome (= every page) must get exactly one sidebar selectbox with the i18n label.""" def test_home_has_one_sidebar_selectbox(self, home_app): home_app.run() # Only one selectbox in the sidebar today; if a page adds # another, this becomes a weaker bound. assert len(home_app.sidebar.selectbox) == 1, ( "expected exactly one sidebar selectbox (the language picker); " f"got {len(home_app.sidebar.selectbox)}" ) def test_selector_label_is_localized(self, home_app): with_language(home_app, "es") home_app.run() labels = [sb.label for sb in home_app.sidebar.selectbox] assert "Idioma" in labels, ( f"Spanish selector should be labelled 'Idioma'; got {labels}" ) def test_selector_label_english_default(self, home_app): home_app.run() # no with_language → default = en labels = [sb.label for sb in home_app.sidebar.selectbox] assert "Language" in labels # --------------------------------------------------------------------------- # Language selector switches session state # --------------------------------------------------------------------------- class TestLanguageSwitch: """Picking 'es' in the selector flips ``st.session_state['ui_lang']`` and re-renders the page with Spanish strings on the next run.""" def test_default_language_is_english(self, home_app): home_app.run() # AppTest's session_state proxy doesn't implement .get(); use # membership check + attribute access. Absence == default ("en"). lang = home_app.session_state["ui_lang"] if "ui_lang" in home_app.session_state else "en" assert lang == "en" text = collected_text(home_app) assert "Data Cleaning Mastery" in text def test_selecting_spanish_persists_in_session(self, home_app): home_app.run() selector = home_app.sidebar.selectbox[0] selector.select("es").run() assert home_app.session_state["ui_lang"] == "es" def test_selecting_spanish_re_renders_in_spanish(self, home_app): home_app.run() selector = home_app.sidebar.selectbox[0] selector.select("es").run() text = collected_text(home_app) assert "Maestría" in text, ( "after selecting Spanish, the home title should switch to " f"'🧹 DataTools — Maestría…'; got:\n{text[:300]}" ) def test_selecting_back_to_english_reverts(self, home_app): # Start in Spanish, then flip back. with_language(home_app, "es") home_app.run() assert "Maestría" in collected_text(home_app) selector = home_app.sidebar.selectbox[0] selector.select("en").run() text = collected_text(home_app) assert "Data Cleaning Mastery" in text assert "Maestría" not in text # --------------------------------------------------------------------------- # Footer + page_title localization # --------------------------------------------------------------------------- class TestLocalizedChrome: """A spot-check on the parts of the chrome that aren't the selector: the bottom footer caption and the home-page hero text. Other strings are pinned indirectly by ``TestEveryPageRenders.test_expected_*``.""" def test_footer_english(self, home_app): home_app.run() text = collected_text(home_app) assert "Your data never leaves" in text def test_footer_spanish(self, home_app): with_language(home_app, "es") home_app.run() text = collected_text(home_app) assert "Tus datos nunca salen" in text def test_upload_section_heading_localizes(self, home_app): with_language(home_app, "es") home_app.run() text = collected_text(home_app) # ``📤 Sube uno o más archivos para empezar`` from the es pack. assert "Sube uno o más archivos" in text # --------------------------------------------------------------------------- # Quit / Close page # --------------------------------------------------------------------------- class TestQuitButtonRenders: """The Close page must show the localized title, body, and the Close-the-app button. We don't actually click the button — that would call ``os._exit(0)`` and kill the test process. We only assert the button is present and its label is localized.""" def test_close_page_english(self, app_factory): app = app_factory("99_Close") app.run() text = collected_text(app) assert "Close DataTools" in text labels = [b.label for b in app.button] assert any("Close the app" in lbl for lbl in labels), ( f"Close-the-app button missing; buttons: {labels}" ) def test_close_page_spanish(self, app_factory): app = app_factory("99_Close") with_language(app, "es") app.run() text = collected_text(app) assert "Cerrar DataTools" in text labels = [b.label for b in app.button] assert any("Cerrar la app" in lbl for lbl in labels), ( f"Spanish Close button missing; buttons: {labels}" ) def test_close_body_describes_unsaved_work_warning_es(self, app_factory): app = app_factory("99_Close") with_language(app, "es") app.run() text = collected_text(app) assert "trabajo sin guardar" in text