61 lines
1.6 KiB
Python
61 lines
1.6 KiB
Python
|
|
"""UI testing utilities and helpers."""
|
||
|
|
|
||
|
|
from PyQt6.QtWidgets import QApplication
|
||
|
|
from typing import Optional
|
||
|
|
|
||
|
|
|
||
|
|
def get_or_create_qapplication() -> QApplication:
|
||
|
|
"""Get existing QApplication or create new one.
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
QApplication instance
|
||
|
|
"""
|
||
|
|
app = QApplication.instance()
|
||
|
|
if app is None:
|
||
|
|
app = QApplication([])
|
||
|
|
return app
|
||
|
|
|
||
|
|
|
||
|
|
def create_test_widget(widget_class, *args, **kwargs):
|
||
|
|
"""Create widget instance for testing.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
widget_class: Widget class to instantiate
|
||
|
|
*args: Positional arguments for widget
|
||
|
|
**kwargs: Keyword arguments for widget
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
Widget instance
|
||
|
|
"""
|
||
|
|
app = get_or_create_qapplication()
|
||
|
|
return widget_class(*args, **kwargs)
|
||
|
|
|
||
|
|
|
||
|
|
class SignalSpy:
|
||
|
|
"""Helper to spy on Qt signals."""
|
||
|
|
|
||
|
|
def __init__(self, signal):
|
||
|
|
"""Initialize signal spy.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
signal: Qt signal to spy on
|
||
|
|
"""
|
||
|
|
self.signal = signal
|
||
|
|
self.calls = []
|
||
|
|
signal.connect(self._on_signal)
|
||
|
|
|
||
|
|
def _on_signal(self, *args, **kwargs):
|
||
|
|
"""Record signal emission."""
|
||
|
|
self.calls.append((args, kwargs))
|
||
|
|
|
||
|
|
def assert_called(self, times: Optional[int] = None):
|
||
|
|
"""Assert signal was called.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
times: Expected number of calls (None for any)
|
||
|
|
"""
|
||
|
|
if times is None:
|
||
|
|
assert len(self.calls) > 0, "Signal was not called"
|
||
|
|
else:
|
||
|
|
assert len(self.calls) == times, f"Signal called {len(self.calls)} times, expected {times}"
|