testzombie-windows 0.2.25__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- testzombie_windows-0.2.25/LICENSE.txt +5 -0
- testzombie_windows-0.2.25/MANIFEST.in +11 -0
- testzombie_windows-0.2.25/PKG-INFO +202 -0
- testzombie_windows-0.2.25/README.md +176 -0
- testzombie_windows-0.2.25/pyproject.toml +39 -0
- testzombie_windows-0.2.25/setup.cfg +4 -0
- testzombie_windows-0.2.25/testzombie_windows/__init__.py +6 -0
- testzombie_windows-0.2.25/testzombie_windows/api.py +152 -0
- testzombie_windows-0.2.25/testzombie_windows/code_update.py +343 -0
- testzombie_windows-0.2.25/testzombie_windows/config.py +38 -0
- testzombie_windows-0.2.25/testzombie_windows/discovery.py +741 -0
- testzombie_windows-0.2.25/testzombie_windows/prerun.py +164 -0
- testzombie_windows-0.2.25/testzombie_windows/resource_listener.py +170 -0
- testzombie_windows-0.2.25/testzombie_windows/robot_library.py +980 -0
- testzombie_windows-0.2.25/testzombie_windows/run_python.py +63 -0
- testzombie_windows-0.2.25/testzombie_windows/run_robot.py +40 -0
- testzombie_windows-0.2.25/testzombie_windows/transparent.py +467 -0
- testzombie_windows-0.2.25/testzombie_windows/uia.py +636 -0
- testzombie_windows-0.2.25/testzombie_windows/uia_actions.py +438 -0
- testzombie_windows-0.2.25/testzombie_windows/uiautomation_adapter.py +398 -0
- testzombie_windows-0.2.25/testzombie_windows.egg-info/PKG-INFO +202 -0
- testzombie_windows-0.2.25/testzombie_windows.egg-info/SOURCES.txt +23 -0
- testzombie_windows-0.2.25/testzombie_windows.egg-info/dependency_links.txt +1 -0
- testzombie_windows-0.2.25/testzombie_windows.egg-info/requires.txt +7 -0
- testzombie_windows-0.2.25/testzombie_windows.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: testzombie-windows
|
|
3
|
+
Version: 0.2.25
|
|
4
|
+
Summary: TestZombie AI integration for Windows UI automation with self-healing, discovery and code updates
|
|
5
|
+
Author: TestZombie AI
|
|
6
|
+
License-Expression: LicenseRef-Proprietary
|
|
7
|
+
Project-URL: Homepage, https://testzombie.ai
|
|
8
|
+
Keywords: windows,ui-automation,self-healing,robot-framework,flaui,uiautomation,testzombie
|
|
9
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Topic :: Software Development :: Testing
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE.txt
|
|
20
|
+
Requires-Dist: uiautomation<3,>=2
|
|
21
|
+
Provides-Extra: flaui
|
|
22
|
+
Requires-Dist: robotframework-flaui>=6; extra == "flaui"
|
|
23
|
+
Provides-Extra: rpa
|
|
24
|
+
Requires-Dist: rpaframework-windows>=8; extra == "rpa"
|
|
25
|
+
Dynamic: license-file
|
|
26
|
+
|
|
27
|
+
# TestZombie AI – Windows Library
|
|
28
|
+
|
|
29
|
+
TestZombie AI integriert Self-Healing, Discovery und optionales Code Update in bestehende Windows-UI-Tests. Die vorhandenen Testfälle und eigenen Robot-Framework-Keywords bleiben unverändert. Die Integration erfolgt über den TestZombie-Runner.
|
|
30
|
+
|
|
31
|
+
**Unterstützt:** Robot Framework mit FlaUILibrary, Robot Framework mit RPA.Windows sowie Python mit `uiautomation`.
|
|
32
|
+
|
|
33
|
+
## Voraussetzungen
|
|
34
|
+
|
|
35
|
+
- Windows mit interaktiver Desktop-Sitzung und Python 3.10 oder neuer (64-Bit empfohlen).
|
|
36
|
+
- Zugriff auf ein TestZombie-AI-Projekt mit API-Key.
|
|
37
|
+
- Bei Robot Framework: das verwendete native Framework in **derselben Python-Umgebung** installieren wie `testzombie-windows`.
|
|
38
|
+
- Die Anwendung muss über einen Fenstertitel und/oder eine AutomationId identifizierbar sein.
|
|
39
|
+
|
|
40
|
+
## Installation mit pip
|
|
41
|
+
|
|
42
|
+
Die Installation erfolgt in der Python-Umgebung, in der auch die Kundentests laufen.
|
|
43
|
+
|
|
44
|
+
**Robot Framework + FlaUILibrary:**
|
|
45
|
+
|
|
46
|
+
```powershell
|
|
47
|
+
python -m pip install "testzombie-windows[flaui]"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**Robot Framework + RPA.Windows:**
|
|
51
|
+
|
|
52
|
+
```powershell
|
|
53
|
+
python -m pip install "testzombie-windows[rpa]"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Python + uiautomation:**
|
|
57
|
+
|
|
58
|
+
```powershell
|
|
59
|
+
python -m pip install testzombie-windows
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Für ein bereits vorhandenes virtuelles Environment dessen `python.exe` verwenden, zum Beispiel:
|
|
63
|
+
|
|
64
|
+
```powershell
|
|
65
|
+
& ".\.venv\Scripts\python.exe" -m pip install "testzombie-windows[flaui]"
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Alternative: Installation von einem lokalen Pfad
|
|
69
|
+
|
|
70
|
+
Installation direkt aus einer Wheel-Datei:
|
|
71
|
+
|
|
72
|
+
```powershell
|
|
73
|
+
python -m pip install "C:\Pakete\testzombie_windows-0.2.25-py3-none-any.whl"
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Oder aus einem entpackten Quellverzeichnis mit `pyproject.toml`:
|
|
77
|
+
|
|
78
|
+
```powershell
|
|
79
|
+
python -m pip install "C:\Pakete\TestZombie-Windows-PyPI-v0.2.25"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Bei lokaler Installation aus einer Wheel-Datei die benötigte Robot-Integration gegebenenfalls zusätzlich installieren, z. B. `python -m pip install "robotframework-flaui>=6"`.
|
|
83
|
+
|
|
84
|
+
Installation prüfen:
|
|
85
|
+
|
|
86
|
+
```powershell
|
|
87
|
+
python -m pip show testzombie-windows
|
|
88
|
+
python -c "import testzombie_windows; print(testzombie_windows.__version__)"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Konfiguration
|
|
92
|
+
|
|
93
|
+
Die Konfiguration erfolgt über Umgebungsvariablen, beispielsweise im CI-Job oder in PowerShell. Es sind **keine Änderungen am Testcode** erforderlich.
|
|
94
|
+
|
|
95
|
+
```powershell
|
|
96
|
+
$env:TZ_API_KEY = "<projekt-api-key>"
|
|
97
|
+
$env:TZ_API_EMAIL = "<konto-email>"
|
|
98
|
+
$env:TZ_APP_NAME = "MeineAnwendung"
|
|
99
|
+
$env:TZ_WINDOW_NAME = "Hauptfenster"
|
|
100
|
+
# Optional, falls vorhanden:
|
|
101
|
+
$env:TZ_WINDOW_AUTOMATION_ID = "MainWindow"
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Die Standard-API-Adresse lautet **`https://testzombie.ai/api`**. Für diese Adresse muss `TZ_API_URL` nicht gesetzt werden. Für eigene Umgebungen kann sie überschrieben werden:
|
|
105
|
+
|
|
106
|
+
```powershell
|
|
107
|
+
$env:TZ_API_URL = "http://localhost/api"
|
|
108
|
+
# Alternativ: $env:TZ_API_URL = "https://staging.example.com/api"
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Die Library erwartet eine vollständige `http(s)`-URL und verhindert doppelte `/api`-Pfadsegmente.
|
|
112
|
+
|
|
113
|
+
### Verfügbare Optionen
|
|
114
|
+
|
|
115
|
+
| Variable | Standard | Bedeutung |
|
|
116
|
+
| --- | --- | --- |
|
|
117
|
+
| `TZ_API_URL` | `https://testzombie.ai/api` | API-Adresse; optional überschreibbar. |
|
|
118
|
+
| `TZ_API_KEY` | – | API-Key des TestZombie-Projekts. |
|
|
119
|
+
| `TZ_API_EMAIL` | leer | Zugehörige API-Identität. |
|
|
120
|
+
| `TZ_APP_NAME` | – | Technische Anwendungskennung, für Python-Integration erforderlich. |
|
|
121
|
+
| `TZ_WINDOW_NAME` | – | Fenstertitel, für direkte Python-Integration erforderlich. |
|
|
122
|
+
| `TZ_WINDOW_AUTOMATION_ID` | leer | Optionale AutomationId des Hauptfensters. |
|
|
123
|
+
| `TZ_BACKEND` | `FLAUI` | Robot-Backend `FLAUI` oder `RPA_WINDOWS`. |
|
|
124
|
+
| `TZ_NATIVE_LIBRARY_ALIAS` | automatisch | Optionaler Robot-Bibliotheksalias, falls `WITH NAME` verwendet wird. |
|
|
125
|
+
| `TZ_ENABLED` | im Runner aktiviert | `0` deaktiviert die transparente Integration. |
|
|
126
|
+
| `TZ_CODE_UPDATE` | `0` | `1` aktiviert automatische Quellcode-Korrekturen nach erfolgreichem Healing. |
|
|
127
|
+
| `TZ_CODE_UPDATE_ROOT` | aktuelles Arbeitsverzeichnis | Verzeichnis, in dem Code Update Dateien bearbeiten darf. |
|
|
128
|
+
| `TZ_DISCOVERY_ENABLED` | `0` | `1` aktiviert die Discovery-Aufzeichnung im TestRun. |
|
|
129
|
+
| `TZ_DISCOVERY_MAX_STATES` | `12` (max. 40) | Obergrenze erfasster UI-Zustände. |
|
|
130
|
+
| `TZ_DISCOVERY_MAX_EVENTS` | `200` (max. 500) | Obergrenze erfasster Aktionen. |
|
|
131
|
+
| `TZ_DISCOVERY_MAX_CONTROLS` | `120` (max. 300) | Obergrenze UI-Controls pro Zustand. |
|
|
132
|
+
| `TZ_DISCOVERY_CAPTURE_OPTION_LABELS` | `0` | Optionales Erfassen von Auswahlbezeichnungen, falls fachlich erlaubt. |
|
|
133
|
+
| `TZ_DISCOVERY_INSPECT_PATTERNS` | `0` | Zusätzliche UIA-Pattern-Informationen erfassen. |
|
|
134
|
+
| `TZ_DISCOVERY_CAPTURE_GRID_DIMENSIONS` | `0` | Zeilen-/Spaltenzahlen von Tabellen erfassen. |
|
|
135
|
+
| `TZ_DISCOVERY_CAPTURE_COUNTER_DELTAS` | `0` | Unterschiede ausgewählter Zähler erfassen. |
|
|
136
|
+
| `TZ_API_TIMEOUT` | `3` Sekunden | HTTP-Timeout (größer 0 bis 60 Sekunden). |
|
|
137
|
+
| `TZ_API_HEAL_TIMEOUT` | `120` Sekunden | Timeout für Healing-Requests (größer 0 bis 300 Sekunden). |
|
|
138
|
+
| `TZ_API_KEY_HEADER` | `X-API-KEY` | Optionaler API-Key-Header. |
|
|
139
|
+
| `TZ_API_MAIL_HEADER` | `X-API-MAIL` | Optionaler Header der API-Identität. |
|
|
140
|
+
| `TZ_FLAUI_SAFE_WAIT` | `1` | Sicherer nativer FlaUI-Wait, sofern verfügbar. |
|
|
141
|
+
| `TZ_FLAUI_PROBE_TIMEOUT` | `0.8` Sekunden | Timeout des FlaUI-Locator-Probes. |
|
|
142
|
+
| `TZ_HEALING_FAILURE_LOG` | `.testzombie/windows-healing-failures.jsonl` | Lokaler Dateipfad für Healing-Diagnosen. |
|
|
143
|
+
| `TZ_ROBOT_DIAGNOSTICS` | `0` | `1` aktiviert erweiterte Robot-Diagnoseausgaben. |
|
|
144
|
+
|
|
145
|
+
API-Credentials nicht in Testdateien, Repositorys oder Logs ablegen. Die Wirksamkeit der Healing-Optionen hängt außerdem von den Einstellungen und Berechtigungen des TestZombie-Projekts ab.
|
|
146
|
+
|
|
147
|
+
## Bestehende Tests ausführen
|
|
148
|
+
|
|
149
|
+
**Robot Framework + FlaUILibrary:**
|
|
150
|
+
|
|
151
|
+
```powershell
|
|
152
|
+
python -m testzombie_windows.run_robot --backend FLAUI -- tests\meine_suite.robot
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**Robot Framework + RPA.Windows:**
|
|
156
|
+
|
|
157
|
+
```powershell
|
|
158
|
+
python -m testzombie_windows.run_robot --backend RPA_WINDOWS -- tests\meine_suite.robot
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
**Direktes Python + uiautomation:**
|
|
162
|
+
|
|
163
|
+
```powershell
|
|
164
|
+
python -m testzombie_windows.run_python tests\meine_tests.py
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Für eine bestehende Python-Modul-Ausführung (z. B. pytest):
|
|
168
|
+
|
|
169
|
+
```powershell
|
|
170
|
+
python -m testzombie_windows.run_python -m pytest tests\
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Die üblichen Robot-CLI-Optionen können nach `--` übergeben werden. Bereits vorhandene `.robot`- und importierte `.resource`-Dateien müssen nicht geändert werden. Native Aufrufe werden innerhalb der unterstützten Adapter transparent verarbeitet. Eigene, vollständig gekapselte Framework-Aufrufe können ein gezieltes Mapping erfordern.
|
|
174
|
+
|
|
175
|
+
## Optional: Code Update
|
|
176
|
+
|
|
177
|
+
Code Update ist standardmäßig ausgeschaltet. Nach erfolgreichem Healing kann TestZombie eindeutige Locator-Referenzen in unterstützten Testdateien aktualisieren:
|
|
178
|
+
|
|
179
|
+
```powershell
|
|
180
|
+
$env:TZ_CODE_UPDATE = "1"
|
|
181
|
+
$env:TZ_CODE_UPDATE_ROOT = "C:\Projekte\MeineTests"
|
|
182
|
+
python -m testzombie_windows.run_robot --backend FLAUI -- tests\meine_suite.robot
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Es werden nur sicher zuordenbare Locator-Ausdrücke aktualisiert. Vor Änderungen werden Backups mit der Endung `.testzombie.bak` erstellt. Für den ersten Einsatz empfiehlt sich ein versionierter Arbeitsstand.
|
|
186
|
+
|
|
187
|
+
## Optional: Discovery
|
|
188
|
+
|
|
189
|
+
```powershell
|
|
190
|
+
$env:TZ_DISCOVERY_ENABLED = "1"
|
|
191
|
+
python -m testzombie_windows.run_robot --backend FLAUI -- tests\meine_suite.robot
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Discovery zeichnet unterstützte UI-Zustände und Aktionen im TestRun auf. Nur explizit in erfolgreichen Testaktionen verwendete Controls werden als GUI Elements registriert. Das Erfassen potenziell personenbezogener Auswahlbezeichnungen bleibt standardmäßig deaktiviert.
|
|
195
|
+
|
|
196
|
+
## Hinweise zur Ausführung
|
|
197
|
+
|
|
198
|
+
- Tests benötigen eine interaktive Windows-Desktop-Sitzung. Eine gesperrte Sitzung oder eine CI-Umgebung ohne sichtbaren Desktop kann UIAutomation verhindern.
|
|
199
|
+
- Alle Komponenten (TestZombie-Library, Robot Framework und nativer Adapter) müssen in derselben Python-Umgebung installiert sein.
|
|
200
|
+
- Ohne gültige API-Anmeldedaten sind servergestütztes Healing, Discovery-Upload und Code Update nicht verfügbar. Die nativen Aufrufe laufen – soweit möglich – unverändert weiter.
|
|
201
|
+
- Code Update wird nur bei ausdrücklich gesetztem `TZ_CODE_UPDATE=1` ausgeführt.
|
|
202
|
+
- Bei fehlenden Fenstern oder mehrdeutigen Treffern `TZ_APP_NAME`, `TZ_WINDOW_NAME` und gegebenenfalls `TZ_WINDOW_AUTOMATION_ID` prüfen.
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# TestZombie AI – Windows Library
|
|
2
|
+
|
|
3
|
+
TestZombie AI integriert Self-Healing, Discovery und optionales Code Update in bestehende Windows-UI-Tests. Die vorhandenen Testfälle und eigenen Robot-Framework-Keywords bleiben unverändert. Die Integration erfolgt über den TestZombie-Runner.
|
|
4
|
+
|
|
5
|
+
**Unterstützt:** Robot Framework mit FlaUILibrary, Robot Framework mit RPA.Windows sowie Python mit `uiautomation`.
|
|
6
|
+
|
|
7
|
+
## Voraussetzungen
|
|
8
|
+
|
|
9
|
+
- Windows mit interaktiver Desktop-Sitzung und Python 3.10 oder neuer (64-Bit empfohlen).
|
|
10
|
+
- Zugriff auf ein TestZombie-AI-Projekt mit API-Key.
|
|
11
|
+
- Bei Robot Framework: das verwendete native Framework in **derselben Python-Umgebung** installieren wie `testzombie-windows`.
|
|
12
|
+
- Die Anwendung muss über einen Fenstertitel und/oder eine AutomationId identifizierbar sein.
|
|
13
|
+
|
|
14
|
+
## Installation mit pip
|
|
15
|
+
|
|
16
|
+
Die Installation erfolgt in der Python-Umgebung, in der auch die Kundentests laufen.
|
|
17
|
+
|
|
18
|
+
**Robot Framework + FlaUILibrary:**
|
|
19
|
+
|
|
20
|
+
```powershell
|
|
21
|
+
python -m pip install "testzombie-windows[flaui]"
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**Robot Framework + RPA.Windows:**
|
|
25
|
+
|
|
26
|
+
```powershell
|
|
27
|
+
python -m pip install "testzombie-windows[rpa]"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Python + uiautomation:**
|
|
31
|
+
|
|
32
|
+
```powershell
|
|
33
|
+
python -m pip install testzombie-windows
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Für ein bereits vorhandenes virtuelles Environment dessen `python.exe` verwenden, zum Beispiel:
|
|
37
|
+
|
|
38
|
+
```powershell
|
|
39
|
+
& ".\.venv\Scripts\python.exe" -m pip install "testzombie-windows[flaui]"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Alternative: Installation von einem lokalen Pfad
|
|
43
|
+
|
|
44
|
+
Installation direkt aus einer Wheel-Datei:
|
|
45
|
+
|
|
46
|
+
```powershell
|
|
47
|
+
python -m pip install "C:\Pakete\testzombie_windows-0.2.25-py3-none-any.whl"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Oder aus einem entpackten Quellverzeichnis mit `pyproject.toml`:
|
|
51
|
+
|
|
52
|
+
```powershell
|
|
53
|
+
python -m pip install "C:\Pakete\TestZombie-Windows-PyPI-v0.2.25"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Bei lokaler Installation aus einer Wheel-Datei die benötigte Robot-Integration gegebenenfalls zusätzlich installieren, z. B. `python -m pip install "robotframework-flaui>=6"`.
|
|
57
|
+
|
|
58
|
+
Installation prüfen:
|
|
59
|
+
|
|
60
|
+
```powershell
|
|
61
|
+
python -m pip show testzombie-windows
|
|
62
|
+
python -c "import testzombie_windows; print(testzombie_windows.__version__)"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Konfiguration
|
|
66
|
+
|
|
67
|
+
Die Konfiguration erfolgt über Umgebungsvariablen, beispielsweise im CI-Job oder in PowerShell. Es sind **keine Änderungen am Testcode** erforderlich.
|
|
68
|
+
|
|
69
|
+
```powershell
|
|
70
|
+
$env:TZ_API_KEY = "<projekt-api-key>"
|
|
71
|
+
$env:TZ_API_EMAIL = "<konto-email>"
|
|
72
|
+
$env:TZ_APP_NAME = "MeineAnwendung"
|
|
73
|
+
$env:TZ_WINDOW_NAME = "Hauptfenster"
|
|
74
|
+
# Optional, falls vorhanden:
|
|
75
|
+
$env:TZ_WINDOW_AUTOMATION_ID = "MainWindow"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Die Standard-API-Adresse lautet **`https://testzombie.ai/api`**. Für diese Adresse muss `TZ_API_URL` nicht gesetzt werden. Für eigene Umgebungen kann sie überschrieben werden:
|
|
79
|
+
|
|
80
|
+
```powershell
|
|
81
|
+
$env:TZ_API_URL = "http://localhost/api"
|
|
82
|
+
# Alternativ: $env:TZ_API_URL = "https://staging.example.com/api"
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Die Library erwartet eine vollständige `http(s)`-URL und verhindert doppelte `/api`-Pfadsegmente.
|
|
86
|
+
|
|
87
|
+
### Verfügbare Optionen
|
|
88
|
+
|
|
89
|
+
| Variable | Standard | Bedeutung |
|
|
90
|
+
| --- | --- | --- |
|
|
91
|
+
| `TZ_API_URL` | `https://testzombie.ai/api` | API-Adresse; optional überschreibbar. |
|
|
92
|
+
| `TZ_API_KEY` | – | API-Key des TestZombie-Projekts. |
|
|
93
|
+
| `TZ_API_EMAIL` | leer | Zugehörige API-Identität. |
|
|
94
|
+
| `TZ_APP_NAME` | – | Technische Anwendungskennung, für Python-Integration erforderlich. |
|
|
95
|
+
| `TZ_WINDOW_NAME` | – | Fenstertitel, für direkte Python-Integration erforderlich. |
|
|
96
|
+
| `TZ_WINDOW_AUTOMATION_ID` | leer | Optionale AutomationId des Hauptfensters. |
|
|
97
|
+
| `TZ_BACKEND` | `FLAUI` | Robot-Backend `FLAUI` oder `RPA_WINDOWS`. |
|
|
98
|
+
| `TZ_NATIVE_LIBRARY_ALIAS` | automatisch | Optionaler Robot-Bibliotheksalias, falls `WITH NAME` verwendet wird. |
|
|
99
|
+
| `TZ_ENABLED` | im Runner aktiviert | `0` deaktiviert die transparente Integration. |
|
|
100
|
+
| `TZ_CODE_UPDATE` | `0` | `1` aktiviert automatische Quellcode-Korrekturen nach erfolgreichem Healing. |
|
|
101
|
+
| `TZ_CODE_UPDATE_ROOT` | aktuelles Arbeitsverzeichnis | Verzeichnis, in dem Code Update Dateien bearbeiten darf. |
|
|
102
|
+
| `TZ_DISCOVERY_ENABLED` | `0` | `1` aktiviert die Discovery-Aufzeichnung im TestRun. |
|
|
103
|
+
| `TZ_DISCOVERY_MAX_STATES` | `12` (max. 40) | Obergrenze erfasster UI-Zustände. |
|
|
104
|
+
| `TZ_DISCOVERY_MAX_EVENTS` | `200` (max. 500) | Obergrenze erfasster Aktionen. |
|
|
105
|
+
| `TZ_DISCOVERY_MAX_CONTROLS` | `120` (max. 300) | Obergrenze UI-Controls pro Zustand. |
|
|
106
|
+
| `TZ_DISCOVERY_CAPTURE_OPTION_LABELS` | `0` | Optionales Erfassen von Auswahlbezeichnungen, falls fachlich erlaubt. |
|
|
107
|
+
| `TZ_DISCOVERY_INSPECT_PATTERNS` | `0` | Zusätzliche UIA-Pattern-Informationen erfassen. |
|
|
108
|
+
| `TZ_DISCOVERY_CAPTURE_GRID_DIMENSIONS` | `0` | Zeilen-/Spaltenzahlen von Tabellen erfassen. |
|
|
109
|
+
| `TZ_DISCOVERY_CAPTURE_COUNTER_DELTAS` | `0` | Unterschiede ausgewählter Zähler erfassen. |
|
|
110
|
+
| `TZ_API_TIMEOUT` | `3` Sekunden | HTTP-Timeout (größer 0 bis 60 Sekunden). |
|
|
111
|
+
| `TZ_API_HEAL_TIMEOUT` | `120` Sekunden | Timeout für Healing-Requests (größer 0 bis 300 Sekunden). |
|
|
112
|
+
| `TZ_API_KEY_HEADER` | `X-API-KEY` | Optionaler API-Key-Header. |
|
|
113
|
+
| `TZ_API_MAIL_HEADER` | `X-API-MAIL` | Optionaler Header der API-Identität. |
|
|
114
|
+
| `TZ_FLAUI_SAFE_WAIT` | `1` | Sicherer nativer FlaUI-Wait, sofern verfügbar. |
|
|
115
|
+
| `TZ_FLAUI_PROBE_TIMEOUT` | `0.8` Sekunden | Timeout des FlaUI-Locator-Probes. |
|
|
116
|
+
| `TZ_HEALING_FAILURE_LOG` | `.testzombie/windows-healing-failures.jsonl` | Lokaler Dateipfad für Healing-Diagnosen. |
|
|
117
|
+
| `TZ_ROBOT_DIAGNOSTICS` | `0` | `1` aktiviert erweiterte Robot-Diagnoseausgaben. |
|
|
118
|
+
|
|
119
|
+
API-Credentials nicht in Testdateien, Repositorys oder Logs ablegen. Die Wirksamkeit der Healing-Optionen hängt außerdem von den Einstellungen und Berechtigungen des TestZombie-Projekts ab.
|
|
120
|
+
|
|
121
|
+
## Bestehende Tests ausführen
|
|
122
|
+
|
|
123
|
+
**Robot Framework + FlaUILibrary:**
|
|
124
|
+
|
|
125
|
+
```powershell
|
|
126
|
+
python -m testzombie_windows.run_robot --backend FLAUI -- tests\meine_suite.robot
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**Robot Framework + RPA.Windows:**
|
|
130
|
+
|
|
131
|
+
```powershell
|
|
132
|
+
python -m testzombie_windows.run_robot --backend RPA_WINDOWS -- tests\meine_suite.robot
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Direktes Python + uiautomation:**
|
|
136
|
+
|
|
137
|
+
```powershell
|
|
138
|
+
python -m testzombie_windows.run_python tests\meine_tests.py
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Für eine bestehende Python-Modul-Ausführung (z. B. pytest):
|
|
142
|
+
|
|
143
|
+
```powershell
|
|
144
|
+
python -m testzombie_windows.run_python -m pytest tests\
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Die üblichen Robot-CLI-Optionen können nach `--` übergeben werden. Bereits vorhandene `.robot`- und importierte `.resource`-Dateien müssen nicht geändert werden. Native Aufrufe werden innerhalb der unterstützten Adapter transparent verarbeitet. Eigene, vollständig gekapselte Framework-Aufrufe können ein gezieltes Mapping erfordern.
|
|
148
|
+
|
|
149
|
+
## Optional: Code Update
|
|
150
|
+
|
|
151
|
+
Code Update ist standardmäßig ausgeschaltet. Nach erfolgreichem Healing kann TestZombie eindeutige Locator-Referenzen in unterstützten Testdateien aktualisieren:
|
|
152
|
+
|
|
153
|
+
```powershell
|
|
154
|
+
$env:TZ_CODE_UPDATE = "1"
|
|
155
|
+
$env:TZ_CODE_UPDATE_ROOT = "C:\Projekte\MeineTests"
|
|
156
|
+
python -m testzombie_windows.run_robot --backend FLAUI -- tests\meine_suite.robot
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Es werden nur sicher zuordenbare Locator-Ausdrücke aktualisiert. Vor Änderungen werden Backups mit der Endung `.testzombie.bak` erstellt. Für den ersten Einsatz empfiehlt sich ein versionierter Arbeitsstand.
|
|
160
|
+
|
|
161
|
+
## Optional: Discovery
|
|
162
|
+
|
|
163
|
+
```powershell
|
|
164
|
+
$env:TZ_DISCOVERY_ENABLED = "1"
|
|
165
|
+
python -m testzombie_windows.run_robot --backend FLAUI -- tests\meine_suite.robot
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Discovery zeichnet unterstützte UI-Zustände und Aktionen im TestRun auf. Nur explizit in erfolgreichen Testaktionen verwendete Controls werden als GUI Elements registriert. Das Erfassen potenziell personenbezogener Auswahlbezeichnungen bleibt standardmäßig deaktiviert.
|
|
169
|
+
|
|
170
|
+
## Hinweise zur Ausführung
|
|
171
|
+
|
|
172
|
+
- Tests benötigen eine interaktive Windows-Desktop-Sitzung. Eine gesperrte Sitzung oder eine CI-Umgebung ohne sichtbaren Desktop kann UIAutomation verhindern.
|
|
173
|
+
- Alle Komponenten (TestZombie-Library, Robot Framework und nativer Adapter) müssen in derselben Python-Umgebung installiert sein.
|
|
174
|
+
- Ohne gültige API-Anmeldedaten sind servergestütztes Healing, Discovery-Upload und Code Update nicht verfügbar. Die nativen Aufrufe laufen – soweit möglich – unverändert weiter.
|
|
175
|
+
- Code Update wird nur bei ausdrücklich gesetztem `TZ_CODE_UPDATE=1` ausgeführt.
|
|
176
|
+
- Bei fehlenden Fenstern oder mehrdeutigen Treffern `TZ_APP_NAME`, `TZ_WINDOW_NAME` und gegebenenfalls `TZ_WINDOW_AUTOMATION_ID` prüfen.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77.0.3", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "testzombie-windows"
|
|
7
|
+
version = "0.2.25"
|
|
8
|
+
description = "TestZombie AI integration for Windows UI automation with self-healing, discovery and code updates"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "LicenseRef-Proprietary"
|
|
12
|
+
license-files = ["LICENSE.txt"]
|
|
13
|
+
authors = [{ name = "TestZombie AI" }]
|
|
14
|
+
keywords = ["windows", "ui-automation", "self-healing", "robot-framework", "flaui", "uiautomation", "testzombie"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Operating System :: Microsoft :: Windows",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3.10",
|
|
19
|
+
"Programming Language :: Python :: 3.11",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Programming Language :: Python :: 3.13",
|
|
22
|
+
"Intended Audience :: Developers",
|
|
23
|
+
"Topic :: Software Development :: Testing",
|
|
24
|
+
]
|
|
25
|
+
dependencies = ["uiautomation>=2,<3"]
|
|
26
|
+
|
|
27
|
+
[project.optional-dependencies]
|
|
28
|
+
flaui = ["robotframework-flaui>=6"]
|
|
29
|
+
rpa = ["rpaframework-windows>=8"]
|
|
30
|
+
|
|
31
|
+
[project.urls]
|
|
32
|
+
Homepage = "https://testzombie.ai"
|
|
33
|
+
|
|
34
|
+
[tool.setuptools]
|
|
35
|
+
include-package-data = false
|
|
36
|
+
|
|
37
|
+
[tool.setuptools.packages.find]
|
|
38
|
+
where = ["."]
|
|
39
|
+
include = ["testzombie_windows*"]
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"""Network contract for the additive Windows API endpoints (Phase 2.2)."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
import socket
|
|
6
|
+
from .config import api_base_url, api_header_names
|
|
7
|
+
import urllib.error
|
|
8
|
+
import urllib.request
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class TestZombieApiError(RuntimeError):
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# The InitController supplies these project settings in InitZombieResult.
|
|
16
|
+
# Keep the allowlist explicit: no tokens, credentials or project secrets in logs.
|
|
17
|
+
_HEALING_FIELDS = (
|
|
18
|
+
('healingLocatorFallbackEnabled', 'Locator-Fallback'),
|
|
19
|
+
('healingVisualPositionEnabled', 'Visual-Position'),
|
|
20
|
+
('healingWaitEnabled', 'Wait'),
|
|
21
|
+
('healingClickEnabled', 'Click'),
|
|
22
|
+
('healingAiEnabled', 'AI'),
|
|
23
|
+
('healingStrictness', 'Strictness'),
|
|
24
|
+
('healingAuditModeEnabled', 'Audit'),
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def format_healing_configuration(config):
|
|
29
|
+
"""Render only settings actually supplied by initZombie, never infer defaults."""
|
|
30
|
+
if not isinstance(config, dict):
|
|
31
|
+
return ''
|
|
32
|
+
rendered = []
|
|
33
|
+
for key, label in _HEALING_FIELDS:
|
|
34
|
+
if key not in config or config[key] is None:
|
|
35
|
+
continue
|
|
36
|
+
value = config[key]
|
|
37
|
+
if isinstance(value, bool):
|
|
38
|
+
value = 'AN' if value else 'AUS'
|
|
39
|
+
else:
|
|
40
|
+
value = str(value)
|
|
41
|
+
rendered.append(f'{label}={value}')
|
|
42
|
+
return ' | '.join(rendered)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def report_healing_configuration(api, *, emitter=print):
|
|
46
|
+
"""Print project-controlled healing flags after a successful Init."""
|
|
47
|
+
summary = format_healing_configuration(getattr(api, 'healing_config', None))
|
|
48
|
+
if summary:
|
|
49
|
+
emitter('[TestZombie Windows] Healing-Konfiguration: ' + summary)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class WindowsApiClient:
|
|
53
|
+
def __init__(self, url=None, api_key=None, email=None, timeout=None):
|
|
54
|
+
try:
|
|
55
|
+
self.url = api_base_url(url)
|
|
56
|
+
self.key_header, self.mail_header = api_header_names()
|
|
57
|
+
except ValueError as exc:
|
|
58
|
+
raise TestZombieApiError(str(exc)) from exc
|
|
59
|
+
self.healing_config = {}
|
|
60
|
+
self.api_key = api_key or os.environ.get('TZ_API_KEY', '')
|
|
61
|
+
self.email = email or os.environ.get('TZ_API_EMAIL', '')
|
|
62
|
+
try:
|
|
63
|
+
self.timeout = float(timeout if timeout is not None else os.environ.get('TZ_API_TIMEOUT', '3'))
|
|
64
|
+
# findWindowsElement may execute a synchronous AI provider request.
|
|
65
|
+
# Its deadline must not inherit the short normal API timeout.
|
|
66
|
+
self.heal_timeout = float(os.environ.get('TZ_API_HEAL_TIMEOUT', '120'))
|
|
67
|
+
except (TypeError, ValueError) as exc:
|
|
68
|
+
raise TestZombieApiError('TZ_API_TIMEOUT / TZ_API_HEAL_TIMEOUT muss eine Sekundenzahl sein.') from exc
|
|
69
|
+
if not (0 < self.timeout <= 60):
|
|
70
|
+
raise TestZombieApiError('TZ_API_TIMEOUT muss groesser 0 und maximal 60 Sekunden sein.')
|
|
71
|
+
if not (0 < self.heal_timeout <= 300):
|
|
72
|
+
raise TestZombieApiError('TZ_API_HEAL_TIMEOUT muss groesser 0 und maximal 300 Sekunden sein.')
|
|
73
|
+
if not self.api_key:
|
|
74
|
+
raise TestZombieApiError('TZ_API_KEY fehlt (Projekt-API-Key konfigurieren).')
|
|
75
|
+
|
|
76
|
+
def request_timeout(self, endpoint):
|
|
77
|
+
return self.heal_timeout if endpoint.strip('/').lower() == 'findwindowselement' else self.timeout
|
|
78
|
+
|
|
79
|
+
def post(self, endpoint, payload):
|
|
80
|
+
timeout = self.request_timeout(endpoint)
|
|
81
|
+
url = self.url + '/api/' + endpoint.lstrip('/')
|
|
82
|
+
body = json.dumps(payload, ensure_ascii=False).encode('utf-8')
|
|
83
|
+
headers = {
|
|
84
|
+
'Content-Type': 'application/json',
|
|
85
|
+
self.key_header: self.api_key,
|
|
86
|
+
self.mail_header: self.email,
|
|
87
|
+
}
|
|
88
|
+
# This marks a single Windows demo request. The server additionally
|
|
89
|
+
# requires a local/test Spring profile, explicit property and exact
|
|
90
|
+
# demo identity; a client-controlled header can never force AI alone.
|
|
91
|
+
if endpoint.strip('/').lower() == 'findwindowselement' and os.environ.get(
|
|
92
|
+
'TZ_WINDOWS_TEST_FORCE_AI', '').strip().lower() in ('1', 'true', 'yes', 'on'):
|
|
93
|
+
from urllib.parse import urlsplit
|
|
94
|
+
if urlsplit(self.url).hostname not in ('localhost', '127.0.0.1', '::1'):
|
|
95
|
+
raise TestZombieApiError('Force-AI test mode requires a localhost API URL')
|
|
96
|
+
headers['X-TestZombie-Windows-Test-Force-AI'] = 'true'
|
|
97
|
+
req = urllib.request.Request(url, body, method='POST', headers=headers)
|
|
98
|
+
try:
|
|
99
|
+
with urllib.request.urlopen(req, timeout=timeout) as response:
|
|
100
|
+
result = json.load(response)
|
|
101
|
+
except urllib.error.HTTPError as exc:
|
|
102
|
+
# Avoid echoing response bodies potentially containing user data.
|
|
103
|
+
raise TestZombieApiError(f'{endpoint}: HTTP {exc.code} (API response rejected)') from exc
|
|
104
|
+
except (urllib.error.URLError, TimeoutError, OSError, ValueError) as exc:
|
|
105
|
+
# urllib can wrap a socket timeout in URLError.reason. Do not
|
|
106
|
+
# include raw response bodies, credentials or user input in logs.
|
|
107
|
+
reason = getattr(exc, 'reason', exc)
|
|
108
|
+
if isinstance(reason, (TimeoutError, socket.timeout)) or 'timed out' in str(reason).lower():
|
|
109
|
+
detail = f'timeout after {timeout:g}s'
|
|
110
|
+
elif isinstance(exc, ValueError):
|
|
111
|
+
detail = 'invalid JSON response'
|
|
112
|
+
else:
|
|
113
|
+
detail = 'network error: ' + type(exc).__name__
|
|
114
|
+
raise TestZombieApiError(f'{endpoint}: {detail}') from exc
|
|
115
|
+
if not isinstance(result, dict) or result.get('success') is False:
|
|
116
|
+
raise TestZombieApiError(f'{endpoint}: unsuccessful API response')
|
|
117
|
+
data = result.get('data')
|
|
118
|
+
if isinstance(data, dict) and data.get('error'):
|
|
119
|
+
raise TestZombieApiError(f'{endpoint}: {data["error"]}')
|
|
120
|
+
return data if isinstance(data, dict) else {}
|
|
121
|
+
|
|
122
|
+
def put_discovery(self, test_run_id, payload):
|
|
123
|
+
"""PUT to the existing DiscoveryController; success is HTTP 204 (no JSON)."""
|
|
124
|
+
from urllib.parse import quote
|
|
125
|
+
if not isinstance(test_run_id, str) or not test_run_id.strip():
|
|
126
|
+
raise TestZombieApiError('Discovery requires a valid testRunId')
|
|
127
|
+
endpoint = 'test-runs/' + quote(test_run_id, safe='') + '/discovery'
|
|
128
|
+
url = self.url + '/api/' + endpoint
|
|
129
|
+
body = json.dumps(payload, ensure_ascii=False).encode('utf-8')
|
|
130
|
+
req = urllib.request.Request(url, body, method='PUT', headers={
|
|
131
|
+
'Content-Type': 'application/json',
|
|
132
|
+
self.key_header: self.api_key,
|
|
133
|
+
self.mail_header: self.email,
|
|
134
|
+
})
|
|
135
|
+
try:
|
|
136
|
+
with urllib.request.urlopen(req, timeout=self.timeout) as response:
|
|
137
|
+
if response.status not in (200, 201, 202, 204):
|
|
138
|
+
raise TestZombieApiError('discovery: unexpected HTTP status')
|
|
139
|
+
return True
|
|
140
|
+
except urllib.error.HTTPError as exc:
|
|
141
|
+
raise TestZombieApiError(f'discovery: HTTP {exc.code}') from exc
|
|
142
|
+
except (urllib.error.URLError, TimeoutError, OSError, ValueError) as exc:
|
|
143
|
+
raise TestZombieApiError(f'discovery: network error: {type(exc).__name__}') from exc
|
|
144
|
+
|
|
145
|
+
def init_run(self, info='ROBOT_WINDOWS'):
|
|
146
|
+
self.healing_config = {}
|
|
147
|
+
data = self.post('initZombie', {'info': info})
|
|
148
|
+
run_id = data.get('testRunId')
|
|
149
|
+
if not run_id:
|
|
150
|
+
raise TestZombieApiError('initZombie did not return a testRunId')
|
|
151
|
+
self.healing_config = {key: data[key] for key, _ in _HEALING_FIELDS if key in data}
|
|
152
|
+
return run_id
|