"""Shared pytest configuration. The GUI suite is headless by default: unless the caller already chose a platform, ``QT_QPA_PLATFORM=offscreen`` is set here, before pytest-qt builds its session ``QApplication``. An explicit caller value is respected. OpenseesPy is a process-global singleton, so a lazy autouse guard wipes the domain after every test. The import is inside the teardown so that ``tests/unit`` never imports the solver. """ from __future__ import annotations import importlib.util import os from collections.abc import Iterator import pytest os.environ.setdefault("QT_QPA_PLATFORM", "offscreen") @pytest.fixture(autouse=True, scope="session") def _isolate_qsettings(tmp_path_factory: pytest.TempPathFactory) -> Iterator[None]: """Redirect ``QSettings`` to a temp dir so tests never touch user state. ``MainWindow`` persists preferences (window layout, canvas backend) under ``QSettings("OTKO", "OTKO")``. Without redirection a developer who, say, switched to the Plotly backend would see PyVista-specific GUI tests fail against their real settings. Skipped entirely when Qt is not installed, so the headless job stays free of Qt. """ if importlib.util.find_spec("PySide6") is None: yield return from PySide6.QtCore import QSettings settings_dir = tmp_path_factory.mktemp("qsettings") for fmt in (QSettings.Format.NativeFormat, QSettings.Format.IniFormat): QSettings.setPath(fmt, QSettings.Scope.UserScope, str(settings_dir)) yield @pytest.fixture(autouse=True) def _wipe_opensees_domain() -> Iterator[None]: """Wipe the OpenseesPy domain after a test if the solver was imported.""" yield try: from openseespy.opensees import wipe except Exception: # pragma: no cover - solver not installed / import side effects return wipe()