Implemented presentation window for live transcripts #1306 (#1323)

Co-authored-by: Raivis Dejus <orvils@gmail.com>
This commit is contained in:
David Olowomeye 2025-12-23 19:29:34 +00:00 committed by GitHub
commit 6e54b5cb02
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
29 changed files with 2171 additions and 166 deletions

View file

@ -0,0 +1,324 @@
import os
import pytest
import tempfile
from unittest.mock import patch, MagicMock
from pytestqt.qtbot import QtBot
from PyQt6.QtCore import Qt
from PyQt6.QtGui import QKeyEvent
from buzz.widgets.presentation_window import PresentationWindow
from buzz.settings.settings import Settings
from buzz.locale import _
class TestPresentationWindow:
def test_should_set_window_title(self, qtbot: QtBot):
"""Test that the window title is set correctly"""
window = PresentationWindow()
qtbot.add_widget(window)
assert _("Live Transcript Presentation") in window.windowTitle()
window.close()
def test_should_have_window_flag(self, qtbot: QtBot):
"""Test that window has the Window flag set"""
window = PresentationWindow()
qtbot.add_widget(window)
assert window.windowFlags() & Qt.WindowType.Window
window.close()
def test_should_have_transcript_display(self, qtbot: QtBot):
"""Test that the transcript display is created"""
window = PresentationWindow()
qtbot.add_widget(window)
assert window.transcript_display is not None
assert window.transcript_display.isReadOnly()
window.close()
def test_should_have_translation_display_hidden(self, qtbot: QtBot):
"""Test that the translation display is created but hidden initially"""
window = PresentationWindow()
qtbot.add_widget(window)
assert window.translation_display is not None
assert window.translation_display.isReadOnly()
assert not window.translation_display.isVisible()
window.close()
def test_should_have_default_size(self, qtbot: QtBot):
"""Test that the window has default size"""
window = PresentationWindow()
qtbot.add_widget(window)
assert window.width() == 800
assert window.height() == 600
window.close()
class TestPresentationWindowUpdateTranscripts:
def test_update_transcripts_with_text(self, qtbot: QtBot):
"""Test updating transcripts with text"""
window = PresentationWindow()
qtbot.add_widget(window)
window.update_transcripts("Hello world")
assert window._current_transcript == "Hello world"
assert "Hello world" in window.transcript_display.toHtml()
window.close()
def test_update_transcripts_with_empty_text(self, qtbot: QtBot):
"""Test that empty text does not update the display"""
window = PresentationWindow()
qtbot.add_widget(window)
window.update_transcripts("")
assert window._current_transcript == ""
window.close()
def test_update_transcripts_escapes_html(self, qtbot: QtBot):
"""Test that special HTML characters are escaped"""
window = PresentationWindow()
qtbot.add_widget(window)
window.update_transcripts("<script>alert('xss')</script>")
html = window.transcript_display.toHtml()
assert "<script>" not in html
assert "&lt;script&gt;" in html
window.close()
def test_update_transcripts_preserves_newlines(self, qtbot: QtBot):
"""Test that newlines are converted to <br> tags"""
window = PresentationWindow()
qtbot.add_widget(window)
window.update_transcripts("Line 1\nLine 2")
html = window.transcript_display.toHtml()
assert "<br>" in html or "<br/>" in html or "Line 1" in html
window.close()
class TestPresentationWindowUpdateTranslations:
def test_update_translations_with_text(self, qtbot: QtBot):
"""Test updating translations with text"""
window = PresentationWindow()
qtbot.add_widget(window)
window.show()
window.update_translations("Translated text")
assert window._current_translation == "Translated text"
assert window.translation_display.isVisible()
assert "Translated text" in window.translation_display.toHtml()
window.close()
def test_update_translations_with_empty_text(self, qtbot: QtBot):
"""Test that empty text does not update the display"""
window = PresentationWindow()
qtbot.add_widget(window)
window.show()
window.update_translations("")
assert window._current_translation == ""
# translation_display should remain hidden when not updated with real text
assert window.translation_display.isHidden()
window.close()
def test_update_translations_escapes_html(self, qtbot: QtBot):
"""Test that special HTML characters are escaped in translations"""
window = PresentationWindow()
qtbot.add_widget(window)
window.update_translations("<b>bold</b>")
html = window.translation_display.toHtml()
assert "&lt;b&gt;" in html
window.close()
class TestPresentationWindowLoadSettings:
def test_load_settings_light_theme(self, qtbot: QtBot):
"""Test loading light theme settings"""
settings = Settings()
settings.set_value(Settings.Key.PRESENTATION_WINDOW_THEME, "light")
settings.set_value(Settings.Key.PRESENTATION_WINDOW_TEXT_SIZE, 24)
window = PresentationWindow()
qtbot.add_widget(window)
assert "#000000" in window.window_style or "color:" in window.window_style
window.close()
def test_load_settings_dark_theme(self, qtbot: QtBot):
"""Test loading dark theme settings"""
settings = Settings()
settings.set_value(Settings.Key.PRESENTATION_WINDOW_THEME, "dark")
window = PresentationWindow()
qtbot.add_widget(window)
assert "#FFFFFF" in window.window_style or "#000000" in window.window_style
window.close()
def test_load_settings_custom_theme(self, qtbot: QtBot):
"""Test loading custom theme settings"""
settings = Settings()
settings.set_value(Settings.Key.PRESENTATION_WINDOW_THEME, "custom")
settings.set_value(Settings.Key.PRESENTATION_WINDOW_TEXT_COLOR, "#FF0000")
settings.set_value(Settings.Key.PRESENTATION_WINDOW_BACKGROUND_COLOR, "#00FF00")
settings.set_value(Settings.Key.PRESENTATION_WINDOW_TEXT_SIZE, 32)
window = PresentationWindow()
qtbot.add_widget(window)
assert "#FF0000" in window.window_style or "#00FF00" in window.window_style
window.close()
def test_load_settings_refreshes_content(self, qtbot: QtBot):
"""Test that load_settings refreshes existing content"""
window = PresentationWindow()
qtbot.add_widget(window)
window.update_transcripts("Test transcript")
window.update_translations("Test translation")
# Reload settings
window.load_settings()
# Content should still be present
assert "Test transcript" in window.transcript_display.toHtml()
assert "Test translation" in window.translation_display.toHtml()
window.close()
class TestPresentationWindowApplyStyling:
def test_apply_styling_creates_css(self, qtbot: QtBot):
"""Test that apply_styling creates appropriate CSS"""
window = PresentationWindow()
qtbot.add_widget(window)
window.apply_styling("#123456", "#654321", 48)
assert "#123456" in window.window_style
assert "#654321" in window.window_style
assert "48pt" in window.window_style
window.close()
def test_apply_styling_with_custom_css_file(self, qtbot: QtBot):
"""Test that custom CSS file is loaded when it exists"""
window = PresentationWindow()
qtbot.add_widget(window)
css_path = window.get_css_file_path()
custom_css = "body { color: red; font-size: 100pt; }"
try:
with open(css_path, "w", encoding="utf-8") as f:
f.write(custom_css)
window.apply_styling("#000", "#FFF", 24)
assert window.window_style == custom_css
finally:
if os.path.exists(css_path):
os.remove(css_path)
window.close()
class TestPresentationWindowFullscreen:
def test_toggle_fullscreen_enters_fullscreen(self, qtbot: QtBot):
"""Test that toggle_fullscreen enters fullscreen mode"""
window = PresentationWindow()
qtbot.add_widget(window)
window.show()
assert not window.isFullScreen()
window.toggle_fullscreen()
assert window.isFullScreen()
window.close()
def test_toggle_fullscreen_exits_fullscreen(self, qtbot: QtBot):
"""Test that toggle_fullscreen exits fullscreen mode"""
window = PresentationWindow()
qtbot.add_widget(window)
window.show()
window.showFullScreen()
assert window.isFullScreen()
window.toggle_fullscreen()
assert not window.isFullScreen()
window.close()
class TestPresentationWindowKeyPressEvent:
def test_escape_exits_fullscreen(self, qtbot: QtBot):
"""Test that ESC key exits fullscreen mode"""
window = PresentationWindow()
qtbot.add_widget(window)
window.show()
window.showFullScreen()
assert window.isFullScreen()
# Simulate ESC key press
event = QKeyEvent(
QKeyEvent.Type.KeyPress,
Qt.Key.Key_Escape,
Qt.KeyboardModifier.NoModifier
)
window.keyPressEvent(event)
assert not window.isFullScreen()
window.close()
def test_escape_does_not_affect_normal_mode(self, qtbot: QtBot):
"""Test that ESC key does nothing in normal mode"""
window = PresentationWindow()
qtbot.add_widget(window)
window.show()
assert not window.isFullScreen()
# Simulate ESC key press
event = QKeyEvent(
QKeyEvent.Type.KeyPress,
Qt.Key.Key_Escape,
Qt.KeyboardModifier.NoModifier
)
window.keyPressEvent(event)
assert not window.isFullScreen()
window.close()
class TestPresentationWindowGetCssFilePath:
def test_get_css_file_path_returns_path(self, qtbot: QtBot):
"""Test that get_css_file_path returns a valid path"""
window = PresentationWindow()
qtbot.add_widget(window)
css_path = window.get_css_file_path()
assert css_path.endswith("presentation_window_style.css")
assert "Buzz" in css_path
window.close()
def test_get_css_file_path_creates_directory(self, qtbot: QtBot):
"""Test that get_css_file_path creates the cache directory"""
window = PresentationWindow()
qtbot.add_widget(window)
css_path = window.get_css_file_path()
parent_dir = os.path.dirname(css_path)
assert os.path.isdir(parent_dir)
window.close()

