Files
orisys-app/apps/studio/tests/conftest.py
T
2026-09-12 14:03:00 +08:00

80 lines
2.3 KiB
Python

"""Shared fixtures for the studio app UI tests.
The tests render real Qt widgets with the offscreen platform plugin, so they need
no display and no camera hardware. A single ``QApplication`` is shared by the
whole session (Qt forbids creating more than one).
"""
from __future__ import annotations
import os
import sys
from pathlib import Path
import pytest
os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
if sys.platform == "win32" and "QT_QPA_FONTDIR" not in os.environ:
_fonts = Path(os.environ.get("WINDIR", r"C:\Windows")) / "Fonts"
if _fonts.is_dir():
os.environ["QT_QPA_FONTDIR"] = str(_fonts)
# ``tools/ui_check.py`` owns the palette rules; importing it keeps one source of
# truth between the pytest suite and the dependency-free checker.
_TOOLS_DIR = Path(__file__).resolve().parents[1] / "tools"
if _TOOLS_DIR.is_dir() and str(_TOOLS_DIR) not in sys.path:
sys.path.insert(0, str(_TOOLS_DIR))
@pytest.fixture(scope="session")
def qt_app():
from PyQt5.QtWidgets import QApplication
app = QApplication.instance() or QApplication([])
yield app
@pytest.fixture
def make_window(qt_app, tmp_path, monkeypatch):
"""Build a ``StudioMainWindow`` whose preference writes stay in tmp_path."""
from orisys_app_shared import prefs as prefs_pkg
from orisys_app_shared import paths as paths_mod
from orisys_studio.app_window import StudioMainWindow
prefs_file = tmp_path / "preference.json"
monkeypatch.setattr(paths_mod, "preference_path", lambda: prefs_file)
monkeypatch.setattr(prefs_pkg.store, "preference_path", lambda: prefs_file)
default_prefs = {
"language": "zh_CN",
"theme": "dark",
"sensor_type": "box",
"source_mode": "camera",
}
created = []
def _make(**overrides):
data = dict(default_prefs)
data.update(overrides)
window = StudioMainWindow(prefs=data)
created.append(window)
return window
yield _make
for window in created:
try:
window.close()
except Exception:
pass
def visible_descendants(widget):
"""Yield every visible descendant widget of ``widget``."""
for child in widget.findChildren(object):
if not hasattr(child, "isVisible") or not hasattr(child, "geometry"):
continue
if child.isVisible():
yield child