Tests: Warten auf das sichtbare Hauptfenster als Schritt im Ablauf statt eigener update()-Schleife

Auf dem langsamen Runner öffnete sich währenddessen der modale Einrichtungs-Assistent und hielt die
Schleife fest (Hänger). Als Tk-Callback-Schritt läuft das Warten auch bei offenem Dialog weiter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 5.5 committed 2026-11-02 14:01:57 +01:00
1 parent 03c5eaf5da
commit 49fc94c918
1 file changed
+14 -14
+14 -14
View File
@@ -61,23 +61,23 @@ class Lauf:
# eine evtl. geöffnete Fehlermeldung schließen, damit der Test nicht hängt # eine evtl. geöffnete Fehlermeldung schließen, damit der Test nicht hängt
self.root.after(100, self._meldungen_zu) self.root.after(100, self._meldungen_zu)
self.root.report_callback_exception = melden self.root.report_callback_exception = melden
self._warten_bis_sichtbar() self._sichtbar_seit: float | None = None
def _warten_bis_sichtbar(self, sekunden: float = 8.0): def hauptfenster_sichtbar(self) -> bool:
"""Wie ein Mensch erst bedienen, wenn das Hauptfenster zu sehen ist: Unter Windows wird es beim """Wie ein Mensch erst bedienen, wenn das Hauptfenster zu sehen ist: Unter Windows wird es beim
Start für den Taskleisten-Eintrag kurz aus- und wieder eingeblendet (unter Wine langsamer).""" Start für den Taskleisten-Eintrag kurz aus- und wieder eingeblendet (unter Wine langsamer).
ende = time.time() + sekunden Wird als erster Schritt jedes Ablaufs geprüft – NICHT mit einer eigenen update()-Schleife,
stabil = 0 denn ein modaler Dialog (z. B. der Assistent beim Erststart) würde die festhalten."""
while time.time() < ende:
try: try:
self.root.update() sichtbar = bool(self.root.winfo_viewable()) and self.app.inhalt.winfo_height() > 50
sichtbar = self.root.winfo_viewable() and self.app.inhalt.winfo_height() > 50
except tk.TclError: except tk.TclError:
return return True
stabil = stabil + 1 if sichtbar else 0 if not sichtbar:
if stabil >= 10: # ~0,1 s durchgehend sichtbar self._sichtbar_seit = None
return return False
time.sleep(0.01) if self._sichtbar_seit is None:
self._sichtbar_seit = time.time()
return time.time() - self._sichtbar_seit >= 0.1
# ---------------------------------------------------------------- Zustand # ---------------------------------------------------------------- Zustand
def lebt_sonst(self, text: str) -> str: def lebt_sonst(self, text: str) -> str:
@@ -135,7 +135,7 @@ class Lauf:
def ablauf(self, schritte: list[tuple], sekunden: float = 20.0, nachlauf: float = 0.3): def ablauf(self, schritte: list[tuple], sekunden: float = 20.0, nachlauf: float = 0.3):
"""schritte: [(bedingung, aktion, beschreibung), ...] – jede Aktion läuft als eigener """schritte: [(bedingung, aktion, beschreibung), ...] – jede Aktion läuft als eigener
Tk-Callback, sobald ihre Bedingung erfüllt ist (auch während ein modaler Dialog offen ist).""" Tk-Callback, sobald ihre Bedingung erfüllt ist (auch während ein modaler Dialog offen ist)."""
offen = list(schritte) offen = [(self.hauptfenster_sichtbar, lambda: None, "Hauptfenster ist sichtbar")] + list(schritte)
start = time.time() start = time.time()
zustand = {"fertig_seit": None} zustand = {"fertig_seit": None}