0a406b5d7383f50f49fce372dcaca4e15435fbf8
3
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
9e5b632710 |
test: Improve test coverage to 80%+ (#122)
* test: Improve test coverage to 80% Increased test coverage from ~33% to 80.15% statement coverage. New test files added: - test_action_handler.py (100% coverage) - test_version.py (100% coverage) - test_logging_manager.py (100% coverage) - test_common_types.py - test_speech_recognition_init.py (100% coverage) - test_resource_manager.py (93% coverage) Significantly expanded existing tests: - test_tray_indicator.py: 76% -> 98% - test_main.py: 50% -> 92% - test_text_injector.py: 60% -> 94% - test_recognition_manager.py: 30% -> 48% - test_command_processor.py: 85% -> 98% - test_keyboard_shortcuts.py: 88% -> 95% - test_config_manager.py: improved to 98% - test_audio_feedback.py: improved to 92% Configuration changes: - Updated pyproject.toml to exclude untestable GTK dialog files (settings_dialog.py, logging_dialog.py) from coverage metrics Key testing improvements: - Added comprehensive GTK mocking for UI components - Added edge case tests for text injection on X11/Wayland - Added keyboard shortcut injection tests - Added error handling and callback tests - Added configuration management tests * fix: Use runtime CI mode detection to fix Python 3.8/3.10 tests Change CI_MODE from module-level constant to _is_ci_mode() function that is evaluated at runtime. This ensures pytest detection works correctly on all Python versions, since pytest modules may not be loaded at import time. * fix: Add PYTEST_RUNNING env var for reliable pytest detection in CI The previous approach to detect pytest at runtime wasn't working reliably on Python 3.8/3.10 in CI environments. This adds a PYTEST_RUNNING=1 environment variable set early in conftest.py that _is_ci_mode() can check to reliably determine if tests are running. * fix: Use patch.object for reliable mocking in audio_feedback tests The previous approach using patch() with module paths didn't work reliably because the module reimport caused the patched objects to not be the same as the ones the functions referenced. Using patch.object() on the imported module's attributes ensures the patches are applied to the actual objects the functions use. * fix: Use patch.object for reliable mocking in test_settings_callback The test was failing on Python 3.8/3.10 because the module-level patch for SettingsDialog wasn't being applied reliably across all Python versions due to import timing differences. Using patch.object() on the imported module ensures the mock is applied to the actual reference that _on_settings_clicked() uses, regardless of Python version or module caching behavior. |
||
|
|
22ab96cea7 |
feat: add Wayland support for keyboard shortcuts using evdev backend (#81)
* feat: add Wayland support for keyboard shortcuts using evdev backend This commit adds multi-backend support for keyboard shortcuts, enabling them to work on Wayland sessions where pynput does not work. **Changes:** - New `keyboard_backends/` package with modular backend system - `base.py`: Abstract base class for keyboard backends - `pynput_backend.py`: Existing pynput implementation (X11/XWayland) - `evdev_backend.py`: New evdev implementation (X11 & Wayland) - `__init__.py`: Backend factory with auto-detection - Updated `keyboard_shortcuts.py`: - Refactored to use backend system - Auto-detects session type (X11 vs Wayland) - Selects appropriate backend automatically - Provides helpful error messages when shortcuts unavailable - Added `evdev>=1.6.0` to dependencies (Linux only) - Comprehensive test updates: - 21 tests pass covering all backends - Tests for session detection - Tests for backend factory - Tests for permission hints **User Impact:** - Keyboard shortcuts now work on Wayland when user is in 'input' group - Clear error messages guide users to fix permission issues - Backward compatible with X11 (pynput backend) **Setup for Wayland:** ```bash sudo usermod -a -G input $USER # Log out and log back in ``` Related to #80 * style: fix flake8 issues in evdev_backend.py - Remove unused import 'categorize' - Remove unused variable 'dev' * style: fix remaining flake8 issues in tests - Remove unused 'time' import - Remove unused 'result' variable - Remove unused 'backend_cls' variable - Break long line to stay under 100 characters * style: apply black and isort formatting to pass CI * feat: auto-configure Wayland keyboard shortcuts during installation Automatically detect Wayland sessions during installation and add the user to the 'input' group required for evdev-based keyboard shortcuts. This eliminates the need for users to manually configure permissions after installation on Wayland systems. * fix: escape commit message in Detect Changes step to handle special characters The commit message was being directly inserted into the bash comparison, which broke when the message contained special characters like parentheses. Fix by assigning to a variable first. * chore: drop unrelated installer/web changes * fix: fall back to evdev backend * style: format keyboard shortcut imports |
||
|
|
1dc1d44665 |
feat: Alpha Launch v0.2.0 - Complete UX Overhaul 🚀🎤 (#39)
* feat: prepare for v0.2.0-alpha release * feat: prepare for v0.2.0-alpha release * chore: remove CHANGELOG.md, use GitHub Releases instead * refactor: use existing About dialog instead of Settings section * style: enhance About dialog UI readability * style: fix formatting with black and isort * feat: show VAD and silence timeout settings for Whisper engine - Renamed 'VOSK Settings' to 'Recognition Settings' - VAD Sensitivity and Silence Timeout now apply to both engines - Added tooltips explaining each setting - VOSK-specific model info only shown when VOSK selected * fix: resolve overlapping UI elements in settings dialog * fix: save VAD and silence timeout settings for both engines Previously these settings were only saved when VOSK was selected. Now they persist correctly for Whisper as well. * fix: show download progress when selecting undownloaded model Previously when auto-applying settings, models would download silently in the background without showing the progress dialog. Now: - Download progress dialog appears for undownloaded models - Model icons update correctly after download completes * feat: add download progress, speed, ETA and cancel button - Show real download progress percentage for VOSK models - Display download speed (MB/s) and estimated time remaining - Add Cancel button to abort downloads - Update status during extraction phase - Whisper downloads still pulse (uses internal downloader) * fix: defer model download until needed, don't block startup - App now starts instantly even if models aren't downloaded - Models are downloaded on-demand when selected in Settings - If user tries to dictate without a model, plays error sound - Added model_ready property to check if engine is usable * fix: improve first-run UX without downloaded models - Settings dialog now defaults to smallest available model, not saved config - Only show saved model if it's actually downloaded - Add desktop notification when trying to dictate without a model - Prevents auto-downloading large models on first launch * feat: add download progress tracking for Whisper models - Implement custom Whisper model download with progress/speed/ETA - Uses OpenAI's CDN URLs directly instead of whisper.load_model() - Progress callback works the same as VOSK downloads - Supports cancellation during download * fix: enable download progress callback for Whisper models Progress callback was only being set for VOSK downloads, not Whisper. Now both engines show real-time progress, speed, and ETA. * fix: update tests for defer_download and config manager mocking - test_main: Mock ConfigManager to prevent saved config from overriding test values - test_settings_dialog: Mock ModelDownloadDialog to prevent GTK init errors - test_speech_recognition: Use proper MockVoskModule class instead of MagicMock, pass defer_download=False for download test - test_whisper_support: Pass defer_download=False to trigger model loading in test * fix: resolve test failures for CI - test_main: Fix ConfigManager patch path to use source module - test_settings_dialog: Mock _is_vosk_model_downloaded and _is_whisper_model_downloaded to skip download flow, add missing dialog attributes - test_speech_recognition: Replace recognizer with properly configured mock that returns valid JSON, fixing test isolation issues when running all tests together * fix: mock _download_whisper_model in whisper test to avoid requests exception handling issue * fix: add gir1.2-girepository-2.0 dep for PyGObject on Ubuntu 24.04 - Add missing girepository-2.0 package for newer Ubuntu runners - Use --no-build-isolation for PyGObject to use system packages * fix: skip PyGObject pip install, use system python3-gi package - Use --no-deps for editable install to skip PyGObject - Install other deps explicitly without PyGObject - Add python3-gi-cairo for complete GTK support - Removes problematic girepository-2.0 build requirement * fix: install PyGObject via pip with proper build deps - Remove python3-gi/python3-gi-cairo (doesn't work with setup-python) - Install PyGObject from pip after installing build dependencies - Simplify venv setup without --system-site-packages hack * Fix GObject * fix: set GI_TYPELIB_PATH for pip-installed PyGObject to find AppIndicator3 |