From d2f3b437595d9f26ac4c0237b4c62c0c66079d4a Mon Sep 17 00:00:00 2001 From: Brian Krabach Date: Mon, 30 Mar 2026 02:36:08 -0700 Subject: [PATCH] test: add frontend tests for settings dialog and new session UI --- muxplex/tests/test_frontend_css.py | 51 +++++++++++++++++++++++++++ muxplex/tests/test_frontend_html.py | 54 +++++++++++++++++++++++++++-- 2 files changed, 103 insertions(+), 2 deletions(-) diff --git a/muxplex/tests/test_frontend_css.py b/muxplex/tests/test_frontend_css.py index 68e4cdb..6abcd3f 100644 --- a/muxplex/tests/test_frontend_css.py +++ b/muxplex/tests/test_frontend_css.py @@ -1623,3 +1623,54 @@ def test_css_fab_focus_visible_outline_not_accent() -> None: "the FAB background is already var(--accent), so the outline would be invisible. " "Use var(--bg) or var(--text) for contrast." ) + + +# ============================================================ +# Consolidated settings CSS selectors (task-8-frontend-tests) +# ============================================================ + + +def test_css_settings_dialog() -> None: + """All settings dialog CSS selectors must exist: .settings-dialog, .settings-tabs, .settings-tab--active, .settings-content, .settings-field, .settings-select.""" + css = read_css() + for cls in ( + ".settings-dialog", + ".settings-tabs", + ".settings-tab--active", + ".settings-content", + ".settings-field", + ".settings-select", + ): + assert cls in css, f"Missing CSS selector '{cls}'" + + +def test_css_header_btn() -> None: + """.header-btn and .header-actions CSS selectors must exist.""" + css = read_css() + for cls in (".header-btn", ".header-actions"): + assert cls in css, f"Missing CSS selector '{cls}'" + + +def test_css_new_session_fab() -> None: + """.new-session-fab CSS selector must exist.""" + css = read_css() + assert ".new-session-fab" in css, "Missing .new-session-fab CSS selector" + + +def test_css_new_session_input() -> None: + """.new-session-input CSS selector must exist.""" + css = read_css() + assert ".new-session-input" in css, "Missing .new-session-input CSS selector" + + +def test_css_settings_textarea() -> None: + """.settings-textarea CSS selector must exist.""" + css = read_css() + assert ".settings-textarea" in css, "Missing .settings-textarea CSS selector" + + +def test_css_sidebar_footer() -> None: + """.sidebar-footer and .sidebar-new-btn CSS selectors must exist.""" + css = read_css() + for cls in (".sidebar-footer", ".sidebar-new-btn"): + assert cls in css, f"Missing CSS selector '{cls}'" diff --git a/muxplex/tests/test_frontend_html.py b/muxplex/tests/test_frontend_html.py index 93535bb..c75b262 100644 --- a/muxplex/tests/test_frontend_html.py +++ b/muxplex/tests/test_frontend_html.py @@ -335,7 +335,7 @@ def test_html_header_actions_div() -> None: def test_html_new_session_btn() -> None: - """#new-session-btn must exist in .header-actions with class header-btn.""" + """#new-session-btn must exist in .header-actions with class header-btn; #new-session-fab must also exist.""" soup = _SOUP btn = soup.find(id="new-session-btn") assert btn is not None, "Missing #new-session-btn" @@ -349,6 +349,8 @@ def test_html_new_session_btn() -> None: assert header_actions.find(id="new-session-btn") is not None, ( "#new-session-btn must be inside .header-actions" ) + # Mobile FAB button must also exist + assert soup.find(id="new-session-fab") is not None, "Missing #new-session-fab" def test_html_settings_btn() -> None: @@ -416,7 +418,7 @@ def test_html_settings_backdrop() -> None: def test_html_settings_dialog() -> None: - """#settings-dialog must be a with class settings-dialog.""" + """#settings-dialog must be a with class settings-dialog; #settings-backdrop and #settings-btn must also exist.""" soup = _SOUP el = soup.find(id="settings-dialog") assert el is not None, "Missing #settings-dialog" @@ -427,6 +429,8 @@ def test_html_settings_dialog() -> None: assert "settings-dialog" in classes, ( f"#settings-dialog must have class 'settings-dialog', has: {classes}" ) + assert soup.find(id="settings-backdrop") is not None, "Missing #settings-backdrop" + assert soup.find(id="settings-btn") is not None, "Missing #settings-btn" def test_html_settings_tabs() -> None: @@ -999,3 +1003,49 @@ def test_html_fab_before_toast() -> None: assert fab_idx < toast_idx, ( f"#new-session-fab (idx={fab_idx}) must appear before #toast (idx={toast_idx})" ) + + +# ============================================================ +# Consolidated settings tests (task-8-frontend-tests) +# ============================================================ + + +def test_html_display_tab_controls() -> None: + """Display tab panel must contain setting-font-size, setting-hover-delay, setting-grid-columns.""" + soup = _SOUP + for id_ in ("setting-font-size", "setting-hover-delay", "setting-grid-columns"): + assert soup.find(id=id_), f"Missing element with id='{id_}'" + + +def test_html_sidebar_new_session_btn() -> None: + """#sidebar-new-session-btn must exist in the document.""" + soup = _SOUP + assert soup.find(id="sidebar-new-session-btn") is not None, ( + "Missing #sidebar-new-session-btn" + ) + + +def test_html_sessions_tab_controls() -> None: + """Sessions tab must contain setting-default-session, setting-sort-order, setting-window-size-largest, setting-auto-open.""" + soup = _SOUP + for id_ in ( + "setting-default-session", + "setting-sort-order", + "setting-window-size-largest", + "setting-auto-open", + ): + assert soup.find(id=id_), f"Missing element with id='{id_}'" + + +def test_html_notifications_tab_controls() -> None: + """Notifications tab must contain setting-bell-sound and notification-request-btn.""" + soup = _SOUP + for id_ in ("setting-bell-sound", "notification-request-btn"): + assert soup.find(id=id_), f"Missing element with id='{id_}'" + + +def test_html_new_session_tab_controls() -> None: + """New Session tab must contain setting-template and setting-template-reset.""" + soup = _SOUP + for id_ in ("setting-template", "setting-template-reset"): + assert soup.find(id=id_), f"Missing element with id='{id_}'"