View file

@ -4,12 +4,15 @@ import pytest
import platform
import tempfile
from unittest.mock import patch
from unittest.mock import patch, MagicMock
from pytestqt.qtbot import QtBot
from PyQt6.QtWidgets import QColorDialog
from PyQt6.QtGui import QColor
from buzz.locale import _
from buzz.settings.recording_transcriber_mode import RecordingTranscriberMode
from buzz.widgets.recording_transcriber_widget import RecordingTranscriberWidget
from buzz.widgets.presentation_window import PresentationWindow
from buzz.settings.settings import Settings
from tests.mock_sounddevice import MockSoundDevice, MockInputStream
@ -187,3 +190,438 @@ class TestRecordingTranscriberWidget:
qtbot.wait(500)
widget.close()
class TestRecordingTranscriberWidgetPresentation:
"""Tests for presentation window related functionality"""
@pytest.mark.timeout(60)
def test_presentation_options_bar_created(self, qtbot: QtBot):
"""Test that presentation options bar is created"""
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
return_value=16_000),
patch("sounddevice.check_input_settings")):
widget = RecordingTranscriberWidget(
custom_sounddevice=MockSoundDevice()
)
qtbot.add_widget(widget)
assert widget.presentation_options_bar is not None
assert not widget.presentation_options_bar.isVisible()
time.sleep(0.5)
widget.close()
@pytest.mark.timeout(60)
def test_presentation_options_bar_has_buttons(self, qtbot: QtBot):
"""Test that presentation options bar has all expected buttons"""
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
return_value=16_000),
patch("sounddevice.check_input_settings")):
widget = RecordingTranscriberWidget(
custom_sounddevice=MockSoundDevice()
)
qtbot.add_widget(widget)
assert widget.show_presentation_button is not None
assert widget.fullscreen_button is not None
assert widget.text_size_spinbox is not None
assert widget.theme_combo is not None
assert widget.text_color_button is not None
assert widget.bg_color_button is not None
time.sleep(0.5)
widget.close()
@pytest.mark.timeout(60)
def test_presentation_window_initially_none(self, qtbot: QtBot):
"""Test that presentation window is None initially"""
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
return_value=16_000),
patch("sounddevice.check_input_settings")):
widget = RecordingTranscriberWidget(
custom_sounddevice=MockSoundDevice()
)
qtbot.add_widget(widget)
assert widget.presentation_window is None
time.sleep(0.5)
widget.close()
@pytest.mark.timeout(60)
def test_on_show_presentation_clicked_creates_window(self, qtbot: QtBot):
"""Test that clicking show presentation button creates the window"""
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
return_value=16_000),
patch("sounddevice.check_input_settings")):
widget = RecordingTranscriberWidget(
custom_sounddevice=MockSoundDevice()
)
qtbot.add_widget(widget)
widget.on_show_presentation_clicked()
assert widget.presentation_window is not None
assert isinstance(widget.presentation_window, PresentationWindow)
assert widget.presentation_window.isVisible()
assert widget.fullscreen_button.isEnabled()
time.sleep(0.5)
widget.close()
@pytest.mark.timeout(60)
def test_on_show_presentation_clicked_syncs_content(self, qtbot: QtBot):
"""Test that clicking show presentation button syncs existing content"""
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
return_value=16_000),
patch("sounddevice.check_input_settings")):
widget = RecordingTranscriberWidget(
custom_sounddevice=MockSoundDevice()
)
qtbot.add_widget(widget)
# Add some text to the transcription box
widget.transcription_text_box.setPlainText("Test transcript text")
widget.on_show_presentation_clicked()
assert widget.presentation_window._current_transcript == "Test transcript text"
time.sleep(0.5)
widget.close()
@pytest.mark.timeout(60)
def test_on_show_presentation_clicked_brings_existing_to_front(self, qtbot: QtBot):
"""Test that clicking show presentation button brings existing window to front"""
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
return_value=16_000),
patch("sounddevice.check_input_settings")):
widget = RecordingTranscriberWidget(
custom_sounddevice=MockSoundDevice()
)
qtbot.add_widget(widget)
# Create window first
widget.on_show_presentation_clicked()
first_window = widget.presentation_window
# Click again
widget.on_show_presentation_clicked()
# Should be the same window
assert widget.presentation_window is first_window
time.sleep(0.5)
widget.close()
@pytest.mark.timeout(60)
def test_on_text_size_changed(self, qtbot: QtBot):
"""Test that text size change updates settings"""
settings = Settings()
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
return_value=16_000),
patch("sounddevice.check_input_settings")):
widget = RecordingTranscriberWidget(
custom_sounddevice=MockSoundDevice()
)
qtbot.add_widget(widget)
widget.on_text_size_changed(36)
# Wait for debounce
qtbot.wait(200)
saved_size = settings.value(Settings.Key.PRESENTATION_WINDOW_TEXT_SIZE, 24, int)
assert saved_size == 36
time.sleep(0.5)
widget.close()
@pytest.mark.timeout(60)
def test_on_theme_changed_light(self, qtbot: QtBot):
"""Test that theme change to light works"""
settings = Settings()
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
return_value=16_000),
patch("sounddevice.check_input_settings")):
widget = RecordingTranscriberWidget(
custom_sounddevice=MockSoundDevice()
)
qtbot.add_widget(widget)
widget.on_theme_changed(0) # light theme
saved_theme = settings.value(Settings.Key.PRESENTATION_WINDOW_THEME, "")
assert saved_theme == "light"
# Color buttons should be hidden for light theme
assert widget.text_color_button.isHidden()
assert widget.bg_color_button.isHidden()
time.sleep(0.5)
widget.close()
@pytest.mark.timeout(60)
def test_on_theme_changed_dark(self, qtbot: QtBot):
"""Test that theme change to dark works"""
settings = Settings()
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
return_value=16_000),
patch("sounddevice.check_input_settings")):
widget = RecordingTranscriberWidget(
custom_sounddevice=MockSoundDevice()
)
qtbot.add_widget(widget)
widget.on_theme_changed(1) # dark theme
saved_theme = settings.value(Settings.Key.PRESENTATION_WINDOW_THEME, "")
assert saved_theme == "dark"
# Color buttons should be hidden for dark theme
assert widget.text_color_button.isHidden()
assert widget.bg_color_button.isHidden()
time.sleep(0.5)
widget.close()
@pytest.mark.timeout(60)
def test_on_theme_changed_custom(self, qtbot: QtBot):
"""Test that theme change to custom shows color buttons"""
settings = Settings()
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
return_value=16_000),
patch("sounddevice.check_input_settings")):
widget = RecordingTranscriberWidget(
custom_sounddevice=MockSoundDevice()
)
qtbot.add_widget(widget)
widget.on_theme_changed(2) # custom theme
saved_theme = settings.value(Settings.Key.PRESENTATION_WINDOW_THEME, "")
assert saved_theme == "custom"
# Color buttons should NOT be hidden for custom theme
assert not widget.text_color_button.isHidden()
assert not widget.bg_color_button.isHidden()
time.sleep(0.5)
widget.close()
@pytest.mark.timeout(60)
def test_on_text_color_clicked(self, qtbot: QtBot):
"""Test that text color button opens color dialog and saves selection"""
settings = Settings()
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
return_value=16_000),
patch("sounddevice.check_input_settings"),
patch("buzz.widgets.recording_transcriber_widget.QColorDialog.getColor",
return_value=QColor("#FF5500"))):
widget = RecordingTranscriberWidget(
custom_sounddevice=MockSoundDevice()
)
qtbot.add_widget(widget)
widget.on_text_color_clicked()
saved_color = settings.value(Settings.Key.PRESENTATION_WINDOW_TEXT_COLOR, "")
assert saved_color == "#ff5500"
time.sleep(0.5)
widget.close()
@pytest.mark.timeout(60)
def test_on_text_color_clicked_cancel(self, qtbot: QtBot):
"""Test that cancelling color dialog does not save"""
settings = Settings()
original_color = settings.value(Settings.Key.PRESENTATION_WINDOW_TEXT_COLOR, "#000000")
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
return_value=16_000),
patch("sounddevice.check_input_settings"),
patch("buzz.widgets.recording_transcriber_widget.QColorDialog.getColor",
return_value=QColor())): # Invalid color = cancelled
widget = RecordingTranscriberWidget(
custom_sounddevice=MockSoundDevice()
)
qtbot.add_widget(widget)
widget.on_text_color_clicked()
saved_color = settings.value(Settings.Key.PRESENTATION_WINDOW_TEXT_COLOR, "")
assert saved_color == original_color
time.sleep(0.5)
widget.close()
@pytest.mark.timeout(60)
def test_on_bg_color_clicked(self, qtbot: QtBot):
"""Test that background color button opens color dialog and saves selection"""
settings = Settings()
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
return_value=16_000),
patch("sounddevice.check_input_settings"),
patch("buzz.widgets.recording_transcriber_widget.QColorDialog.getColor",
return_value=QColor("#00AA55"))):
widget = RecordingTranscriberWidget(
custom_sounddevice=MockSoundDevice()
)
qtbot.add_widget(widget)
widget.on_bg_color_clicked()
saved_color = settings.value(Settings.Key.PRESENTATION_WINDOW_BACKGROUND_COLOR, "")
assert saved_color == "#00aa55"
time.sleep(0.5)
widget.close()
@pytest.mark.timeout(60)
def test_on_fullscreen_clicked(self, qtbot: QtBot):
"""Test that fullscreen button toggles presentation window fullscreen"""
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
return_value=16_000),
patch("sounddevice.check_input_settings")):
widget = RecordingTranscriberWidget(
custom_sounddevice=MockSoundDevice()
)
qtbot.add_widget(widget)
# Create presentation window first
widget.on_show_presentation_clicked()
assert not widget.presentation_window.isFullScreen()
widget.on_fullscreen_clicked()
assert widget.presentation_window.isFullScreen()
time.sleep(0.5)
widget.close()
@pytest.mark.timeout(60)
def test_on_fullscreen_clicked_without_window(self, qtbot: QtBot):
"""Test that fullscreen button does nothing without presentation window"""
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
return_value=16_000),
patch("sounddevice.check_input_settings")):
widget = RecordingTranscriberWidget(
custom_sounddevice=MockSoundDevice()
)
qtbot.add_widget(widget)
# Should not raise exception
widget.on_fullscreen_clicked()
time.sleep(0.5)
widget.close()
@pytest.mark.timeout(60)
def test_presentation_window_updates_on_transcription(self, qtbot: QtBot):
"""Test that presentation window updates when new transcription arrives"""
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
return_value=16_000),
patch("sounddevice.check_input_settings")):
widget = RecordingTranscriberWidget(
custom_sounddevice=MockSoundDevice()
)
qtbot.add_widget(widget)
widget.on_show_presentation_clicked()
widget.transcriber_mode = RecordingTranscriberMode.APPEND_BELOW
widget.on_next_transcription("Hello world")
assert "Hello world" in widget.presentation_window._current_transcript
time.sleep(0.5)
widget.close()
@pytest.mark.timeout(60)
def test_close_event_closes_presentation_window(self, qtbot: QtBot):
"""Test that closing widget also closes presentation window"""
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
return_value=16_000),
patch("sounddevice.check_input_settings")):
widget = RecordingTranscriberWidget(
custom_sounddevice=MockSoundDevice()
)
qtbot.add_widget(widget)
widget.on_show_presentation_clicked()
presentation_window = widget.presentation_window
time.sleep(0.5)
widget.close()
assert widget.presentation_window is None
@pytest.mark.timeout(60)
def test_fullscreen_button_disabled_initially(self, qtbot: QtBot):
"""Test that fullscreen button is disabled when no presentation window"""
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
return_value=16_000),
patch("sounddevice.check_input_settings")):
widget = RecordingTranscriberWidget(
custom_sounddevice=MockSoundDevice()
)
qtbot.add_widget(widget)
assert not widget.fullscreen_button.isEnabled()
time.sleep(0.5)
widget.close()
@pytest.mark.timeout(60)
def test_presentation_bar_shown_when_recording(self, qtbot: QtBot):
"""Test that presentation bar is shown when recording starts"""
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
return_value=16_000),
patch("sounddevice.check_input_settings")):
widget = RecordingTranscriberWidget(
custom_sounddevice=MockSoundDevice()
)
widget.device_sample_rate = 16_000
qtbot.add_widget(widget)
# Initially hidden
assert widget.presentation_options_bar.isHidden()
# Simulate clicking record by directly calling the handler
# This avoids starting actual recording threads
widget.current_status = widget.RecordingStatus.RECORDING
widget.record_button.set_recording()
widget.transcription_options_group_box.setEnabled(False)
widget.audio_devices_combo_box.setEnabled(False)
widget.presentation_options_bar.show()
# Should no longer be hidden after recording starts
assert not widget.presentation_options_bar.isHidden()
time.sleep(0.5)
widget.close()