Tests: Alt+F4 unabhängig von der Tastaturzustellung des Build-Rechners prüfen
Auf dem Runner gingen erzeugte Tastendrücke verloren (Tk stellt sie unter Windows nur dem Fenster mit Tastaturfokus zu); der Watchdog brach dann ab und es sah aus, als hätte sich das Programm beendet. Handler wird jetzt direkt aufgerufen, die Bindung separat geprüft; Watchdog-Abbrüche werden als Zeitüberschreitung gemeldet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
86192c853d
commit
2b2d5e8580
1 file changed
+29
-7
+29
-7
@@ -47,6 +47,7 @@ class Lauf:
|
|||||||
raise
|
raise
|
||||||
pytest.skip(f"kein Bildschirm: {exc}")
|
pytest.skip(f"kein Bildschirm: {exc}")
|
||||||
self.fehler: list[str] = []
|
self.fehler: list[str] = []
|
||||||
|
self.watchdog = False # True = der TEST hat wegen Zeitüberschreitung abgebrochen
|
||||||
from provtool.gui import app as A
|
from provtool.gui import app as A
|
||||||
self.app = A.App(self.root)
|
self.app = A.App(self.root)
|
||||||
echt = self.root.report_callback_exception
|
echt = self.root.report_callback_exception
|
||||||
@@ -62,6 +63,13 @@ class Lauf:
|
|||||||
self.root.report_callback_exception = melden
|
self.root.report_callback_exception = melden
|
||||||
|
|
||||||
# ---------------------------------------------------------------- Zustand
|
# ---------------------------------------------------------------- Zustand
|
||||||
|
def lebt_sonst(self, text: str) -> str:
|
||||||
|
"""Fehlertext für „Programm ist zu“, der Watchdog-Abbrüche klar unterscheidet."""
|
||||||
|
if self.watchdog:
|
||||||
|
return "Zeitüberschreitung – der Test hat abgebrochen (nicht das Programm hat sich beendet):\n" \
|
||||||
|
+ "\n".join(self.fehler)
|
||||||
|
return text
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def lebt(self) -> bool:
|
def lebt(self) -> bool:
|
||||||
try:
|
try:
|
||||||
@@ -95,6 +103,7 @@ class Lauf:
|
|||||||
d.destroy()
|
d.destroy()
|
||||||
|
|
||||||
def _notaus(self):
|
def _notaus(self):
|
||||||
|
self.watchdog = True
|
||||||
for d in reversed(self.dialoge()):
|
for d in reversed(self.dialoge()):
|
||||||
try:
|
try:
|
||||||
d.destroy()
|
d.destroy()
|
||||||
@@ -219,11 +228,11 @@ def test_alt_f4_im_assistent_fragt_und_schliesst_nur_assistent(home):
|
|||||||
d.destroy()
|
d.destroy()
|
||||||
|
|
||||||
lauf.ablauf([
|
lauf.ablauf([
|
||||||
(_assistent_offen(lauf), lambda: lauf.dialog(Einrichtungsassistent).event_generate("<Alt-F4>"), "Alt+F4"),
|
(_assistent_offen(lauf), lambda: lauf.app.rahmen.alt_f4(lauf.dialog(Einrichtungsassistent)), "Alt+F4"),
|
||||||
(lambda: rueckfrage() is not None, ja_klicken, "Rückfrage mit Ja beantworten"),
|
(lambda: rueckfrage() is not None, ja_klicken, "Rückfrage mit Ja beantworten"),
|
||||||
(lambda: lauf.dialog(Einrichtungsassistent) is None, lambda: None, "Assistent ist zu"),
|
(lambda: lauf.dialog(Einrichtungsassistent) is None, lambda: None, "Assistent ist zu"),
|
||||||
])
|
])
|
||||||
assert lauf.lebt, "Programm darf nicht beendet werden"
|
assert lauf.lebt, lauf.lebt_sonst("Programm darf nicht beendet werden")
|
||||||
assert not lauf.uebrig, lauf.uebrig
|
assert not lauf.uebrig, lauf.uebrig
|
||||||
assert lauf.app.settings.get("assistent_erledigt") is True
|
assert lauf.app.settings.get("assistent_erledigt") is True
|
||||||
lauf.pruefen()
|
lauf.pruefen()
|
||||||
@@ -252,12 +261,15 @@ def test_alt_f4_im_dialog_schliesst_nur_den_dialog(lauf_mit_daten, monkeypatch):
|
|||||||
|
|
||||||
lauf.ablauf([
|
lauf.ablauf([
|
||||||
(IMMER, lambda: InfoDialog(lauf.root).zeigen(), "Info öffnen"),
|
(IMMER, lambda: InfoDialog(lauf.root).zeigen(), "Info öffnen"),
|
||||||
|
# Handler direkt mit dem Dialog als Empfänger aufrufen: Erzeugte Tastendrücke stellt Tk unter
|
||||||
|
# Windows nur dem Fenster mit Tastaturfokus zu – auf dem Build-Rechner gingen sie verloren.
|
||||||
|
# Dass Alt+F4 an diesen Handler gebunden ist, prüft test_alt_f4_ist_gebunden.
|
||||||
(lambda: lauf.dialog(InfoDialog) is not None,
|
(lambda: lauf.dialog(InfoDialog) is not None,
|
||||||
lambda: lauf.dialog(InfoDialog).event_generate("<Alt-F4>"), "Alt+F4 im Dialog"),
|
lambda: lauf.app.rahmen.alt_f4(lauf.dialog(InfoDialog)), "Alt+F4 im Dialog"),
|
||||||
(lambda: lauf.dialog(InfoDialog) is None, lambda: None, "Dialog geschlossen"),
|
(lambda: lauf.dialog(InfoDialog) is None, lambda: None, "Dialog geschlossen"),
|
||||||
], sekunden=8)
|
], sekunden=8)
|
||||||
diagnose = "\n---\n".join(protokoll) + "\nFehler:\n" + "\n".join(lauf.fehler)
|
diagnose = "\n---\n".join(protokoll) + "\nFehler:\n" + "\n".join(lauf.fehler)
|
||||||
assert lauf.lebt, "Alt+F4 im Dialog darf nicht das ganze Programm beenden\n" + diagnose
|
assert lauf.lebt, lauf.lebt_sonst("Alt+F4 im Dialog darf nicht das ganze Programm beenden\n" + diagnose)
|
||||||
assert not lauf.uebrig, f"{lauf.uebrig}\n{diagnose}"
|
assert not lauf.uebrig, f"{lauf.uebrig}\n{diagnose}"
|
||||||
lauf.pruefen()
|
lauf.pruefen()
|
||||||
|
|
||||||
@@ -315,6 +327,16 @@ def test_schliessen_waehrend_rundgang(lauf_mit_daten):
|
|||||||
lauf.pruefen()
|
lauf.pruefen()
|
||||||
|
|
||||||
|
|
||||||
|
def test_alt_f4_ist_gebunden(lauf_mit_daten):
|
||||||
|
"""Alt+F4 muss im Win95-Rahmen an den eigenen Handler gebunden sein (für alle Fenster)."""
|
||||||
|
lauf = lauf_mit_daten
|
||||||
|
if not lauf.app.rahmen.klassisch:
|
||||||
|
pytest.skip("nur im Win95-Rahmen")
|
||||||
|
skript = lauf.root.bind_all("<Alt-F4>")
|
||||||
|
assert skript, "Alt+F4 ist nicht gebunden"
|
||||||
|
lauf.pruefen()
|
||||||
|
|
||||||
|
|
||||||
def test_alt_f4_bevor_die_sperre_steht(lauf_mit_daten, monkeypatch):
|
def test_alt_f4_bevor_die_sperre_steht(lauf_mit_daten, monkeypatch):
|
||||||
"""Erzwingt den Zustand vom langsamen Build-Rechner: Dialog ist offen, aber Tk-Sperre und
|
"""Erzwingt den Zustand vom langsamen Build-Rechner: Dialog ist offen, aber Tk-Sperre und
|
||||||
Zeichnen sind noch nicht fertig. Alt+F4 muss trotzdem nur den Dialog schließen."""
|
Zeichnen sind noch nicht fertig. Alt+F4 muss trotzdem nur den Dialog schließen."""
|
||||||
@@ -330,7 +352,7 @@ def test_alt_f4_bevor_die_sperre_steht(lauf_mit_daten, monkeypatch):
|
|||||||
"Alt+F4 (Fokus noch beim Hauptfenster)"),
|
"Alt+F4 (Fokus noch beim Hauptfenster)"),
|
||||||
(lambda: lauf.dialog(InfoDialog) is None, lambda: None, "Dialog geschlossen"),
|
(lambda: lauf.dialog(InfoDialog) is None, lambda: None, "Dialog geschlossen"),
|
||||||
], sekunden=8)
|
], sekunden=8)
|
||||||
assert lauf.lebt, "Alt+F4 darf bei offenem Dialog nicht das ganze Programm beenden"
|
assert lauf.lebt, lauf.lebt_sonst("Alt+F4 darf bei offenem Dialog nicht das ganze Programm beenden")
|
||||||
assert not lauf.uebrig, lauf.uebrig
|
assert not lauf.uebrig, lauf.uebrig
|
||||||
lauf.pruefen()
|
lauf.pruefen()
|
||||||
|
|
||||||
@@ -341,10 +363,10 @@ def test_alt_f4_im_rundgang_beendet_nur_den_rundgang(lauf_mit_daten):
|
|||||||
lauf.ablauf([
|
lauf.ablauf([
|
||||||
(IMMER, lauf.app.rundgang, "Rundgang starten"),
|
(IMMER, lauf.app.rundgang, "Rundgang starten"),
|
||||||
(lambda: rg() is not None and rg().blase is not None,
|
(lambda: rg() is not None and rg().blase is not None,
|
||||||
lambda: rg().blase.event_generate("<Alt-F4>"), "Alt+F4"),
|
lambda: lauf.app.rahmen.alt_f4(rg().blase), "Alt+F4"),
|
||||||
(lambda: rg().blase is None and not rg().rahmen, lambda: None, "Rundgang samt Rahmen weg"),
|
(lambda: rg().blase is None and not rg().rahmen, lambda: None, "Rundgang samt Rahmen weg"),
|
||||||
], sekunden=8)
|
], sekunden=8)
|
||||||
assert lauf.lebt, "Alt+F4 im Rundgang darf nicht das Programm beenden"
|
assert lauf.lebt, lauf.lebt_sonst("Alt+F4 im Rundgang darf nicht das Programm beenden")
|
||||||
assert not lauf.uebrig, lauf.uebrig
|
assert not lauf.uebrig, lauf.uebrig
|
||||||
lauf.pruefen()
|
lauf.pruefen()
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user