test: mobile layout regression suite — 14 tests for every QA run - #254
test: mobile layout regression suite — 14 tests for every QA run#254nesquena-hermes wants to merge 1 commit into
Conversation
Adds tests/test_mobile_layout.py with 14 static checks that run on every QA pass to catch mobile regressions before they reach production. Tests cover: - CSS breakpoints at 900px (right panel slide-over) and 640px - Right panel position:fixed slide-over markup and mobile-open class - Mobile overlay (#mobileOverlay) for tap-to-close sidebar - Mobile bottom nav markup and CSS - Mobile files toggle button (#btnMobileFiles) - Profile dropdown z-index not clipped by overflow-x:auto ancestor - topbar-chips horizontal scrolling on narrow viewports - Workspace panel close via toggleMobileFiles() - toggleMobileFiles() defined in boot.js with mobile-open toggle - body overflow:hidden preventing double scrollbars - 100dvh viewport height for correct mobile sizing (not 100vh) - 44px minimum touch targets for send/nav buttons - 16px compositor textarea font-size to prevent iOS zoom-on-focus All 14 tests pass against current master. Future PRs that break mobile layout will be caught here before QA.
Full Review: PR #254 — Mobile QA regression suiteSecurity AuditN/A — this is a test-only PR. No code changes, no new endpoints, no frontend modifications. Code Review14 static tests covering:
All tests are static file reads — no server needed, run in < 3 seconds. They read Test quality is good:
One note: Tests 1-2 check for breakpoint existence but not that the right rules are inside them. For example, Tests587 passed, 0 failed (1 pre-existing failure from unmerged PR #243's test). VerdictApproved. Valuable regression safety net for mobile layout. All 14 tests pass against current master. Ready to merge. |
|
Agent review — APPROVED ✅ (merged to stage) Reviewed all 14 tests. Categories covered: 900px/640px breakpoints, right panel slide-over CSS, mobile overlay, bottom nav, files button, profile dropdown z-index, chip overflow, workspace close, 100dvh, 44px touch targets, 16px font-size. All static checks — no server needed, completes in ~2s. Two minor test-logic nits noted by auditor (non-blocking): one regex fallback in the 900px test uses These 14 tests now run on every QA pass as part of the core mobile regression gate. Tests: 638 passed (14 new) on review branch. Stage total: 645 passed, 0 failed. |
Adds tests/test_mobile_layout.py with 14 static regression tests that run on every QA pass to catch mobile layout breakage before it reaches prod. Covers: breakpoints at 900px/640px, right panel slide-over CSS, mobile overlay, bottom nav, files button, profile dropdown z-index, chip overflow, workspace close, 100dvh, 44px touch targets, 16px font-size on textarea.
* fix: custom provider with slash model name no longer rerouted to OpenRouter (#255) When base_url is configured in config.yaml, resolve_model_provider() now trusts the configured provider/base_url entirely and skips the slash-based OpenRouter heuristic. Fixes google/gemma-4-26b-a4b with provider:custom being silently routed to OpenRouter, resulting in 401 errors. Fixes #230 * test: mobile layout regression suite — 14 tests for every QA run (#254) Adds tests/test_mobile_layout.py with 14 static regression tests that run on every QA pass to catch mobile layout breakage before it reaches prod. Covers: breakpoints at 900px/640px, right panel slide-over CSS, mobile overlay, bottom nav, files button, profile dropdown z-index, chip overflow, workspace close, 100dvh, 44px touch targets, 16px font-size on textarea. * feat: /skills slash command lists and filters available Hermes skills (#257) Adds /skills [query] command to commands.js. Fetches from /api/skills, groups by category (alphabetically sorted), displays as a formatted assistant message. Optional query filters by name, description, or category. i18n keys added for en, de, zh, zh-Hant. 1 regression test added. Fixes #248 * feat: shared app dialogs replace native confirm()/prompt() calls (#251) Adds showConfirmDialog() and showPromptDialog() helpers to ui.js, backed by a themed #appDialogOverlay. Replaces all 11 native browser confirm/prompt call sites across panels.js, sessions.js, ui.js, workspace.js. Supports: danger mode, keyboard focus trap (Tab/Escape/Enter), focus restore, ARIA roles, mobile-responsive stacked buttons at 640px. i18n for en/de/zh/zh-Hant. 5 new tests in test_sprint33.py verify markup, CSS, helpers, and absence of native dialog calls. Extracted from PR #242. * fix: Android Chrome mobile — workspace panel close + profile dropdown (#256) Fix #247: toggleMobileFiles() now shows/hides the mobile overlay when toggling the right workspace panel. New closeMobileFiles() helper closes the panel with correct overlay state tracking. Overlay onclick calls both closeMobileSidebar() and closeMobileFiles(). Mobile-only close button (x) added to workspace panel header. Fix #246: profile dropdown uses position:fixed;top:56px;right:8px at max-width:900px, escaping the overflow-x:auto stacking context that was clipping it on Android Chrome. Fix applied during review: closeMobileSidebar() now checks if the right panel is still open before hiding the overlay, preventing the overlay from disappearing when only the sidebar is closed. Fixes #247 Fixes #246 * feat: session ⋯ action dropdown replaces per-row buttons (#252) Replaces the 5 per-row hover action buttons (pin/move/archive/duplicate/trash) with a single ⋯ trigger that opens a positioned dropdown menu. Menu has full keyboard (Escape), click-outside, scroll, and resize-reposition handling. Position:fixed prevents sidebar clipping. 5 actions: Pin/Unpin, Move to project, Archive/Unarchive, Duplicate, Delete (danger style). Each with icon and descriptive subtitle. Updated test_sprint16.py: test_sessions_js_uses_action_menu_not_per_row_buttons asserts the new trigger and menu functions exist, old per-row classes are gone. Extracted from PR #242. * docs: v0.47.0 release notes, bump version, update test counts (645) --------- Co-authored-by: Nathan Esquenazi <nesquena@gmail.com>
|
Merged to master via stage branch in PR #258 (v0.47.0). |
* fix: custom provider with slash model name no longer rerouted to OpenRouter (nesquena#255) When base_url is configured in config.yaml, resolve_model_provider() now trusts the configured provider/base_url entirely and skips the slash-based OpenRouter heuristic. Fixes google/gemma-4-26b-a4b with provider:custom being silently routed to OpenRouter, resulting in 401 errors. Fixes nesquena#230 * test: mobile layout regression suite — 14 tests for every QA run (nesquena#254) Adds tests/test_mobile_layout.py with 14 static regression tests that run on every QA pass to catch mobile layout breakage before it reaches prod. Covers: breakpoints at 900px/640px, right panel slide-over CSS, mobile overlay, bottom nav, files button, profile dropdown z-index, chip overflow, workspace close, 100dvh, 44px touch targets, 16px font-size on textarea. * feat: /skills slash command lists and filters available Hermes skills (nesquena#257) Adds /skills [query] command to commands.js. Fetches from /api/skills, groups by category (alphabetically sorted), displays as a formatted assistant message. Optional query filters by name, description, or category. i18n keys added for en, de, zh, zh-Hant. 1 regression test added. Fixes nesquena#248 * feat: shared app dialogs replace native confirm()/prompt() calls (nesquena#251) Adds showConfirmDialog() and showPromptDialog() helpers to ui.js, backed by a themed #appDialogOverlay. Replaces all 11 native browser confirm/prompt call sites across panels.js, sessions.js, ui.js, workspace.js. Supports: danger mode, keyboard focus trap (Tab/Escape/Enter), focus restore, ARIA roles, mobile-responsive stacked buttons at 640px. i18n for en/de/zh/zh-Hant. 5 new tests in test_sprint33.py verify markup, CSS, helpers, and absence of native dialog calls. Extracted from PR nesquena#242. * fix: Android Chrome mobile — workspace panel close + profile dropdown (nesquena#256) Fix nesquena#247: toggleMobileFiles() now shows/hides the mobile overlay when toggling the right workspace panel. New closeMobileFiles() helper closes the panel with correct overlay state tracking. Overlay onclick calls both closeMobileSidebar() and closeMobileFiles(). Mobile-only close button (x) added to workspace panel header. Fix nesquena#246: profile dropdown uses position:fixed;top:56px;right:8px at max-width:900px, escaping the overflow-x:auto stacking context that was clipping it on Android Chrome. Fix applied during review: closeMobileSidebar() now checks if the right panel is still open before hiding the overlay, preventing the overlay from disappearing when only the sidebar is closed. Fixes nesquena#247 Fixes nesquena#246 * feat: session ⋯ action dropdown replaces per-row buttons (nesquena#252) Replaces the 5 per-row hover action buttons (pin/move/archive/duplicate/trash) with a single ⋯ trigger that opens a positioned dropdown menu. Menu has full keyboard (Escape), click-outside, scroll, and resize-reposition handling. Position:fixed prevents sidebar clipping. 5 actions: Pin/Unpin, Move to project, Archive/Unarchive, Duplicate, Delete (danger style). Each with icon and descriptive subtitle. Updated test_sprint16.py: test_sessions_js_uses_action_menu_not_per_row_buttons asserts the new trigger and menu functions exist, old per-row classes are gone. Extracted from PR nesquena#242. * docs: v0.47.0 release notes, bump version, update test counts (645) --------- Co-authored-by: Nathan Esquenazi <nesquena@gmail.com>
* fix: custom provider with slash model name no longer rerouted to OpenRouter (nesquena#255) When base_url is configured in config.yaml, resolve_model_provider() now trusts the configured provider/base_url entirely and skips the slash-based OpenRouter heuristic. Fixes google/gemma-4-26b-a4b with provider:custom being silently routed to OpenRouter, resulting in 401 errors. Fixes nesquena#230 * test: mobile layout regression suite — 14 tests for every QA run (nesquena#254) Adds tests/test_mobile_layout.py with 14 static regression tests that run on every QA pass to catch mobile layout breakage before it reaches prod. Covers: breakpoints at 900px/640px, right panel slide-over CSS, mobile overlay, bottom nav, files button, profile dropdown z-index, chip overflow, workspace close, 100dvh, 44px touch targets, 16px font-size on textarea. * feat: /skills slash command lists and filters available Hermes skills (nesquena#257) Adds /skills [query] command to commands.js. Fetches from /api/skills, groups by category (alphabetically sorted), displays as a formatted assistant message. Optional query filters by name, description, or category. i18n keys added for en, de, zh, zh-Hant. 1 regression test added. Fixes nesquena#248 * feat: shared app dialogs replace native confirm()/prompt() calls (nesquena#251) Adds showConfirmDialog() and showPromptDialog() helpers to ui.js, backed by a themed #appDialogOverlay. Replaces all 11 native browser confirm/prompt call sites across panels.js, sessions.js, ui.js, workspace.js. Supports: danger mode, keyboard focus trap (Tab/Escape/Enter), focus restore, ARIA roles, mobile-responsive stacked buttons at 640px. i18n for en/de/zh/zh-Hant. 5 new tests in test_sprint33.py verify markup, CSS, helpers, and absence of native dialog calls. Extracted from PR nesquena#242. * fix: Android Chrome mobile — workspace panel close + profile dropdown (nesquena#256) Fix nesquena#247: toggleMobileFiles() now shows/hides the mobile overlay when toggling the right workspace panel. New closeMobileFiles() helper closes the panel with correct overlay state tracking. Overlay onclick calls both closeMobileSidebar() and closeMobileFiles(). Mobile-only close button (x) added to workspace panel header. Fix nesquena#246: profile dropdown uses position:fixed;top:56px;right:8px at max-width:900px, escaping the overflow-x:auto stacking context that was clipping it on Android Chrome. Fix applied during review: closeMobileSidebar() now checks if the right panel is still open before hiding the overlay, preventing the overlay from disappearing when only the sidebar is closed. Fixes nesquena#247 Fixes nesquena#246 * feat: session ⋯ action dropdown replaces per-row buttons (nesquena#252) Replaces the 5 per-row hover action buttons (pin/move/archive/duplicate/trash) with a single ⋯ trigger that opens a positioned dropdown menu. Menu has full keyboard (Escape), click-outside, scroll, and resize-reposition handling. Position:fixed prevents sidebar clipping. 5 actions: Pin/Unpin, Move to project, Archive/Unarchive, Duplicate, Delete (danger style). Each with icon and descriptive subtitle. Updated test_sprint16.py: test_sessions_js_uses_action_menu_not_per_row_buttons asserts the new trigger and menu functions exist, old per-row classes are gone. Extracted from PR nesquena#242. * docs: v0.47.0 release notes, bump version, update test counts (645) --------- Co-authored-by: Nathan Esquenazi <nesquena@gmail.com>
Summary
Adds
tests/test_mobile_layout.py— a 14-test static regression suite that runs on every QA pass to catch mobile layout regressions before they reach production. All tests are static (no server needed) and complete in under 3 seconds.Motivation
The review of PR #242 identified that the hermes-webui has meaningful mobile-specific layout code (slide-over right panel, bottom nav, overflow-based chip scrolling, 100dvh sizing) that has no automated regression coverage. Any PR touching
style.css,index.html, orboot.jscan silently break mobile without failing any existing test.These tests act as a safety net for that gap. They're intentionally designed so that if you break mobile layout in a PR, at least one of them will fail.
What's tested (14 tests)
test_mobile_breakpoint_900px_present@media(max-width:900px)exists; rightpanel hidden at desktop-narrowtest_mobile_breakpoint_640px_present@media(max-width:640px)exists for phone widthstest_rightpanel_mobile_slide_over_cssposition:fixed,right:-320pxoffscreen,.mobile-open{right:0}slide-intest_mobile_overlay_present#mobileOverlayelement +.mobile-overlayCSS for tap-to-closetest_mobile_bottom_nav_present.mobile-bottom-navmarkup and CSS intacttest_mobile_files_button_present#btnMobileFilesin HTML and CSStest_profile_dropdown_not_clipped_by_overflow#profileChipWrappresent,.profile-dropdownz-index >= 100test_topbar_chips_mobile_overflowoverflow-x:autofor horizontal chip scrollingtest_workspace_close_button_presenttoggleMobileFiles()wired to a buttontest_toggle_mobile_files_js_definedtoggleMobileFiles()in boot.js withmobile-opentoggletest_body_overflow_hiddenbodyhasoverflow:hidden(prevents double scrollbars)test_100dvh_viewport_height100dvhused (not just100vhwhich clips under iOS address bar)test_composer_touch_target_sizetest_composer_textarea_font_size_mobileTest results
638 passed, 0 failed, 0 skipped (up from 624 on master — +14 new tests)
All 14 tests pass against current master. The tests are designed to fail on common regressions:
@media(max-width:900px)breakpoint →test_mobile_breakpoint_900px_presentfails#mobileOverlayfrom HTML →test_mobile_overlay_presentfailsfont-size:14pxon mobile →test_composer_textarea_font_size_mobilefails100vhinstead of100dvh→test_100dvh_viewport_heightfails